• vue中mixins的理解及应用


    vue中提供了一种混合机制--mixins,用来更高效的实现组件内容的复用。最开始我一度认为这个和组件好像没啥区别。。后来发现错了。下面我们来看看mixins和普通情况下引入组件有什么区别?

    mixins

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

    mixins理解

    组件在引用之后相当于在父组件内开辟了一块单独的空间,来根据父组件props过来的值进行相应的操作,单本质上两者还是泾渭分明,相对独立。

    而mixins则是在引入组件之后,则是将组件内部的内容如data等方法、method等属性与父组件相应内容进行合并。相当于在引入后,父组件的各种属性方法都被扩充了。

    • 单纯组件引用:
      父组件 + 子组件 >>> 父组件 + 子组件
    • mixins:
      父组件 + 子组件 >>> new父组件
      有点像注册了一个vue的公共方法,可以绑定在多个组件或者多个Vue对象实例中使用。另一点,类似于在原型对象中注册方法,实例对象即组件或者Vue实例对象中,仍然可以定义相同函数名的方法进行覆盖,有点像子类和父类的感觉。

    mixins的使用

    方法的复用

    html

    <div id="app">
        <child></child>
        <kid></kid>
    </div>

    js

    Vue.component('child',{
        template:`<h1 @click="foo">child component</h1>`,
        methods:{
            foo(){
                console.log('Child foo()'+this.msg++)
            }
        }
    })
     
    Vue.component('kid',{
        template:`<h1 @click="foo">kid component</h1>`,
        methods:{
            foo(){
                console.log('Kid foo()'+this.msg++)
            }
        }
    })

    在借助mixins之前,在两个不同的组件的组件中调用foo方法,需要重复定义,倘若方法比较复杂,代码将更加冗余。若借助mixins,则变得十分简单:

    let mixin={
        data(){
            return{
                msg:1
            }
        },
        methods:{
            foo(){
                console.log('hello from mixin!----'+this.msg++)
            }
        }
    }
    var child=Vue.component('child',{ 
            template:`<h1 @click="foo">child component</h1>`, 
            mixins:[mixin]
    })
    Vue.component('kid',{ 
            template:`<h1 @click="foo">kid component</h1>`, 
            mixins:[mixin]
    })

    虽然此处,两个组件用可以通过this.msg引用mixins中定义的msg,但是,小编尝试过,两个组件引用的并不是同一个msg,而是各自创建了一个新的msg。如果在组件中定义相同的data,则此处会引用组件中的msg,而非mixins中的。

    方法的覆盖

    如果在引用mixins的同时,在组件中重复定义相同的方法,则mixins中的方法会被覆盖。

    var child=Vue.component('child',{
        template:`<h1 @click="foo">child component</h1>`,
        mixins:[mixin],
        methods:{
            foo(){
                console.log('Child foo()'+this.msg++)
            }
        }
    })

    此时,若单击h1标签,则在控制台中打印"Child foo() 1" 3、合并生命周期此时,若单击h1标签,则在控制台中打印"Child foo() 1"

    合并生命周期

    let mixin={
        mounted(){
            console.log('mixin say hi')//先输出
        },
        data(){
            return{
                msg:1
            }
        },
        methods:{
            foo(){
                console.log('mixin foo()'+this.msg++)
            }
        }
    }
    let vm=new Vue({
        el:"#app",
        data:{
            msg: 2
        },
        mounted: function(){
            console.log('app say hi')//后输出
        },
        methods:{
            foo(){
                console.log('Parent foo()'+this.msg)
            }
        }
    })

    通过上面的介绍,现在对mixins有了比较深入的了解,在设计复杂组件时是很有必要的。

    实践:状态码统一过滤

    一般情况下不要全局使用,因为会污染vue所有实例,这里通过一个简单的应用展示mixin的使用技巧,在所有vue实例中添加统一状态码过滤器。

    因为自定义方法会在所有的实例中混入,如果按照以前的方法,难免会有覆盖原先的方法的危险,按照官方的建议,混入的自定义方法名增加前缀 $_ 用作区分。

    创建一个 config.js 文件,用于保存状态码对应的含义,将其暴露出去


    export const typeConfig = {
      1: "type one",
      2: "type two",
      3: "type three"
    }

    再创建一个 filters.js 文件,用于保存所有的自定义函数

    import { typeConfig } from "./config"
    export default {
      filters: {
        $_filterType: (value) => {
          return typeConfig[value] || "type undefined"
        }
      }
    }

    最后,在 main.js 中引入我们的 filters 方法集

    import filter from "./filters"
    Vue.mixin(filter)

    接下来,我们就可以在 .vue 的模板文件中随意使用自定义函数了

    <template>
      <div>{{typeStatus | $_filterType}}<div>
    </template>

    包装插件

    接下来简单应用一下 Vue 中插件的制作方法。创建插件之后,就可以 Vue.use(myPlugin) 来使用了。

    首先附上插件的 官方文档[点我查看]

    一句话解释,包装的插件需要一个 install 的方法将插件装载到 Vue 上。

    关于 Vue.use() 的源码

    function initUse (Vue) {
      Vue.use = function (plugin) {
        var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
        if (installedPlugins.indexOf(plugin) > -1) {
          return this
        }
    
        // additional parameters
        var args = toArray(arguments, 1);
        args.unshift(this);
        if (typeof plugin.install === 'function') {
          plugin.install.apply(plugin, args);
        } else if (typeof plugin === 'function') {
          plugin.apply(null, args);
        }
        installedPlugins.push(plugin);
        return this
      };
    }

    很直观的就看到他在最后调用了 plugin.install 的方法,我们要做的就是处理好这个 install 函数即可。

    config.js 文件依旧需要,这里保存了所有状态码对应的转义文字

    创建一个 myPlugin.js 文件,这个就是我们编写的插件

    import { typeConfig } from "./config"
    
    myPlugin.install = (Vue) => {
      Vue.mixin({
        filters: {
          $_filterType: (value) => {
            return typeConfig[value] || "type undefined"
          }
        }
      })
    }
    export default myPlugin

    插件的 install 函数的第一个参数为 Vue 的实例,后面还可以传入一些自定义参数。

    在 main.js 文件中,我们不用 Vue.mixin() 转而使用 Vue.use() 来完成插件的装载。

    import myPlugin from "./myPlugin"
    Vue.use(myPlugin)

    至此,我们已经完成了一个小小的插件,并将我们的状态码转义过滤器放入了所有的 Vue 实例中,在 .vue 的模板文件中,我们可以使用 {{ typeStatus | $_filterType }} 来进行状态码转义了。

    Vue.mixin() 可以将自定义的方法混入所有的 Vue 实例中,谨慎使用。


    转载链接:https://www.jianshu.com/p/a72bf060eeaa
  • 相关阅读:
    Python基础之迭代器、生成器
    Python基础之模块+异常
    Python基础之面向对象思维解决游戏《天龙八部》
    Oracle创建存储过程
    数据库范式
    Oracle条件判断
    Oracle的三种循环
    Oracle的pl/sql变量类型
    oracle如何实现去重和分页
    相关子查询和非相关子查询
  • 原文地址:https://www.cnblogs.com/lst619247/p/13323837.html
Copyright © 2020-2023  润新知