混入

    例子:

    当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。

    比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。

    1. data() {
    2. return {
    3. message: 'hello',
    4. foo: 'abc'
    5. }
    6. }
    7. }
    8. const app = Vue.createApp({
    9. mixins: [myMixin],
    10. data() {
    11. return {
    12. message: 'goodbye',
    13. bar: 'def'
    14. }
    15. },
    16. created() {
    17. console.log(this.$data) // => { message: "goodbye", foo: "abc", bar: "def" }
    18. }
    19. })

    同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。

    1. const myMixin = {
    2. created() {
    3. console.log('mixin hook called')
    4. }
    5. }
    6. const app = Vue.createApp({
    7. mixins: [myMixin],
    8. created() {
    9. console.log('component hook called')
    10. })
    11. // => "混入对象的钩子被调用"
    12. // => "组件钩子被调用"

    你还可以为 Vue 应用程序全局应用 mixin:

    1. const app = Vue.createApp({
    2. myOption: 'hello!'
    3. })
    4. // 为自定义的选项 'myOption' 注入一个处理器。
    5. app.mixin({
    6. created() {
    7. const myOption = this.$options.myOption
    8. if (myOption) {
    9. console.log(myOption)
    10. }
    11. }
    12. })
    13. app.mount('#mixins-global') // => "hello!"

    混入也可以进行全局注册。使用时格外小心!一旦使用全局混入,它将影响每一个之后创建的组件 (例如,每个子组件)。

    1. const app = Vue.createApp({
    2. myOption: 'hello!'
    3. })
    4. // 为自定义的选项 'myOption' 注入一个处理器。
    5. app.mixin({
    6. created() {
    7. const myOption = this.$options.myOption
    8. if (myOption) {
    9. console.log(myOption)
    10. }
    11. }
    12. })
    13. // 将myOption也添加到子组件
    14. app.component('test-component', {
    15. })
    16. app.mount('#mixins-global')
    17. // => "hello!"
    18. // => "hello from component!"

    大多数情况下,只应当应用于自定义选项,就像上面示例一样。推荐将其作为发布,以避免重复应用混入。

    自定义选项将使用默认策略,即简单地覆盖已有值。如果想让自定义选项以自定义逻辑合并,可以向 app.config.optionMergeStrategies 添加一个函数:

    1. const app = Vue.createApp({
    2. custom: 'hello!'
    3. })
    4. app.config.optionMergeStrategies.custom = (toVal, fromVal) => {
    5. console.log(fromVal, toVal)
    6. // => "goodbye!", undefined
    7. // => "hello", "goodbye!"
    8. return fromVal || toVal
    9. }
    10. app.mixin({
    11. custom: 'goodbye!',
    12. created() {
    13. console.log(this.$options.custom) // => "hello!"
    14. }
    15. })

    如你所见,在控制台中,我们先从 mixin 打印 toValfromVal,然后从 app 打印。如果存在,我们总是返回 fromVal,这就是为什么 this.$options.custom 设置为 你好! 最后。让我们尝试将策略更改为始终从子实例返回值:

    1. const app = Vue.createApp({
    2. custom: 'hello!'
    3. })
    4. app.config.optionMergeStrategies.custom = (toVal, fromVal) => toVal || fromVal
    5. app.mixin({
    6. custom: 'goodbye!',
    7. created() {
    8. console.log(this.$options.custom) // => "goodbye!"
    9. })

    在 Vue 2 中,mixin 是将部分组件逻辑抽象成可重用块的主要工具。但是,他们有几个问题:

    • 可重用性是有限的:我们不能向 mixin 传递任何参数来改变它的逻辑,这降低了它们在抽象逻辑方面的灵活性