Vue.js 2.x 混入

Vue.js 2.x mixins

混入

混入(mixins)是一种分发vue组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。

Demo源码

例子:

<div id="app">
    <ul>
        <li>a: {{ a }}</li>
        <li>b: {{ b }}</li>
    </ul>
</div>

<script type="text/javascript">
    const myMixin = {
        data() {
            return {
                a: 1
            }
        },
        methods: {
            sayHello() {
                console.log('Hello world!');
            }
        },
        mounted() {
            this.sayHello();
        }
    };

    new Vue({
        el: '#app',
        mixins: [myMixin],
        data() {
            return {
                b: 2
            }
        }
    });

</script>

选项合并

当组件和混入对象有同名选项时,不同的选项将以不同的恰当方式混合。

选项 优先级(最终保留) 方式
数据对象(data) 组件 递归合并
钩子函数 - 都保留,混入对象钩子在组件钩子之前调用
对象(methods/components/directives) 组件 混为一个对象
数据对象(data)

值类型直接按照组件优先进行覆盖。
对象如果键名有重复,按照组件键值优先进行覆盖。
数组直接按照组件的值进行覆盖。

比如:

<div id="app">
    <ul>
        <li>a: {{ a }}</li>
        <li>b: {{ b }}</li>
        <li>c: {{ c }}</li>
        <li>obj.a: {{ obj.a }}</li>
        <li>obj.b: {{ obj.b }}</li>
        <li>obj.c: {{ obj.c }}</li>
    </ul>
    <ul>
        <li v-for="item in arr">{{ item.id }}: {{ item.name }}</li>
    </ul>
    <ul>
        <li v-for="item in arr2">{{ item }}</li>
    </ul>
</div>

<script src="../vendor/vue.js"></script>
<script type="text/javascript">
    const myMixin = {
        data() {
            return {
                a: 1,
                c: 3,
                obj: {
                    a: 1,
                    b: 2
                },
                arr: [
                    { id: 1, name: 'a' },
                    { id: 2, name: 'b' }
                ],
                arr2: [1, 2, 3]
            }
        },
        methods: {
            sayHello() {
                console.log('Hello world!');
            }
        },
        mounted() {
            this.sayHello();
        }
    };

    new Vue({
        el: '#app',
        mixins: [myMixin],
        data() {
            return {
                b: 2,
                c: 4,
                obj: {
                    b: 3,
                    c: 3
                },
                arr: [
                    { id: 2, name: 'b2' },
                    { id: 3, name: 'c' }
                ],
                arr2: [3, 4, 5]
            }
        }
    });
</script>

钩子函数

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

const myMixin2 = {
    created() {
        console.log('%s created hook!', 'mixin');
    }
};

new Vue({
    mixins: [myMixin2],
    created() {
        console.log('%s created hook!', 'component');
    }
});

// mixin created hook!
// component created hook!
对象选项(methodscomponentsdirectives

将被混合为一个对象,两个对象键名冲突时,取组件对象 的键值对。
watch将被全部保留,且混入对象中的watch先于组件执行。
computed将只保留组件。

<div id="app2">
    <p>{{ r }}</p>
</div>

<script src="../vendor/vue.js"></script>
<script type="text/javascript">
    const myMixin3 = {
        data() {
            return {
                a: 1
            }
        },
        methods: {
            foo() {
                console.log('This is foo');
            },
            bar() {
                console.log('This is bar');
            }
        },
        watch: {
            a(v) {
                console.log('watch value from mixin: %s', v);
            }
        },
        computed: {
            r() {
                return `computed value from mixin: ${ this.a }`;
            }
        }
    };

    const vm = new Vue({
        mixins: [myMixin3],
        el: '#app2',
        data() {
            return {
                b: 2
            }
        },
        watch: {
            a(v) {
                console.log('watch value from component: %s', v + this.b);
            }
        },
        computed: {
            r() {
                return `computed value from component: ${ this.a * this.b }`;
            }
        },
        methods: {
            bar() {
                console.log('This is balabala');
            },
            count() {
                this.a++;
            }
        },
        created() {
            setInterval(() => {
                this.count();
            }, 2000);
        }
    });

    vm.foo(); // This is foo
    vm.bar(); // This is balabala

</script>

全局混入

可以在Vue上进行全局混入,将会影响到所有之后创建的Vue实例,之前的不会影响。
使用时应当像下面的例子一样,只应用于自定义选项,避免影响过多。

Vue.mixin({
	created() {
		const isTrigger = this.$options.trigger;
		if (!isTrigger) return;
		console.log('Global mixin created hook log.');
	}
});

new Vue({
	trigger: true,
	created() {
		console.log('A component after global mixin.');
	}
});

// Global mixin created hook log.
// A component after global mixin.

自定义选项合并策略

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

原文
Last updated by Jehorn 3PM, July 24, 2019

posted @ 2019-07-24 15:16  古宝只  阅读(303)  评论(0编辑  收藏  举报