vue2之混入(mixin)


mixin的概念

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

简单描述:提取公共逻辑,降低组件代码冗余程度,哪个组件需要用到mixin的逻辑,就单独去引入对应的mixin文件即可

注意:mixin是一个对象


定义一个mixin

我的项目是v2-advanced-usage

// src目录下创建一个mixins文件夹并新增一个js文件
// 路径:v2-advanced-usage/src/mixins/getNameMixin.js
// 定义一个名为getNameMixin混入对象
export const getNameMixin = {
  components: {},
  data() {
    return {
     message: 'this is getNameMixin msg',
     foo: 'abc'
    };
  },
};
  1. mixin(混入)有Vue完整的生命周期和数据状态
  2. 可以在mixin的js文件中定义公共的数据、公共的方法、钩子函数等

使用mixin

<!--在App.vue文件中引入mixin-->
<!--此时页面显示的信息是getNameMixin中的数据:this is getNameMixin msg-->
<template>
  <div id="app">
    <h4>
      <span>This data comes from getNameMixin file:</span>
      <span style="color: blueviolet">{{ message }}</span>
    </h4>
  </div>
</template>

<script>
import { getNameMixin } from "./mixins/getNameMixin";
export default {
  name: "App",
  mixins: [getNameMixin],
};
</script>

mixin和组件的优先级

在App.vue中增加自身的methods方法和data状态

// 修改App.vue文件
<template>
  <div id="app">
    <h4>
      <span>This data comes from getNameMixin file:</span>
      <span style="color: blueviolet">{{ name }}</span>
    </h4>
  </div>
</template>

<script>
import { getNameMixin } from "./mixins/getNameMixin";
export default {
  name: "App",
  mixins: [getNameMixin],
  data: function () {
    return {
      message: 'this is component msg',
      bar: 'def'
    }
  },
  created: function () {
    console.log(this.message)
    // => "this is component msg"
  }
};
</script>
/**
 *  此时页面显示的是组件的数据:'this is component msg',而不是mixins里面的'this is getNameMixin msg'
 * 	created钩子函数打印的是组件内的数据"this is component msg"
 */

总结:
1. 当组件和混入(mixin)对象含有同名数据时,这些数据会进行“合并”,并且组件优先级最高,非同名数据会放到一个对象里面

示例1:

// getNameMixin的message被组件内的message覆盖,mixinDemo的foo属性和组件内的bar属性放到一个对象内
// getNameMixin.js内的代码
export const getNameMixin = {
  data() {
    return {
      message: 'this is mixinDemo msg',
      foo: 'abc'
    }
  }
}
// App.vue文件代码
<template>
  <div id="app">
    <h4>
      <span>This data comes from getNameMixin file:</span>
      <span style="color: blueviolet">{{ message }}</span>
    </h4>
  </div>
</template>
<script>
import { getNameMixin } from "./mixins/getNameMixin";
export default {
  name: "App",
  mixins: [getNameMixin],
  data: function () {
    return {
      message: 'this is component msg',
      bar: 'def'
    }
  },
  created: function () {
    console.log(this.$data)
    // => { message: "this is component msg", foo: "abc", bar: "def" }
  }
};
</script>

2. 当组件和混入(mixin)对象含有同名生命周期钩子函数时,这些生命周期钩子函数会“合并”为一个数组,并且混入对象内的函数优先调用,组件自身函数后调用

示例2:

// 同名生命周期钩子函数,优先执行mixinDemo中的钩子函数,后执行组件内的钩子函数
var mixinDemo = {
  created: function () {
    console.log('混入对象的钩子被调用')
  }
}
new Vue({
  mixins: [mixinDemo],
  created: function () {
    console.log('组件钩子被调用')
  }
})
// => 输出:"混入对象的钩子被调用"(优先触发了)
// => 输出:"组件钩子被调用"

3. 组件和混入(mixin)对象中的methods、components 和 directives,将被合并为同一个对象,如果有同名的冲突,以组件自身为准

示例3:

// conflicting为同名的methods函数,mixinDemo内的不再调用,只会触发组件内的conflicting
var mixinDemo = {
  methods: {
    foo: function () {
      console.log('foo')
    },
    conflicting: function () {
      console.log('from mixin')
    }
  }
}
var vm = new Vue({
  mixins: [mixinDemo],
  methods: {
    bar: function () {
      console.log('bar')
    },
    conflicting: function () {
      console.log('from self')
    }
  }
})
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"

mixin也可以通过Vue.mixin的方式混入到全局中,使用时需要格外小心!一旦使用全局混入,它将影响每一个之后创建的 Vue 实例,这是非常危险的行为

mixin的缺点:

  1. 命名冲突,data、生命周期、methods、components、directives等都会出现冲突现象
  2. 依赖不透明,不利于问题溯源,因为mixin 和使用它的组件之间没有层次关系
  3. 全局注册的mixin,会影响到整个实例下的所有组件,在使用过程中,容易出现察觉不到的问题

结论:不建议使用太多的mixin,项目开发时,可以使用函数式编程范式,提取公共函数的方式来处理公共问题,业务逻辑可以抽离独立组件的方式来处理

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骑乌龟跑步的小卡拉米

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值