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

    Mixins

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

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

    基础实例

    我们有一对不同的组件,它们的作用是切换一个状态布尔值,一个模态框和一个提示框。这些提示框和模态框除了在功能上,没有其他共同点:它们看起来不一样,用法不一样,但是逻辑一样。
    // 模态框
    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
      }
    };
    
    如果你是以vue-cli创建的项目来写,可以这样
    // mixin.js
    
    export const toggle = {
        data () {
            isshowing: false
        },
        methods: {
            toggleShow() {
                this.isshowing = !this.isshowing
            }
        }
    }
    // modal.vue
    // 将mixin引入该组件,就可以直接使用 toggleShow() 了
    import {mixin} from '../mixin.js'
    
    export default {
        mixins: [mixin],
        mounted () {
            
        }
    }
    // tooltip组件同上

    合并

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

    一、数据对象内

    mixin的数据对象和组件的数据发生冲突时以组件数据优先。

    var mixin = {
      data: function () {
        return {
          message: 'hello',
          foo: 'abc'
        }
      }
    }
    
    new Vue({
      mixins: [mixin],
      data: function () {
        return {
          message: 'goodbye',
          bar: 'def'
        }
      },
      created: function () {
        console.log(this.$data)
        // => { message: "goodbye", foo: "abc", bar: "def" }
      }
    })
    二、钩子函数

    同名钩子函数将会混合为一个数组,都将被调用到,但是混入对象的钩子将在组件自身钩子之前调用。

    var mixin = {
      created: function () {
        console.log('混入对象的钩子被调用')
      }
    }
    
    new Vue({
      mixins: [mixin],
      created: function () {
        console.log('组件钩子被调用')
      }
    })
    
    // => "混入对象的钩子被调用"
    // => "组件钩子被调用"
    三、值为对象的选项

    值为对象的选项,例如 methodscomponents 和 directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。

    var mixin = {
      methods: {
        foo: function () {
          console.log('foo')
        },
        conflicting: function () {
          console.log('from mixin')
        }
      }
    }
    
    var vm = new Vue({
      mixins: [mixin],
      methods: {
        bar: function () {
          console.log('bar')
        },
        conflicting: function () {
          console.log('from self')
        }
      }
    })
    
    vm.foo() // => "foo"
    vm.bar() // => "bar"
    vm.conflicting() // => "from self"

    全局混入

    全局混合被注册到了每个单一组件上。因此,它们的使用场景极其有限并且要非常的小心。一个我能想到的用途就是它像一个插件,你需要赋予它访问所有东西的权限。但即使在这种情况下,我也对你正在做的保持警惕,尤其是你在应用中扩展的函数,可能对你来说是不可知的。

    Vue.mixin({
        mounted() {
            console.log("我是mixin");
        }
    })
    
    new Vue({
        ...
    })

    再次提醒,小心使用它!那个 console.log将会出现在每个组件上。这种情况还不算坏(除了控制台上有多余的输出),但如果它被错误的使用,你将能看到它会多么的有害。

    一个使用合理的例子
    // 为自定义的选项 'myOption' 注入一个处理器。
    Vue.mixin({
      created: function () {
        var myOption = this.$options.myOption
        if (myOption) {
          console.log(myOption)
        }
      }
    })
    
    new Vue({
      myOption: 'hello!'
    })
    // => "hello!"

    总结

    混合对于封装一小段想要复用的代码来讲是有用的。对你来说它们当然不是唯一可行的。混合很好,它不需要传递状态,但是这种模式当然也可能会被滥用。所以我们还是需要仔细斟酌使用喽!!

    例子

     
    import {mapGetters} from 'vuex'
    
    // 目的是想要处理 scroll 的bottom值,在含有playlist列表的情况下
    export const playlistMixin = {
      computed: {
        ...mapGetters([
          'playList'
        ])
      },
      mounted() {
        this.handlePlaylist(this.playList)
      },
      activated() {
        this.handlePlaylist(this.playList)
      },
      watch: {
        playlist(newVal) {
          this.handlePlaylist(newVal)
        }
      },
      methods: {
        // 如果组件中没有这个方法,那么就报错
        handlePlaylist() {
          throw new Error('component must implement handlePlaylist method')
        }
      }
    }
  • 相关阅读:
    灰哥的二叉树
    BZOJ1029: [JSOI2007]建筑抢修[模拟 贪心 优先队列]
    POJ1155TELE[树形背包]
    HDU4003Find Metal Mineral[树形DP 分组背包]
    POJ1837 Balance[分组背包]
    HDU2639Bone Collector II[01背包第k优值]
    POJ3666Making the Grade[DP 离散化 LIS相关]
    HDU2955 Robberies[01背包]
    HDU2191悼念512汶川大地震遇难同胞——珍惜现在,感恩生活[多重背包]
    POJ1014Dividing[多重背包可行性]
  • 原文地址:https://www.cnblogs.com/atomgame/p/12496327.html
Copyright © 2011-2022 走看看