混入mixin - 逻辑混入

217 阅读3分钟

什么是mixinn

卡达烬.jpg 混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。——Vue2

我们都知道.vue文件一般由三部分组成,HTML模板、JavaScript所在的Script标签,以及存放样式的style标签,简单的理解就是等同于.vue文件中的<script>标签中的内容,它能够实现继承拓展等等,并且不会被替代

来自Vue2文档的一个简单例子,简单体会一下mixin的可复用思想以及简单用法

// 定义一个混入对象
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!"

mixin的作用:

抽离公共逻辑

逻辑相同,模板(.Vue文件)样式不同,可共用一个mixin,抽离出相同逻辑,可供不同的组件使用,减少重复代码

简单的Mixin执行

//在主Vue文件中
<template>
  <div class="hello">
    <h2>{{ msg }}</h2>
  </div>
</template>

<script>
  import demoMixin from './mixin/demoMixin'

  export default {
    name: 'HelloWorld2',
    mixins: [demoMixin],
  data () {
    return {
      msg: '我显示的是主mixin',
    }
  },
  created() {
    console.log('我叫mixin,我来了!')
  }
  }
</script>
// demoMixin.js
export default {
  data() {
    return {
      hero: "i'm 吕布",
      weapon: {
        name: '方天画戟',
        type: '长矛'
      }
    }
  },
  created() {
    console.log('大丈夫生居天地间,岂能郁郁久居人下!')
  }
}

这个时候控制台会打印:

以及页面会展示

合并策略

由上打印的数据以及展示的内容,可以看到,页面显示的msg还是Vue文件中script标签中的内容,打印的数据是包含Vue文件JS代码,也包含mixin代码,也就是,重复命名的变量,会和Vue文件中script标签中的data、methods等等进行合并;但是mixin中方法还是会执行。

变量补充形式

和Vue文件中Script标签中的JS代码是从属关系,Mixin是作为主逻辑的额外补充存在的,而且主次Mixin之间不会因为重名而覆盖本来的变量

生命周期

同上,有打印数据可知,就是Vue文件中的代码先执行, mixin之后执行

加载顺序

同样被引用的两个mixin ,会根据数组里面的引用顺序去按顺序加载,Vue中的mixin option是以一个数组的形式存在的,按照数组顺序前面的先加载先执行,后面的后加载后执行;

<script>
import demoMixin from './mixin/demoMixin'
import demoMixin2 from './mixin/demoMixin2'

export default {
  name: 'HelloWorld2',
  mixins: [demoMixin, demoMixin2],
  data () {
    return {
      msg: '我显示的是主mixin',
    }
  },
  created() {
    console.log('我叫mixin,我来了!')
  }
}
</script>
// demoMixin.js
export default {
  data() {
    return {
      hero: "i'm 吕布",
      weapon: {
        name: '方天画戟',
        type: '长矛'
      }
    }
  },
  created() {
    console.log('大丈夫生居天地间,岂能郁郁久居人下!')
  }
}
// demoMixin2.js
export default {
    data() {
        return {
            hero: "i'm 吕奉先",
            weapon: {
                name: '方天画戟',
                type: '长矛'
            }
        }
    },
    created() {
        console.log('我今生不能以汝为妻,非英雄也!')
    }
}

继承拓展extends - 逻辑上共同拓展

extends的底层核心就是Class类的一个继承,一个extends就是在新建实例的时候新建了一个共同的父亲;

使用方法:extends就不再写在mixin里面了,而是写在了extends里面,执行的时候是先执行extends,

mixin可以有多个,但是extends只能有一个,只能做到单继承,父亲类只能有一个,是单继承,不能像吕布一样,三姓家奴;如果有多个,请使用混入;

  1. 应用:核心逻辑的功能继承
  2. 合并策略
    1. 不会覆盖无论是父子mixin还是 主次mixin,方法都会依次执行(),
    2. 生命周期 => 不论是业务代码还是mixin都在extends之后 => 继承
<script>
import demoMixin from './mixin/demoMixin'
import demoMixin2 from './mixin/demoMixin2'
import demoExtends from './mixin/demoExtends'


export default {
  name: 'HelloWorld2',
  mixins: [demoMixin, demoMixin2],
  extends: demoExtends,
  data () {
    return {
      msg: '我显示的是主mixin',
    }
  },
  created() {
    console.log('我叫mixin,我来了!')
  }
}
</script>
// demoExtends.js
export default {
    data() {
        return {
            hero: "i'm 董卓",
            weapon: {
                name: '七星宝刀',
                type: '差点被七星宝刀干嗝屁'
            }
        }
    },
    created() {
        console.log('吾儿奉先何在!')
    }
}

Vue3删除了mixin

Vue3:因为是Composition API,是使用了函数式的,不再有methods等等,直接当成JavaScript去写,不再写mixin,直接写JS文件,导出函数就好了。真香啊