Vue 之 Mixins (混入)

Mixins

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

何时使用 Mixins
1. 页面的风格不用,可是执行的方法和须要的数据相似,咱们是选择每一个都写呢仍是提取出公共部分呢?

基础实例vue

咱们有一对不一样的组件,它们的做用是切换一个状态布尔值,一个模态框和一个提示框。这些提示框和模态框除了在功能上,没有其余共同点:它们看起来不同,用法不同,可是逻辑同样。
// 模态框
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组件同上

合并vuex

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

1、数据对象内

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" }
  }
})
2、钩子函数

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

var mixin = {
  created: function () {
    console.log('混入对象的钩子被调用')
  }
}

new Vue({
  mixins: [mixin],
  created: function () {
    console.log('组件钩子被调用')
  }
})

// => "混入对象的钩子被调用"
// => "组件钩子被调用"
3、值为对象的选项

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

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"

全局混入函数

全局混合被注册到了每一个单一组件上。所以,它们的使用场景极其有限而且要很是的当心。一个我能想到的用途就是它像一个插件,你须要赋予它访问全部东西的权限。但即便在这种状况下,我也对你正在作的保持警戒,尤为是你在应用中扩展的函数,可能对你来讲是不可知的。this

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

new Vue({
    ...
})

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

一个使用合理的例子
// 为自定义的选项 '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')
    }
  }
}
相关文章
相关标签/搜索