在Vue 3中,混入(Mixin)是一种将可重用功能和逻辑添加到组件中的方式。混入可以包含组件选项,如data
、methods
、created
等,这样您可以在多个组件中重复使用相同的逻辑,而不必重复编写代码。混入提供了一种模块化的方式来组织和复用组件功能。
混入允许您将共享的逻辑封装到一个混入对象中,然后将混入对象应用到一个或多个组件中。这使得在不同的组件中共享通用功能变得更容易。混入对象中的选项将会被合并到组件的选项中。
mixins
以下是一个简单的混入示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const myMixin = { data() { return { message: 'Hello from mixin!', }; }, methods: { showMessage() { console.log(this.message); }, }, };
const myComponent = { mixins: [myMixin], template: '<div><button @click="showMessage">Show Message</button></div>', };
const app = Vue.createApp(myComponent); app.mount('#app');
|
点击Show Message
按钮后则会输出如下结果
在上面的示例中,myMixin
是一个混入对象,包含了data
和methods
选项。然后,我们创建一个myComponent
组件,并将myMixin
混入应用到该组件中。这使得message
和showMessage
方法在myComponent
中可用。
需要注意的是,混入可以包含任何选项,包括data
、methods
、computed
、watch
等,但当多个混入对象具有相同的选项时,Vue 将会以一定的策略进行合并。这些策略可能会导致一些潜在的命名冲突,因此在使用混入时需要小心谨慎。通常,建议给混入的数据和方法命名时使用唯一的前缀或命名空间,以避免命名冲突。
选项合并
当组件和混入对象含有同名选项时,这些选项将以恰当的方式混合。
数据对象合并
数据对象在内部会进行浅合并 (一层属性深度),在和组件的数据发生冲突时以组件数据优先。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 混入</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id = "app"></div> <script>
const myMixins={ data(){ return{ message:'hello from myMinx', } }, methods: { changeMessage(){ console.log(this.message) } } }
const MyComponent={ mixins:[myMixins], template: `<div><button @click="changeMessage">changeMessage</button></div>`, data(){ return{ message:'hello from MyComponent ' } } }
Vue.createApp(MyComponent).mount('#app'); </script> </body> </html>
|
钩子函数合并
同名钩子函数将合并为一个数组,因此都将被调用。另外,mixin 对象的钩子将在组件自身钩子之前调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 钩子函数混入</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id = "app"></div> <script>
const myMixins={ created(){ console.log('mixin 对象的钩子被调用'); }, }
const MyComponent={ mixins:[myMixins], created(){ console.log('组件的钩子被调用'); } }
Vue.createApp(MyComponent).mount('#app'); </script> </body> </html>
|
执行结果
函数合并
值为对象的选项,例如 methods、components
和 directives
,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 函数合并</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id = "app"></div> <script> const myMixin = { methods: { foo() { console.log('foo') }, conflicting() { console.log('from mixin') } } } const app = Vue.createApp({ mixins: [myMixin], methods: { bar() { console.log('bar') }, conflicting() { console.log('from self') } } }) const vm = app.mount('#app') vm.foo() vm.bar() vm.conflicting() </script> </body> </html>
|
执行结果
全局混入
全局混入可以全局注册混入对象。注意使用! 一旦使用全局混入对象,将会影响到 所有 之后创建的 Vue 实例。使用恰当时,可以为自定义对象注入处理逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 全局混入</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id = "app"></div> <script type = "text/javascript"> const app = Vue.createApp({ myOption: 'hello!' })
app.mixin({ created() { const myOption = this.$options.myOption if (myOption) { document.write(myOption) } } }) app.mount('#app') </script> </body> </html>
|
代码解析
上面代码定义一个名为 myOption
的自定义选项,并将其设置为 'hello!'
。
然后,通过以下代码段,使用全局混入 (app.mixin
) 注入一个处理器,该处理器在每个组件实例的 created
钩子中检查 myOption
并在文档中打印它:
当你调用 app.mount('#app')
时,Vue 应用实例会根据自定义选项 myOption
的值 'hello!'
执行全局混入中的 created
钩子,然后在页面上输出 "hello!"
。
参考资料