Vue3 Mixins 的使用方式
mixin的用处:主要用于多个组件内存在重复JS业务逻辑(可以包括methods,mounted,watch等等),将该JS部分代码封装在一个js文件下对外暴露,需要使用的组件进行引用。
当多个组件,或者页面使用相同的逻辑,可以考虑使用 mixins 把公共部分提取。类似于于封装组件,再把代码导入到组件的意思
Vue3中已经不推荐使用
Mixins 在 Vue 3 支持主要是为了向后兼容,因为生态中有许多库使用到。在新的应用中应尽量避免使用 mixin,特别是全局 mixin。若要进行逻辑复用,推荐用组合式函数来替代。
和 Mixin 的对比
Vue 2 的用户可能会对 mixins 选项比较熟悉。它也让我们能够把组件逻辑提取到可复用的单元里。然而 mixins 有三个主要的短板:
不清晰的数据来源:当使用了多个 mixin 时,实例上的数据属性来自哪个 mixin 变得不清晰,这使追溯实现和理解组件行为变得困难。这也是我们推荐在组合式函数中使用 ref + 解构模式的理由:让属性的来源在消费组件时一目了然。
命名空间冲突:多个来自不同作者的 mixin 可能会注册相同的属性名,造成命名冲突。若使用组合式函数,你可以通过在解构变量时对变量进行重命名来避免相同的键名。
隐式的跨 mixin 交流:多个 mixin 需要依赖共享的属性名来进行相互作用,这使得它们隐性地耦合在一起。而一个组合式函数的返回值可以作为另一个组合式函数的参数被传入,像普通函数那样。
基于上述理由,我们不再推荐在 Vue 3 中继续使用 mixin。保留该功能只是为了项目迁移的需求和照顾熟悉它的用户。
实操对比 vue2 Mixins 在 vue3的区别,封装一个发送验证码的函数 sendVerifyCode.js
vue2 的 sendVerifyCode.js
export default {
data() {
return {
disabled: false,
text: "获取验证码"
};
},
methods: {
sendCode() {
if (this.disabled) return;
this.disabled = true;
let n = 60;
this.text = "剩余 " + n + "s";
const run = setInterval(() => {
n = n - 1;
if (n < 0) {
clearInterval(run);
}
this.text = "剩余 " + n + "s";
if (this.text < "剩余 " + 0 + "s") {
this.disabled = false;
this.text = "重新获取";
}
}, 1000);
}
}
};
vue2中直接使用mixins即可将disabled
,text
,sendCode
函数导入到Login.vue
页面, 点击按钮时可修改按钮文字为倒计时
vue2 的 Login.vue
<template>
<button:disabled="disabled" :class="disabled === true ? 'on' : ''" @click="sendCode">
{{ text }}
</button>
</template>
<script>
import { sendVerifyCode } from './sendVerifyCode.js'
export default {
mixins: [sendVerifyCode],
data() {
return {
};
},
methods: {
}
};
</script>
vue3 的 sendVerifyCode.js
import { ref } from 'vue'
export function useSendCode() {
const disabled = ref(false)
const text = ref('获取验证码')
function sendCode(){
if (disabled.value) return;
disabled.value = true;
let n = 60;
text.value = "剩余 " + n + "s";
const run = setInterval(() => {
n = n - 1;
if (n < 0) {
clearInterval(run);
}
text.value = "剩余 " + n + "s";
if (text.value < "剩余 " + 0 + "s") {
disabled.value = false;
text.value = "重新获取";
}
}, 1000);
}
return {
disabled,
text,
sendCode
};
}
vue3 的 Login.vue
<template>
<button:disabled="disabled" :class="disabled === true ? 'on' : ''" @click="sendCode">
{{ text }}
</button>
</template>
<script setup>
import { useSendCode } from './sendVerifyCode.js'
// 解构useSendCode的返回值
const {disabled, text, sendCode} = useSendCode();
</script>
对比之后发现vue2
与vue3
的写法核心逻辑完全一致,我们做的只是把它移到一个外部函数中去,并返回需要暴露的状态,而vue3的组合式写法更加清晰,少写很多格式代码