详解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 插槽简介及使用示例
Nov 19 Vue.js
如何使用 vue-cli 创建模板项目
Nov 19 Vue.js
详解实现vue的数据响应式原理
Jan 20 Vue.js
Vue实现摇一摇功能(兼容ios13.3以上)
Jan 26 Vue.js
vue-cli中实现响应式布局的方法
Mar 02 Vue.js
vue实现倒计时功能
Mar 24 Vue.js
vue3中的组件间通信
Mar 31 Vue.js
vue3使用vue-router的完整步骤记录
Jun 20 Vue.js
vue中利用mqtt服务端实现即时通讯的步骤记录
Jul 01 Vue.js
Element-ui Layout布局(Row和Col组件)的实现
Dec 06 Vue.js
vue cli4中mockjs在dev环境和build环境的配置详情
Apr 06 Vue.js
vue实现登陆页面开发实践
May 30 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
为什么《星际争霸》是测试人工智能的理想战场
2019/12/03 星际争霸
ASP知识讲座四
2006/10/09 PHP
PHP面向对象分析设计的经验原则
2008/09/20 PHP
php5 图片验证码实现代码
2009/12/11 PHP
php 实现进制转换(二进制、八进制、十六进制)互相转换实现代码
2010/10/22 PHP
Apache2中实现多网站域名绑定的实现方法
2011/06/01 PHP
NodeJS框架Express的模板视图机制分析
2011/07/19 NodeJs
JavaScript检测浏览器cookie是否已经启动的方法
2015/02/27 Javascript
JS实现文件动态顺序载入的方法
2015/03/07 Javascript
WordPress中鼠标悬停显示和隐藏评论及引用按钮的实现
2016/01/12 Javascript
Bootstrap每天必学之工具提示(Tooltip)插件
2016/04/26 Javascript
AngularJS入门教程之服务(Service)
2016/07/27 Javascript
echarts学习笔记之箱线图的分析与绘制详解
2017/11/22 Javascript
详解vuex之store拆分即多模块状态管理(modules)篇
2018/11/13 Javascript
vue 实现根据data中的属性值来设置不同的样式
2020/08/04 Javascript
[01:18:45]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第三场2月1日
2021/03/11 DOTA
零基础写python爬虫之抓取百度贴吧并存储到本地txt文件改进版
2014/11/06 Python
Python列表(list)、字典(dict)、字符串(string)基本操作小结
2014/11/28 Python
python使用Queue在多个子进程间交换数据的方法
2015/04/18 Python
Python数据可视化正态分布简单分析及实现代码
2017/12/04 Python
解决python中 f.write写入中文出错的问题
2018/10/31 Python
python encrypt 实现AES加密的实例详解
2020/02/20 Python
增大python字体的方法步骤
2020/07/05 Python
Python pysnmp使用方法及代码实例
2020/08/24 Python
python 利用百度API识别图片文字(多线程版)
2020/12/14 Python
如何用border-image实现文字气泡边框的示例代码
2020/01/21 HTML / CSS
html5.2 dialog简介详解
2018/02/27 HTML / CSS
专营店会计助理岗位职责
2013/11/29 职场文书
我的求职计划书
2014/01/10 职场文书
五十岁生日宴会答谢词
2014/01/15 职场文书
大专毕业自我鉴定
2014/02/04 职场文书
主题班会演讲稿
2014/05/22 职场文书
2014年教研室工作总结
2014/12/06 职场文书
升学宴家长答谢词
2015/09/29 职场文书
电工生产实习心得体会
2016/01/22 职场文书
vue 给数组添加新对象并赋值
2022/04/20 Vue.js