使用场景
在Vue3
中,使用什么API
就引入,这个就是组合式 API
。
然而,有时引入很多的API
就不利于代码的阅读。
所以,在 Vue3
中新增了 Hook
,可以通过自定义hook
函数来存放组合式API
的东西,在需要的时候再进行引用。
概念
hook
:其本质是一个函数,把 setup
函数中使用的 Composition API
放到一个文件中进行了封装,然后在需要用到的地方,进行引入,类似于 vue2.x
中的 mixin
。
自定义hook
的优势
自定义 hook
能够复用代码,让setup
中的逻辑更清楚易懂。
实例
TestPage.vue
<template><p>The title is&#xff1a;{{ title }}</p><p>The currt count is&#xff1a;{{ currCount }}</p><a-button &#64;click&#61;"plusCount(3)" type&#61;"primary">click me plus count</a-button><a-button &#64;click&#61;"minusCount()">click me minus count</a-button><a-button &#64;click&#61;"set(5)" type&#61;"danger">click me set count</a-button><a-button &#64;click&#61;"reset" type&#61;"dashed">click me reset count</a-button>
</template><script lang&#61;"ts">
import { ref } from &#39;vue&#39;
import setCount from &#39;./hook/setCount&#39;export default {name: &#39;test&#39;,props: {msg: String,},setup() {const title &#61; ref(&#39;This is test page&#39;)const {current: currCount,plusCount,minusCount,set,reset,} &#61; setCount(2, {min: 1,max: 15,})return {title,currCount,plusCount,minusCount,set,reset,}},
}
</script>
/hook/setCount.ts&#xff1a;
import { ref, Ref, watch } from &#39;vue&#39;
interface Range {min?: number,max?: number
}
interface Result {current: Ref<number>,plusCount: (delta?: number) &#61;> void,minusCount: (delta?: number) &#61;> void,set: (value: number) &#61;> void,reset: () &#61;> void
}export default function useCount(initialVal: number, range?: Range): Result {const current &#61; ref(initialVal)const plusCount &#61; (delta?: number): void &#61;> {if (typeof delta &#61;&#61;&#61; &#39;number&#39;) {current.value &#43;&#61; delta} else {current.value &#43;&#61; 1}}const minusCount &#61; (delta?: number): void &#61;> {if (typeof delta &#61;&#61;&#61; &#39;number&#39;) {current.value -&#61; delta} else {current.value -&#61; 1}}const set &#61; (value: number): void &#61;> {current.value &#61; value}const reset &#61; () &#61;> {current.value &#61; initialVal}watch(current, (newVal: number, oldVal: number) &#61;> {if (newVal &#61;&#61;&#61; oldVal) {return}if (range && range.min && newVal < range.min) {current.value &#61; range.min} else if (range && range.max && newVal > range.max) {current.value &#61; range.max}})return {current,plusCount,minusCount,set,reset}
}
有时候&#xff0c;一个组件里面可能会使用多个 hook
&#xff0c;如下&#xff1a;
/hook/setStudent.ts&#xff1a;
import { reactive } from "vue";export default function() {let student &#61; reactive({name: "xiao ming",age:18, changeInfomation() {student.name &#61; "xiaofang"student.age &#61; 20}})return student;
}
修改 TestPage.vue&#xff1a;
<template><p>The title is&#xff1a;{{ title }}</p><p>The student name is:{{stu.name}}</p><p>The student age is:{{stu.age}}</p><a-button &#64;click&#61;"stu.changeInfomation" type&#61;"primary">click me change the student&#39;s information</a-button><p>The currt count is&#xff1a;{{ currCount }}</p><a-button &#64;click&#61;"plusCount(3)" type&#61;"primary">click me plus count</a-button><a-button &#64;click&#61;"minusCount()">click me minus count</a-button><a-button &#64;click&#61;"set(5)" type&#61;"danger">click me set count</a-button><a-button &#64;click&#61;"reset" type&#61;"dashed">click me reset count</a-button>
</template><script lang&#61;"ts">
import { ref } from &#39;vue&#39;
import setCount from &#39;./hook/setCount&#39;
import setStudent from &#39;./hook/setStudent&#39;export default {name: &#39;test&#39;,props: {msg: String,},setup() {const title &#61; ref(&#39;This is test page&#39;)const {current: currCount,plusCount,minusCount,set,reset,} &#61; setCount(2, {min: 1,max: 15,})return {title,currCount,plusCount,minusCount,set,reset,stu: setStudent(),}},
}
</script>
页面效果&#xff1a;
Hook
的特征之一&#xff1a;可以在组件外去写一些自定义 Hook
&#xff0c;所以&#xff0c;不仅可以在.vue
组件内部使用Vue
的能力&#xff0c;而且&#xff0c;在任意的文件下&#xff08;如setCount.ts
&#xff09;下也可以。