在 Vue 中,mixin
是一种分发 Vue 组件中可复用功能的非常灵活的方式。你可以把多个组件中公用的逻辑抽离出来,然后通过 mixin
的方式“混入”组件中,减少代码重复。
🌟 基本使用方式
定义一个 mixin
:
// myMixin.js
export const myMixin = {data() {return {message: 'Hello from mixin!'}},created() {console.log('mixin created')},methods: {greet() {console.log(this.message)}}
}
在组件中使用它:
<script>
import { myMixin } from './myMixin'export default {mixins: [myMixin],created() {console.log('component created')}
}
</script>
控制台输出顺序是:
mixin created
→component created
🧠 特点与合并规则
-
生命周期钩子:多个
created
等生命周期函数会依次调用,先执行 mixin 里的,再执行组件里的。 -
data:
data
会进行合并,如果有重名属性,组件内的会覆盖 mixin 的。 -
methods、computed、components:这些会合并,同名的会被组件自身的覆盖。
✅ 使用场景
-
多个组件都有类似的逻辑,比如页面滚动监听、数据格式化、权限控制等。
-
封装一些通用逻辑,比如 API 调用、表单校验等。
⚠️ 注意事项
虽然 mixin
很方便,但当项目变大、混入过多时会导致:
-
来源不明确,不好追踪逻辑。
-
属性冲突难排查。
所以在 Vue 3 中,推荐使用 组合式 API(Composition API) 来代替 mixin
,用 setup
+ 自定义 hooks
会更清晰、可维护。
在 Vue 3 中,推荐用 Composition API 替代 mixin,主要是为了让逻辑更加清晰、可组合、可复用。
✅ 推荐做法:使用组合式 API + 自定义 composable(逻辑抽离)
Vue 3 不再推荐 mixins
,而是鼓励用 组合式 API(setup()
)+ 可组合函数(composables) 来实现逻辑复用。
🧩 示例:用 composable 替代 mixin
🎯 目标:封装一个“窗口宽度监听”的逻辑(原本可能会写在 mixin 中)
✅ 新写法(推荐的 Vue 3 用法)
// useWindowSize.js
import { ref, onMounted, onUnmounted } from 'vue'export function useWindowSize() {const width = ref(window.innerWidth)const height = ref(window.innerHeight)const update = () => {width.value = window.innerWidthheight.value = window.innerHeight}onMounted(() => {window.addEventListener('resize', update)})onUnmounted(() => {window.removeEventListener('resize', update)})return { width, height }
}
在组件中使用:
<script setup>
import { useWindowSize } from './useWindowSize'const { width, height } = useWindowSize()
</script><template><div>宽度:{{ width }},高度:{{ height }}</div>
</template>
✅ 优势对比
特性 | mixin | composable |
---|---|---|
可读性 | 🌧 多个来源混入,逻辑分散 | ☀️ 函数式封装,清晰独立 |
逻辑复用 | 有,但容易命名冲突 | 强,命名作用域明确 |
调试方便 | 否,逻辑混乱 | 是,函数调用链清晰 |
类型推导 | 差(TS 支持弱) | 好,TS 友好 |
✨ 常用内置组合式 API
功能 | API |
---|---|
生命周期 | onMounted , onUpdated , onUnmounted , onBeforeMount , 等 |
响应式 | ref , reactive , computed , watch , watchEffect |
依赖注入 | provide , inject |
DOM 绑定 | onMounted + ref |