自定义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.pageXy.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 = falseresult.value = response.data}).catch(e => {loading.value = falseerrorMsg.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>