Vue.js 的 mixin 到底有什么作用?一篇博文让你明白它的作用!

好久没写博客了,主要还是破事太多,实在无暇顾及到技术博客,刚刚下班回到家,趁着媳妇做饭的功夫;赶快水一篇博文,本篇博文来记录一下 vue.js 的混入(mixin)到底能做什么是!

Snipaste_2021-11-29_20-44-03.png

一句话总结

其实 mixin 一句话就能讲明白:就是全局“提前”写好一些东西,可以是函数可以是变量也可以是配置项,写完了所有页面都能用,当然这里很显然说的是工程化开发模式。

举个例子

其实上面那句话如果没项目经验或许你还是不能理解,那么我就直接举一个实际的例子来说明:比如我最近在做一个网盘项目,这个网盘项目在大多数地方都会用到一些函数,比如:格式化时间,格式化文件大小;当然实际的解决方案也有很多,如下:

最笨的办法

在每一个需要的地方复制一份所需的函数,能解决问题,但是最笨的办法。懂得都懂!

页面1

<template>
    <section class="example1">
        创建时间:{{ formatTime(ajaxResult.create_time) }}
    </section>
</template>

<script>
// 这个格式化时间使用的是moment
import moment from "moment";

export default {
    name: "Example1",
    data() {
        return {
            // 假装这里是接口返回的数据
            ajaxResult: {
                create_time: new Date().getTime()
            }
        }
    },
    methods: {
        /**
         * 格式化时间
         * @param time 时间戳
         * @param format 格式化的格式
         */
        formatTime(time, format = "YYYY年MM月DD日 HH:mm:ss") {
            return moment(time).format(format);
        }
    }
}
</script>

<style scoped>

</style>

页面2:实现同样的功能,你需要机械式的复制一份,能实现功能,但是很笨!*

<template>
    <section class="example2">
        创建时间:{{ formatTime(ajaxResult.create_time) }}
    </section>
</template>

<script>
// 这个格式化时间使用的是moment
import moment from "moment";

export default {
    name: "Example2",
    data() {
        return {
            // 假装这里是接口返回的数据
            ajaxResult: {
                create_time: new Date().getTime()
            }
        }
    },
    methods: {
        /**
         * 格式化时间
         * @param time 时间戳
         * @param format 格式化的格式
         */
        formatTime(time, format = "YYYY年MM月DD日 HH:mm:ss") {
            return moment(time).format(format);
        }
    }
}
</script>

<style scoped>

</style>

写一个工具类

或者自行封装一个工具类或者函数,硬注入到 this 里面去(也就是Vue.js根),然后在实际的使用的时候使用 this.函数名 调用;此方式算是比较常见的一个解决方案,肯定比最笨的办法要好,但缺点也很明显,那就是等于只是缩短的代码,用一个“替代的函数”简化了“一开始的多行”操作;你总是得写一行调用的代码的!

在 main.js 或者类似地方注入函数

import Vue from "vue";
import App from "./App"
import moment from "moment";

/**
 * 当然!你也可以写一个全局的方法,硬挂载到this上
 * 算是比较常规的解决方案,但不是最优解
 */
Vue.prototype.formatTime = (time, format = "YYYY年MM月DD日 HH:mm:ss") => {
    return moment(time).format(format);
}

new Vue({
    render: h => h(App)
}).$mount('#app')

然后你就可以世界在页面里面直接使用了!,这个方法看似无懈可击,但实际上是把你自己把自己限死了,因为你这样全局硬注入方法,等于把自己限制在 methods 里面,但实际场景中,你可能在各种乱七八糟的东西都要注入,很显然把自己限制在 methods 是不明智的!

<template>
    <section class="example">
        创建时间:{{ formatTime(ajaxResult.create_time) }}
    </section>
</template>

<script>
export default {
    name: "Example",
    data() {
        return {
            // 假装这里是接口返回的数据
            ajaxResult: {
                create_time: new Date().getTime()
            }
        }
    }
}
</script>

<style scoped>

</style>

用混入

在这个场景中,最好的办法就是混入,你可以直接使用混入来给所有页面(组件)提前注入好这个方法,虽然可能你在肉眼可见的范围内似乎跟上面写一个工具类没有太大的区别;但是实际上在真实的项目中,在这样或者类似的场景里,混入一定是最优解(比如非常场景的需求:使用moment.js来格式化格式化传给你的时间)

import Vue from "vue";
import App from "./App"
import moment from "moment";

// 用混入!更高的自由度!
Vue.mixin({
    created() {
        console.log("你可以完全就像写一个普通的页面一样,写混入!比如这个函数,在每个页面都会触发!")
    },
    mounted() {
        console.log("同理!这个也会触发!")
    },
    methods: {
        /**
         * 格式化时间
         * @param time 时间戳
         * @param format 格式化的格式
         */
        formatTime(time, format = "YYYY年MM月DD日 HH:mm:ss") {
            return moment(time).format(format);
        }
    }
})

new Vue({
    render: h => h(App)
}).$mount('#app')

你可以看到,如果你用混入,就完全自由了,你并没有把自己硬限制在 methods,你完全可以像写一个正常的页面一样,写注入!是不是比想象的简单多了?