详解Vue的mixin策略


Posted in Vue.js onNovember 19, 2020

我之前一直以为mixin的合并是以组件内的优先,即mixin的内容如果和组件内有冲突的,以组件内为准,确实存在这种情况,但是vue指定的策略更详细,下面分别记录各种情况对应的合并策略

基本

当一个组件使用mixin的时候,所有mixin的选项会被混入到组件自己的选项中, 这部分没什么好说的,直接看代码

// define a mixin object
const myMixin = {
 created() {
  this.hello()
 },
 methods: {
  hello() {
   console.log('hello from mixin!')
  }
 }
}

// define an app that uses this mixin
const app = Vue.createApp({
 mixins: [myMixin]
})

app.mount('#mixins-basic') // => "hello from mixin!"

选项的合并策略

这里的选项指的就是 data methods和生命周期钩子函数这些选项,他们的会采取不同的合并策略

像data,methods,components,directives这样的会被合并进同一个对象中,并且遇到冲突项以组件的为准

const myMixin = {
 data() {
  return {
   message: 'hello',
   foo: 'abc'
  }
 }
}

const app = Vue.createApp({
 mixins: [myMixin],
 data() {
  return {
   message: 'goodbye',
   bar: 'def'
  }
 },
 created() {
  console.log(this.$data) // => { message: "goodbye", foo: "abc", bar: "def" }
 }
})
const myMixin = {
 methods: {
  foo() {
   console.log('foo')
  },
  conflicting() {
   console.log('from mixin')
  }
 }
}

const app = Vue.createApp({
 mixins: [myMixin],
 methods: {
  bar() {
   console.log('bar')
  },
  conflicting() {
   console.log('from self')
  }
 }
})

const vm = app.mount('#mixins-basic')

vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"

而对于钩子函数就不是简单的替换了,如果有同名的,他们会被一起合并进数组中,然后依次调用,且mixin的钩子函数会率先被调用

const myMixin = {
 created() {
  console.log('mixin hook called')
 }
}

const app = Vue.createApp({
 mixins: [myMixin],
 created() {
  console.log('component hook called')
 }
})

// => "mixin hook called"
// => "component hook called"

全局混入和自定义选项

const app = Vue.createApp({
 myOption: 'hello!'
})

// inject a handler for `myOption` custom option
app.mixin({
 created() {
  const myOption = this.$options.myOption
  if (myOption) {
   console.log(myOption)
  }
 }
})

app.mount('#mixins-global') // => "hello!"

上述代码,我们在全局创建了一个自定义选项,然后进行了全局混入处理,但是需要注意的是,这会影响到这个app所有的子组件:

const app = Vue.createApp({
 myOption: 'hello!'
})

// inject a handler for `myOption` custom option
app.mixin({
 created() {
  const myOption = this.$options.myOption
  if (myOption) {
   console.log(myOption)
  }
 }
})

// add myOption also to child component
app.component('test-component', {
 myOption: 'hello from component!'
})

app.mount('#mixins-global')

// => "hello!"
// => "hello from component!"

我们可以看到,对于自定义选项这不是简单的替换,而是分别调用,当然我们也可以制定我们自己的合并策略:

const app = Vue.createApp({})

app.config.optionMergeStrategies.customOption = (toVal, fromVal) => {
 // return mergedVal
}

合并策略接收两个参数,分别是指定项在父实例和子实例的值,当使用mixin的时候我们可以查看打印什么:

const app = Vue.createApp({
 custom: 'hello!'
})

app.config.optionMergeStrategies.custom = (toVal, fromVal) => {
 console.log(fromVal, toVal)
 // => "goodbye!", undefined
 // => "hello", "goodbye!"
 return fromVal || toVal
}

app.mixin({
 custom: 'goodbye!',
 created() {
  console.log(this.$options.custom) // => "hello!"
 }
})

可以看到第一次从mixin打印,然后从app打印。

注意事项

  • mixin很容易造成冲突,你得确保不会有冲突的属性名,来避免冲突,这会造成额外的负担
  • 复用性有限,因为mixin不能接受参数,所以逻辑是写定的,不灵活

