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:逻辑来源透明、无命名冲突、易于测试与复用。

笔记加载中…