Vue3 混入
多个组件经常出现重复的 data、methods、computed——复制粘贴会让代码难以维护。混入(Mixin)就是一种分发复用的机制:把公共选项抽取成一个对象,任何组件都能"混入"它。需要说明的是,混入属于选项式 API 的复用方式,组合式 API 项目更推荐用 composable(组合式函数)替代。
定义混入并使用
混入本质上就是一个普通的选项对象,可以包含 data、methods、computed、生命周期钩子等。把它写进组件的 mixins 数组即可合并使用:
// src/mixins/hello.js
export const helloMixin = {
data() {
return { msg: '来自混入的数据' }
},
created() {
console.log('混入的 created 执行了')
},
}
<template>
<p>{{ msg }}</p>
</template>
<script>
import { helloMixin } from './mixins/hello'
export default {
mixins: [helloMixin],
}
</script>
效果:模板可以直接使用混入提供的 msg,同时混入的 created 钩子也会自动执行。
全局混入
使用 app.mixin 注册后,所有组件都会自动获得这些选项,通常只用来注入插件级、跨全局的公共逻辑:
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mixin({
created() {
console.log('全局混入:每个组件创建时都执行')
},
})
app.mount('#app')
注意:全局混入会影响所有组件,业务代码慎用,避免污染太多无关组件。
选项合并规则
混入与组件本身的选项冲突时,遵循以下规则:
- 生命周期钩子:全部执行,混入的钩子先执行,组件自己的后执行;
- data:组件内的数据优先,同名属性以组件为准;
- methods 与 computed:组件内的同名方法、计算属性覆盖混入的。
const mix = {
data: () => ({ name: '混入' }),
created() { console.log('先打印我') },
}
export default {
mixins: [mix],
data: () => ({ name: '组件' }),
created() { console.log('再打印我,name =', this.name) },
}
// 效果:控制台依次输出"先打印我"、"再打印我,name = 组件"
混入 vs 组合式函数
组合式 API 出现后,官方更推荐用 composable 替代 mixin:它只是普通函数,数据来源清晰、不会因同名属性产生隐式覆盖,对 TypeScript 也更友好:
// src/composables/useCounter.js
import { ref } from 'vue'
export function useCounter() {
const count = ref(0)
const add = () => count.value++
return { count, add }
}
<script setup>
import { useCounter } from './composables/useCounter'
const { count, add } = useCounter()
</script>
<template>
<button @click="add">数量:{{ count }}</button>
</template>
小结
混入通过 mixins 数组把公共选项混合进组件,并遵循清晰的合并规则,理解它有助于阅读既有项目代码。新项目建议优先选择 composable:逻辑来源透明、无命名冲突、易于测试与复用。