阅读笔记 | vue3的hooks/ vue2的mixin
阅读文章:理解Vue3中的hooks(为什么要用hooks)
作者:会飞的特洛伊
链接:https://juejin.cn/post/7208111879150993464
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
阅读笔记系列会更新一些文章的摘要内容与自己的一些补充理解,用于记录与复习。
原文摘要一般正文表示,补充理解或查阅资料的补充一般引用表示。
mixin混入
混入是一种思想,可以抽象理解成组件的组件。
mixin的功能
- 逻辑函数的复用
- vue 组件中的选项式API(例如:data,computed,watch)或者组件的生命周期钩子(created、mounted、destroyed)
这里可以看出两个特点
1.与vue组件的区别是没有模板(template)/视图板块,只提供复用的功能逻辑。=> 解构UI和逻辑。
2.与抽离复用逻辑的js文件的区别是可以使用vue组件中的配置。
mixin的使用
在vue中,mixin定义的就是一个对象,对象中放置的vue组件相应的选项式API和对应的生命周期钩子。
案例
// 定义一个mixin
export const mixins = {
data() {
return {
msg: "我是小猪课堂",
};
},
computed: {},
created() {
console.log("我是mixin中的created生命周期函数");
},
mounted() {
console.log("我是mixin中的mounted生命周期函数");
},
methods: {
clickMe() {
console.log("我是mixin中的点击事件");
},
},
};
//
// src/App.vue中使用导出的mixin
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<button @click="clickMe">点击我</button>
</div>
</template>
<script>
import { mixins } from "./mixin/index";
export default {
name: "App",
mixins: [mixins], // 注册mixin,这样mixin中所有的钩子函数等同于组件中钩子
components: {},
created(){
console.log("组件调用minxi数据",this.msg);
},
mounted(){
console.log("我是组件的mounted生命周期函数")
}
};
</script>
说明
- mixin中的生命周期函数会和组件的生命周期函数一起合并执行。
- mixin中的data数据在组件中也可以使用。
- mixin中的方法在组件内部可以直接调用。
- 生命周期函数合并后执行顺序:先执行mixin中的,后执行组件的。
- 同名函数冲突问题,本组件中优先级高于mixin
优点与缺点
- 优点:组件中钩子函数的注册复用
- 缺点
- 相同钩子中注册的函数名相同会发生冲突,组件的
data
、methods
、filters
会覆盖mixins里的同名data
、methods
、filters
- 定位错误需要花费时间
- 隐式传入,变量来源不明确,不利于阅读,使代码变得难以维护
- 相同钩子中注册的函数名相同会发生冲突,组件的
hooks
mixin是options API的体现,hooks 是composition API的体现。
hooks = 逻辑函数 + vue3 composition api
mixin = 逻辑函数 + vue2 options api
说明
1.vue3 的 hook函数 相当于 vue2 的 mixin(对象), 但是 hooks 是函数
2.vue3 的 hook函数 可以帮助我们提高代码的复用性, 让我们能在不同的组件中都利用 hooks 函数
import {ref} from 'vue'
// 导出1个 name_hooks.ts文件
// hooks中不用写在setup中
export const name_hooks = function(value: string) {
const name = ref('')
const setName = (value: string) => {
name.value = value
}
return {
name, setName
}
}
// 引入hooks文件
<template>
<div>{{ name }}</div>
<select @change="setName"></select> // 这里select组件的change事件会自动传value值
// 然后value值作为传参传递给setName
</template>
<script setup lang='ts'>
import { name_hooks } from './name_hooks'
const { name, setName } = name_hooks() // 注意: 通常需要通过解构赋值将需要的属性方法添加进组件中,解构时需要注意响应式丢失的问题
</script>
工作上发现使用hooks的一个场景
每一个组件基本都会细分到实现一种功能,比如播放条是一个组件。复用时,很多时候并不关心功能如何实现,而是关注这个组件有哪些功能(比如播放、暂停、跳转播放等)。
为了方便阅读和维护,会将该组件的逻辑代码抽离成一个或多个hooks文件。每个功能将需要的数据聚合在一起写成一个函数形式,函数的返回值就是供组件使用的数据。最后将每个功能函数分别export 出来。
自定义hook规范
1.将可复用功能抽离为外部JS文件
2.函数名和文件名以use
开头,比如usePlayBar
3.引用时将需要的变量或者方法显示解构暴露出来,比如const {play,pause} = usePlayBar()