Vue3 中自定义hook函数

自定义hook函数

  • 使用Vue3的组合API封装的可复用的功能函数;
  • 自定义hook的作用类似于vue2中的mixin技术
  • 自定义Hook的优势: 很清楚复用功能代码的来源, 更清楚易懂;

什么是vue2中的mixin混入?

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

// 定义一个混入对象
var myMixin = {
    
    
  created: function () {
    
    
    this.hello()
  },
  methods: {
    
    
    hello: function () {
    
    
      console.log('hello from mixin!')
    }
  }
}

// 定义一个使用混入对象的组件
var Component = Vue.extend({
    
    
  mixins: [myMixin]
})

var component = new Component() // => "hello from mixin!"

封装一个hook函数

封装一个点击的hook函数:

import {
    
     ref, onMounted, onUnmounted } from 'vue'
/* 
收集用户鼠标点击的页面坐标
*/
export default function useMousePosition () {
    
    
  // 初始化坐标数据
  const x = ref(-1)
  const y = ref(-1)

  // 用于收集点击事件坐标的函数
  const updatePosition = (e: MouseEvent) => {
    
    
    x.value = e.pageX
    y.value = e.pageY
  }

  // 挂载后绑定点击监听
  onMounted(() => {
    
    
    document.addEventListener('click', updatePosition)
  })

  // 卸载前解绑点击监听
  onUnmounted(() => {
    
    
    document.removeEventListener('click', updatePosition)
  })

  return {
    
    x, y}
}
<template>
<div>
  <h2>x: {
   
   {x}}, y: {
   
   {y}}</h2>
</div>
</template>

<script>

import {
      
      
  ref
} from "vue"
/* 
在组件中引入并使用自定义hook
自定义hook的作用类似于vue2中的mixin技术
自定义Hook的优势: 很清楚复用功能代码的来源, 更清楚易懂
*/
import useMousePosition from './hooks/useMousePosition'

export default {
      
      
  setup() {
      
      

    const {
      
      x, y} = useMousePosition()

    return {
      
      
      x,
      y,
    }
  }
}
</script>

封装一个hook axios请求hook函数

import {
    
     ref } from 'vue'
import axios from 'axios'

/* 
使用axios发送异步ajax请求
*/
export default function useUrlLoader<T>(url: string) {
    
    

  const result = ref<T | null>(null)
  const loading = ref(true)
  const errorMsg = ref(null)

  axios.get(url)
    .then(response => {
    
    
      loading.value = false
      result.value = response.data
    })
    .catch(e => {
    
    
      loading.value = false
      errorMsg.value = e.message || '未知错误'
    })

  return {
    
    
    loading,
    result,
    errorMsg,
  }
}
<template>
<div class="about">
  <h2 v-if="loading">LOADING...</h2>
  <h2 v-else-if="errorMsg">{
   
   {errorMsg}}</h2>
  <!-- <ul v-else>
    <li>id: {
    
    {result.id}}</li>
    <li>name: {
    
    {result.name}}</li>
    <li>distance: {
    
    {result.distance}}</li>
  </ul> -->

  <ul v-for="p in result" :key="p.id">
    <li>id: {
   
   {p.id}}</li>
    <li>title: {
   
   {p.title}}</li>
    <li>price: {
   
   {p.price}}</li>
  </ul>
  <!-- <img v-if="result" :src="result[0].url" alt=""> -->
</div>
</template>

<script lang="ts">
import {
      
      
  watch
} from "vue"
import useRequest from './hooks/useRequest'

// 地址数据接口
interface AddressResult {
      
      
  id: number;
  name: string;
  distance: string;
}

// 产品数据接口
interface ProductResult {
      
      
  id: string;
  title: string;
  price: number;
}

export default {
      
      
  setup() {
      
      

    // const {loading, result, errorMsg} = useRequest<AddressResult>('/data/address.json')
    const {
      
      loading, result, errorMsg} = useRequest<ProductResult[]>('/data/products.json')

    watch(result, () => {
      
      
      if (result.value) {
      
      
        console.log(result.value.length) // 有提示
      }
    })

    return {
      
      
      loading,
      result, 
      errorMsg
    }
  }
}
</script>

猜你喜欢

转载自blog.csdn.net/weixin_44684357/article/details/132433799