所以官方推荐使用 Composition Api来组织逻辑

以上就是详解Vue的mixin策略的详细内容,更多关于Vue的mixin策略的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
vue使用vant中的checkbox实现全选功能
Nov 17 Vue.js
vue+element UI实现树形表格
Dec 29 Vue.js
如何在VUE中使用vue-awesome-swiper
Jan 04 Vue.js
vue watch监控对象的简单方法示例
Jan 07 Vue.js
vue-resource 拦截器interceptors使用详解
Jan 18 Vue.js
vue.js实现点击图标放大离开时缩小的代码
Jan 27 Vue.js
vue使用节流函数的踩坑实例指南
May 20 Vue.js
HTML+VUE分页实现炫酷物联网大屏功能
May 27 Vue.js
vue响应式原理与双向数据的深入解析
Jun 04 Vue.js
vue 实现弹窗关闭后刷新效果
Apr 08 Vue.js
使用vue判断当前环境是安卓还是IOS
Apr 12 Vue.js
vue3不同环境下实现配置代理
May 25 Vue.js
一篇超完整的Vue新手入门指导教程
Nov 18 #Vue.js
vue3.0实现点击切换验证码(组件)及校验
Nov 18 #Vue.js
在Vue中使用Echarts可视化库的完整步骤记录
Nov 18 #Vue.js
详解vue实现坐标拾取器功能示例
Nov 18 #Vue.js
Vue如何循环提取对象数组中的值
Nov 18 #Vue.js
vue在图片上传的时候压缩图片
Nov 18 #Vue.js
Vue +WebSocket + WaveSurferJS 实现H5聊天对话交互的实例
Nov 18 #Vue.js
You might like
日本十大科幻动漫 宇宙骑士垫底,第一已成经典
2020/03/04 日漫
图解上海144收音机
2021/03/02 无线电
PHP PDO数据库操作预处理与注意事项
2019/03/16 PHP
PHP的静态方法与普通方法用法实例分析
2019/09/26 PHP
Javascript的严格模式strict mode详细介绍
2014/06/06 Javascript
分享28款免费实用的 JQuery 图片和内容滑块插件
2014/12/15 Javascript
把Node.js程序加入服务实现随机启动
2015/06/25 Javascript
jquery实现的V字形显示效果代码
2015/10/27 Javascript
Extjs实现下拉菜单效果
2016/04/01 Javascript
vue插件tab选项卡使用小结
2016/10/27 Javascript
JS利用cookies设置每隔24小时弹出框
2017/04/20 Javascript
angular之ng-template模板加载
2017/11/09 Javascript
vue打开新窗口并实现传参的图文实例
2021/03/04 Vue.js
Python with的用法
2014/08/22 Python
Python入门篇之文件
2014/10/20 Python
Python过滤列表用法实例分析
2016/04/29 Python
python数字图像处理之高级形态学处理
2018/04/27 Python
python中从str中提取元素到list以及将list转换为str的方法
2018/06/26 Python
python 保存float类型的小数的位数方法
2018/10/17 Python
python之消除前缀重命名的方法
2018/10/21 Python
Python基础之函数基本用法与进阶详解
2020/01/02 Python
python构造IP报文实例
2020/05/05 Python
提高python代码运行效率的一些建议
2020/09/29 Python
五种Python转义表示法
2020/11/27 Python
Pandas的数据过滤实现
2021/01/15 Python
html5+CSS3+JS实现七夕言情功能代码
2017/08/28 HTML / CSS
解决HTML5中滚动到底部的事件问题
2019/08/22 HTML / CSS
斯洛伐克时尚服装网上商店:Cellbes
2016/10/20 全球购物
英国电视和家用电器购物网站:rlrdistribution.co.uk
2018/11/20 全球购物
C语言笔试题回忆
2015/04/02 面试题
运动会口号8字
2014/06/07 职场文书
2014年个人年终总结
2015/03/09 职场文书
致短跑运动员加油稿
2015/07/21 职场文书
2016年师德师风学习心得体会
2016/01/12 职场文书
一文搞懂Python Sklearn库使用
2021/08/23 Python
nginx七层负载均衡配置详解
2022/07/15 Servers