组合式函数
长得像是useXXX的函数,比如在vben框架中的useTable、useForm等方法。(结尾有vben这两个use函数的源码分析)。
这种useXXX函数是用于在vue组合式写法中,将重复代码段提取成函数(放在js或者ts文件中)的写法。
组合式函数例子
写一个在前端监控环境中的鼠标移动的方法如下
<script>
import {ref, onMounted, onUnmounted} from 'vue';
const x=ref(0);
const y=ref(0);
function moveXY(event){
x.value = event.pageX;
y.value = event.pageY;
}
onMounted(()=>windows.addEventListener('mousemove', update));
onUnmounted(()=>removeEventListener('mousemove', update));
</script>
如果多个组件都需要监控鼠标移动,会产生重复代码,每一个组件都要建立变量xy,编写函数moveXY,以及在挂接函数中调用addEventListener监听事件。
使用组合式函数进行封装
// mouse.js
import {ref, onMounted, onUnmounted} from 'vue';
export function useMouse() {
// 组合式函数管理的变量
const x=ref(0);
const y=ref(0);
// 组合式函数中的方法,可以修改管理的变量
function moveXY(event){
x.value = event.pageX;
y.value = event.pageY;
}
// 一个组合式函数也可以挂靠在所属组件的生命周期上
// 来启动和卸载副作用
onMounted(()=>windows.addEventListener('mousemove', update));
onUnmounted(()=>removeEventListener('mousemove', update));
// 返回管理的变量
return {x, y}
}
再原来vue中使用组合式函数
<template>Mouse position is at: {{ x }}, {{ y }}</template>
<script>
import {useMouse} from './mouse.js'
const {x, y} = useMouse()
</script>
使用组合式函数时,也可以进行传参;并且可以在组合式函数中嵌套组合式函数;
下面,将挂接生命周期部分代码封装
// event.js
import {onMounted, onUnmounted} from 'vue'
export function useEventListener(target, event, callback) {
// 这个函数有三个入参,target,event,callback
onMounted(()=>target.addEventListener(event, callback))
onUnmounted(()=>target.addEventListener(event, callback))
// 这个函数没有返回值
}
嵌套使用方式
// mouse.js
import {ref, onMounted, onUnmounted} from 'vue';
import {useEventListener} from './event.js'
export function useMouse() {
// 组合式函数管理的变量
const x=ref(0);
const y=ref(0);
useEventListener(window, 'mousemove', (event)=>{
x.value = event.pageX;
y.value = event.pageY;
})
// 返回管理的变量
return {x, y}
}
vben框架中,组合式函数怎么使用的
<template>
<BasicTable @register="registerTable" />
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, useTable } from '/@/components/Table';
import { getBasicColumns, getBasicShortColumns } from './tableData';
import { demoListApi } from '/@/api/demo/table';
export default defineComponent({
components: { BasicTable },
setup() {
// 使用useTable传入相关props,获取表格相关的操作方法
// 通过@register将useTable与表格组件绑定。
const [registerTable,{}] = useTable({
api: demoListApi,
columns: getBasicColumns(),
});
return {
registerTable,
};
},
});
</script>
useTable源码
src\components\Table\src\hooks\useTable.ts
存放在hooks文件夹中,
// 入参与返回值的ts定义,入参表格props,返回一个函数也就是register,一个复合类型,表格行为TableActionType或者表单行为(这里是为了兼容表格表单)
export function useTable(tableProps?: Props): [
(instance: TableActionType, formInstance: UseTableMethod) => void,
TableActionType & {
getForm: () => FormActionType;
},
] {
const tableRef = ref<Nullable<TableActionType>>(null);
const loadedRef = ref<Nullable<boolean>>(false);
const formRef = ref<Nullable<UseTableMethod>>(null);
let stopWatch: WatchStopHandle;
function register(instance: TableActionType, formInstance: UseTableMethod) {
//省略
}
//省略
// 最后返回之前所到的一个列表
return [register, methods];
}
“组合式函数”(Composables) 是一个利用 Vue 的组合式 API 来封装和复用有状态逻辑的函数。而有状态逻辑这回事,后面继续分析。