一、自定义 hook 函数
什么是 hook?
- hook 的本质是一个函数,把 setup 函数中使用的 Composition API 进行了封装。
- 类似于 vue2.x 中的 mixin。
- 自定义 hook 的优势:复用代码,让 setup 中逻辑更清楚易懂。
实例
- 在 src 下创建 hooks 文件夹
- 在 hooks 文件夹中创建 usexxx.js 文件 (一般都以 use- 开头)
- 在 usexxx.js 中进行函数封装,并暴露出来
- 记得在函数最后返回要用到的属性
- 最后在组件中导入它就可以使用了
./hook/usePoint.js:定义鼠标打点的相关内容
import { reactive, onMounted, onBeforeUnmount } from "vue"; export default function savePoint() { // 实现鼠标打点相关的数据 let point = reactive({ x: 0, y: 0, }); // 实现鼠标打点相关的方法 function savePoint(event) { point.x = event.pageX; point.y = event.pageY; console.log(event.pageX, event.pageY); } // 实现鼠标打点相关的钩子 onMounted(() => { window.addEventListener("click", savePoint); }); onBeforeUnmount(() => { window.removeEventListener("click", savePoint); }); return point }
Demo.vue:导入 hooks 文件夹里面的 js 文件,直接使用
<template> <div> <h3>当前点击时鼠标的坐标为:x:{{point.x}}, y:{{point.y}}</h3> </div> </template> <script> import usePoint from '../hooks/usePoint' export default { name: "Demo", setup() { // 数据 let point = usePoint() // 返回一个对象 return { point }; }, }; </script>
初始点:
找到了个浪漫点:
二、toRef 和 toRefs
toRef
- 作用:创建一个 ref 对象,其 value 值指向另一个对象中的某个属性
// 语法 const name = toRef(person, 'name')
- 应用:要将响应式对象中的某个属性单独提供给外部使用时
- 实例:
- 在返回的对象中,每个属性都用 toRef() 响应式接收
- 在模板字符串里面直接写属性名,就不用使用 . 获取了
<template> <div> <h3>姓名:{{name}}</h3> <h3>年龄:{{age}}</h3> <h3>薪资:{{salary}}K</h3> <button @click="name+='~'">修改姓名</button> <button @click="age++">增长年龄</button> <button @click="salary++">增加薪资</button> </div> </template> <script> import { reactive, toRef } from "vue"; export default { name: "Demo", setup() { // 数据 let person = reactive({ name: '张三', age: 18, job: { j1:{ salary: 20 } } }) // 返回一个对象 return { name: toRef(person, 'name'), age: toRef(person, 'age'), salary: toRef(person.job.j1, 'salary') }; }, }; </script>
分别点击各个按钮数次后(响应式更新):
toRefs
作用:toRefs 与 toRef 功能一致,但可以批量创建多个 ref 对象,语法 toRefs(person)
实例:
toRefs 是一个对象,对象里面不能直接写对象,所有使用 ... 展开运算符
只对 person 的一级键值对有效,更深层次的还是需要通过 . 手动获取
<template> <div> <h3>姓名:{{name}}</h3> <h3>年龄:{{age}}</h3> <h3>薪资:{{job.j1.salary}}K</h3> <button @click="name+='~'">修改姓名</button> <button @click="age++">增长年龄</button> <button @click="job.j1.salary++">增加薪资</button> </div> </template> <script> import { reactive, toRefs } from "vue"; export default { name: "Demo", setup() { // 数据 let person = reactive({ name: '张三', age: 18, job: { j1:{ salary: 20 } } }) // 返回一个对象 return { ...toRefs(person) }; }, }; </script>
分别点击各个按钮数次后(响应式更新):
不积跬步无以至千里 不积小流无以成江海