详解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中使用Echarts可视化库的完整步骤记录
Nov 18 Vue.js
element-plus一个vue3.xUI框架(element-ui的3.x 版初体验)
Dec 02 Vue.js
Vue与React的区别和优势对比
Dec 18 Vue.js
vue中父子组件的参数传递和应用示例
Jan 04 Vue.js
vue3.0中友好使用antdv示例详解
Jan 05 Vue.js
vue二选一tab栏切换新做法实现
Jan 19 Vue.js
Vue2.x-使用防抖以及节流的示例
Mar 02 Vue.js
详解Vue.js 可拖放文本框组件的使用
Mar 03 Vue.js
vue 中 get / delete 传递数组参数方法
Mar 23 Vue.js
VUE中的v-if与v-show区别介绍
Mar 13 Vue.js
vue3语法糖内的defineProps及defineEmits
Apr 14 Vue.js
Vue Element plus使用方法梳理
Dec 24 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
PHP 中 Orientation 属性判断上传图片是否需要旋转
2015/10/16 PHP
thinkPHP5.0框架引入Traits功能实例分析
2017/03/18 PHP
javascript两段代码,两个小技巧
2010/02/04 Javascript
给超链接添加特效鼠标移动展示提示信息且随鼠标移动
2013/10/17 Javascript
js中的onchange和onpropertychange (onchange无效的解决方法)
2014/03/08 Javascript
用javascript将数据导入Excel示例代码
2014/09/10 Javascript
Javascript冒泡排序算法详解
2014/12/03 Javascript
javascript框架设计之类工厂
2015/06/23 Javascript
基于jQuery下拉选择框插件支持单选多选功能代码
2016/06/07 Javascript
BootstrapValidator不触发校验的实现代码
2016/09/28 Javascript
基于javascript的异步编程实例详解
2017/04/10 Javascript
zTree 树插件实现全国五级地区点击后加载的示例
2018/02/05 Javascript
vue-cli中安装方法(图文详细步骤)
2018/12/12 Javascript
微信小程序rich-text富文本用法实例分析
2019/05/20 Javascript
微信小程序获取复选框全选反选选中的值(实例代码)
2019/12/17 Javascript
OpenLayers加载缩放控件使用方法详解
2020/09/25 Javascript
利用python获得时间的实例说明
2013/03/25 Python
Python使用defaultdict读取文件各列的方法
2017/05/11 Python
Python如何生成树形图案
2018/01/03 Python
python利用微信公众号实现报警功能
2018/06/10 Python
python matlibplot绘制多条曲线图
2021/02/19 Python
[机器视觉]使用python自动识别验证码详解
2019/05/16 Python
python 中pyqt5 树节点点击实现多窗口切换问题
2019/07/04 Python
Django学习之文件上传与下载
2019/10/06 Python
Django app配置多个数据库代码实例
2019/12/17 Python
Python 使用生成器代替线程的方法
2020/08/04 Python
css3实现3d旋转动画特效
2015/03/10 HTML / CSS
Peter Alexander新西兰站:澳大利亚领先的睡衣设计师品牌
2016/12/10 全球购物
俄罗斯茶和咖啡网上商店:Tea.ru
2021/01/26 全球购物
Unix如何添加新的用户
2014/08/20 面试题
英语专业学子个人的自我评价
2013/10/02 职场文书
春节活动策划方案
2014/01/24 职场文书
节水倡议书范文
2014/04/15 职场文书
护理专业自荐书
2014/06/04 职场文书
标准大学生职业生涯规划书写作指南
2014/09/18 职场文书
2015大学生入党个人自传
2015/06/26 职场文书