Vue Mixin

449 阅读2分钟

mixins定义

官方描述:一种分发Vue组件中可复用功能的方式,mixins是一个js对象,可以包含组件中script项中任意功能选项,如data、components、methods、created、computed等等。

一句话概括:将共用的功能以对象的方式传入mixins选项中

使用场景

存在多个组件中的数据或功能相近时,可以利用mixins将公共部分提取出来,通过mixins封装的函数,组件调用他们是不会改变函数作用域外部的。

如何创建Mixins

在src中创建mixins文件夹,并在其下创建myMixins.js

export const myMixins = {
   data(){},
   created(){},
   mounted(){},
   computed:{},
   methods:{}
}

如何使用Mixins

在需要调用的组件中引入myMixins.js文件,然后在export default 中引入需要的对象即可

<script>
   import {myMixins} from '@/mixins/myMixins.js'
   export default {
     mixins:[myMixins]
   }
</script>

例子

// 定义一个混入对象
var myMixin = {
  created: function () {
    this.hello()
  },
  methods: {
    hello: function () {
      console.log('hello from mixin!')
    }
  }
}

// 定义一个使用混入对象的组件
var Component = Vue.extend({
  mixins: [myMixin]
})

var component = new Component() // => "hello from mixin!"

Mixins的特点

  • 第一种:方法和参数在各组件中不共享,其属性只会被当前组件所识别并不会被共享,其他组件无法从当前组件中获取到mixins中的数据和方法。

  • Mixins合并冲突

引入mixins后组件会对其进行合并,将mixins中的数据和方法扩展到当前组件中来,在合并过程中会出现冲突。

数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先,组件中的健会覆盖混入对象的。

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" }
  }
})
  • 如果mixin里面有一个created,自己的组件里也有一个created,代码执行的是先执行mixin里的再执行自己组件的created。相同逻辑时,会覆盖掉mixin中的。 (同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。)

值为函数(created\mounted)的选项,混入组件时选项会被合并调用,混合对象里的钩子函数在组件里的钩子函数之前调用

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

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

// => "混入对象的钩子被调用"
// => "组件钩子被调用"
  • 值为对象的选项,例如 methods、components 和 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"

对于混入组件和主组件中的相关冲突

  • 对于方法来说,主组件中的方法会覆盖掉混入组件的方法(名字相同时)

  • 对于生命周期相同时,会将其合并在一个里面,对应周期里的名字相同时,也会被覆盖

  • 混合对象里的钩子函数在主组件里的钩子函数之前调用;

  • 钩子函数相同时,混入对象函数中的console会在主组件里的钩子函数之前调用;

Mixins与vuex的区别

  • vuex:用来做状态管理的,里面定义的变量在每个组件中均可以使用和修改,在任一组件中修改此变量的值之后其他组件中此变量的值也会随之修改。

  • Mixins:可以定义共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的值的修改在组件中不会相互影响

mixins的实践应用

状态码统一过滤:

  • 创建一个 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>