Vue Mixins
在讲hooks之前,先讲一下mixin,mixins和hooks很相似,不同在与 hooks 是函数,其实Hooks很好地解决了mixins存在的一些缺点,如果有知道mixin的可以直接跳过。
mixins(vue2)
mixins的基础
mixin就是混入的意思,下面是官方文档的介绍:”它提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项“。
通俗一点,就类似于java里面的多重继承!如果多个组件中有一些相同的逻辑,那么通过mixins就可以实现共用这些代码,避免代码冗余,就类似与组件的js之间合并在一起,共享行为。
mixins的使用
export default { data(){ return { count:0, } }, methods:{ getCount(){ console.log("我是mixins-"+this.count); }, }, created(){ console.log("我是mixins-created"); }, mounted(){ console.log("我是mixins-mounted"); } }
讲mixins引入组件即可使用
<template> </template> <script> import mixin from "@...../mixin.js" export default{ mixins:[common], created(){ console.log("我是component-created"); }, mounted(){ console.log("我是component-mounted"); } methods:{ getCount(){ console.log("我是component-"+this.count); }, }, } </script>
|
mixins的特性:
- mixins中的生命周期会会和引入的mixins的生命周期整合在一起,并且是混入对象的钩子将在组件自身钩子之前调用。
//如上面的的代码将依次输出 我是mixins-created 我是mixins-mounted 我是component-created 我是component-mounted
|
2. 如果mixins和组件的键名冲突时,取组件对象的键值对。(个人觉得和混入对象的钩子将在组件自身钩子**之前**调用相同的原因)
var mixin = { methods: { foo: function () { console.log('foo') }, conflicting: function () { console.log('from mixin') } } }
var vm = new Vue({ mixins: [mixin], methods: { bar: function () { console.log('bar') }, conflicting: function () { console.log('from self') } } })
vm.foo() vm.bar() vm.conflicting()
|
mixins和vuex区别
Mixins:mixins定义的共用变量,可以在每个组合后的组件中使用,但mixins引入到组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。
vuex:vuex主要用来做状态管理,类似于全局变量和全局方法,里面定义的states在各个组件都可以用,在任一组件中修改此变量的值之后,其他组件中此变量的值也会被修改。
mixins和父子组件的区别
组件:父子组件当中,相当于在父组件中给出一片独立的空间供子组件使用,然后根据props或者$emit来传递信息,但本质上两者是相对独立的。
Mixins:在引入组件之后与组件中的对象和方法进行合并,相当于扩展了父组件的对象与方法,可以理解为形成了一个新的组件。(装饰器模式)
mixins的缺点
假如是引入了多个 mixins 的话, data 来源不明确(隐式引入),就是不清楚一些变量方法是来自哪个mixin?不利于维护
多个 mixins 的生命周期会融合到一起运行,但是同名属性、同名方法无法融合,可能会导致冲突。
比如 mixin1 中的方法getCount() 是要输出 mixin1 的变量 count1 ,但是 mixin2 也是用了相同的方法名getCount(),但它输出的是 mixin2 的的变量count2
这是这时mixin1的getCount可能就会被覆盖了,就会造成一些bug了
mixins和组件可能出现多对多的关系,复杂度较高(即一个组件可以引用多个mixins,一个mixins也可以被多个组件引用)
可以说mixins的缺点是推动vue3 Composition API背后的主要推动因素之一!
自定义Hooks (Vue3)
个人还没系统学习过Vue3,这里也只是简单尝尝鲜,找时间再补Vue3!
vue3实现的mixins和vue2的区别个人理解就是,vue3 是通过自定义hook函数,而mixins是合并对象。我们将所复用的变量从新的setup(vue3)函数返回js变量,而不是以组件功能去实现。
这里通过一个官方例子来学习自定义Hooks的使用,以及考虑它是怎么解决mixins的缺点的。
import { ref, onMounted, onUnmounted } from "vue";
export function useMousePosition() { const x = ref(0); const y = ref(0);
function update(e) { x.value = e.pageX; y.value = e.pageY; }
onMounted(() => { window.addEventListener("mousemove", update); });
onUnmounted(() => { window.removeEventListener("mousemove", update); });
return { x, y }; }
import { useMousePosition } from "./mouse"; export default { setup() { const { x, y } = useMousePosition(); return { x, y }; }, };
|
虽然看起来自定义hooks实现的mixins的运用回略显繁琐,但其实这样子才解决了 vue2 mixins 的缺点
从代码就可以看出mouse的x,y来自useMousePosition,这种显示引入很快就可以帮我们找到变量来源,假如有命名冲突也可以通过显示命名解决了,如下:
import { useMousePosition1 } from "./mouse1"; import { useMousePosition2 } from "./mouse2"; export default { setup() { const { mouse1.x, mouse1.y } = useMousePosition1(); const { mouse2.x, mouse2.y } = useMousePosition2(); return { mouse1.x, mouse1.y, mouse2.x, mouse2.y }; }, };
|
当然这只是简单的运用,至于里面的原理大家感兴趣可以了解一下,也可以带着着个问题去学习一下vue3的新特性!
参考链接
- mixins和vuex区别_hkduan的博客-CSDN博客_vuex和mixins
- Vue2/Vue3中的代码逻辑复用对比(mixins、自定义hook) - 起源地 (qiyuandi.com)
- Vue3 Composition API如何替换Vue Mixins_慕课手记 (imooc.com)