zoukankan      html  css  js  c++  java
  • Vue 之 Mixins (混入)

    Vue 之 Mixins (混入)

    Mixins

    Mixins是一种分发Vue组件中可复用功能的非常灵活的一种方式。

    什么时候使用Mixins

    页面的风格不用,但是执行的方法和需要的数据类似,我们是选择每个都写呢还是提取出公共部分呢?

    基础实例

    我们有一对不同的组件,它们的作用是切换一个状态布尔值,一个模态框和一个提示框。这些提示框和模态框除了在功能上,没有其他共同点:它们看起来不一样,用法不一样,但是逻辑一样。

    // 模态框
    const Modal = {
      template: '#modal',
      data() {
        return {
          isShowing: false
        }
      },
      methods: {
        toggleShow() {
          this.isShowing = !this.isShowing;  
        }
      },
      components: {
        appChild: Child
      }
    }
    
    // 提示框
    const Tooltip = {
      template: '#tooltip',
      data() {
        return {
          isShowing: false
        }
      },
      methods: {
        toggleShow() {
          this.isShowing = !this.isShowing;  
        }
      },
      components: {
        appChild: Child
      }
    }
    

    解决办法如下:

    const toggle = {
        data () {
            isshowing: false
        },
        methods: {
            toggleShow() {
                this.isshowing = !this.isshowing
            }
        }
    }
    
    // 下面即可使用了
    // mixins: [变量名]
    
    const Modal = {
      template: '#modal',
      mixins: [toggle],
      components: {
        appChild: Child
      }
    }
    
    const Tooltip = {
      template: '#tooltip',
      mixins: [toggle],
      components: {
        appChild: Child
      }
    }
    

    选项合并

    当组件和混入对象含有同名选项时,这些选项会以恰当的方式混合。 比如数据对象在内部会进行浅合并(一层属性的深度),在和组件的数据发生冲突时,以组件数据优先。

    var mixin = {
      data() {
        return {
          msg_mixins: 'mixins',
          msg: '123'
        }
      }
    }
    
    var app = new Vue({
      el: '#app',
      mixins: [mixin],
      data: {
        msg: 'app'
      },
      created: function ( ) {
        console.log(this.$data)
        // => { "msg": "app", "msg_mixins": "mixins" }
      }
    })
    

    同名的钩子函数将混合为一个数组,所以都会被调用,另外,混入对象的钩子函数会在组件自身的钩子函数之前先进行调用。

    var mixin = {
      data() {
        return {
          msg_mixins: 'mixins',
          msg: '123'
        }
      },
      created: function ( ) {
        console.log('混入对象的钩子被调用')
      }
    }
    
    var app = new Vue({
      mixins: [mixin],
      el: '#app',
      data: {
        msg: 'app'
      },
      created: function ( ) {
        console.log('组件钩子被调用')
      }
    })
    
    混入对象的钩子被调用
    组件钩子被调用
    vue.js:9058 You are running Vue in development mode.
    Make sure to turn on production mode when deploying for production.
    See more tips at https://vuejs.org/guide/deployment.html
    

    当混合值为对象的选项,例如 methods,components,directive,将被混合为同一个对象,两个对象键名冲突时,取组件的。

    混入对象的钩子被调用
    merge3.html:47 组件钩子被调用
    vue.js:9058 You are running Vue in development mode.
    Make sure to turn on production mode when deploying for production.
    See more tips at https://vuejs.org/guide/deployment.html
    app.foo
    ƒ () {
              console.log('foo')
            }
    app.foo
    ƒ () {
              console.log('foo')
            }
    app.conflicting
    ƒ () {
              console.log('from self')
            }
    

    注意:Vue.extend() (扩展)也使用同样的策略进行合并。

    全局混入

    我们也可以进行全局注册混入对象,注意使用。一旦使用全局混入对象,将会影响所有你创建的 vue 实例,如果使用恰当可以对自定义的对象注入逻辑。比如全局的判断等,会方便一些,不需要每个页面判断,直接取值就行了。

    Vue.mixin({
      created: function ( ) {
          console.log('全局混入')
      }
    })
    
    var mixin = {
      data() {
        return {
          msg_mixins: 'mixins',
          msg: '123'
        }
      },
      created: function ( ) {
        console.log('混入对象的钩子被调用')
      },
      methods: {
        foo: function ( ) {
          console.log('foo')
        },
        conflicting: function ( ) {
          console.log('from mixin')
        }
      }
    }
    
    var app = new Vue({
      mixins: [mixin],
      el: '#app',
      data: {
        msg: 'app'
      },
      created: function ( ) {
        console.log('组件钩子被调用')
      },
      methods: {
        bar: function ( ) {
          console.log('bar')
        },
        conflicting: function ( ) {
          console.log('from self')
        }
      }
    })
    
    全局混入
    mixin.html:34 混入对象的钩子被调用
    mixin.html:53 组件钩子被调用
    vue.js:9058 You are running Vue in development mode.
    Make sure to turn on production mode when deploying for production.
    See more tips at https://vuejs.org/guide/deployment.html
    

    谨慎使用全局混入对象,因为会影响到每个单独创建的 Vue 实例 (包括第三方模板)。大多数情况下,只应当应用于自定义选项。也可以将其用作 Plugins 以避免产生重复应用。

    自定义选项合并策略

    自定义选项使用默认策略,就是简单的覆盖默认值。如果想让自定义选项以自定义的逻辑合并, 可以向 Vue.config.optionMergeStrategies 添加一个函数:

    Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
      // 返回合并后的值
    }
    

    也就是说,本来的选项的合并方式是默认的,但是我们可以通过修改添加一个函数,来修改合并的方式逻辑。

    对于大多数的合并策略来说,可以使用 methods:

    var strategies = Vue.config.optionMergeStrategies
    strategies.myOption = strategies.methods
    

    可以在 Vuex 1.x 的混入策略里找到一个更高级的例子:

    const merge = Vue.config.optionMergeStrategies.computed
    Vue.config.optionMergeStrategies.vuex = function (toVal, fromVal) {
      if (!toVal) return fromVal
      if (!fromVal) return toVal
      return {
        getters: merge(toVal.getters, fromVal.getters),
        state: merge(toVal.state, fromVal.state),
        actions: merge(toVal.actions, fromVal.actions)
      }
    }
  • 相关阅读:
    完全背包笔记
    渗透测试之信息收集常用网站
    结对项目-四则运算"软件"之升级版
    第三次作业:个人项目-小学四则运算“软件”之初版
    分布式版本控制系统Git的安装与使用
    第一次作业:准备
    爬虫综合大作业
    爬取全部校园新闻
    理解爬虫原理
    中文词频统计与词云生成
  • 原文地址:https://www.cnblogs.com/xuzhenlei/p/12410732.html
Copyright © 2011-2022 走看看