详解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-cli3没有vue.config.js文件夹及配置vue项目域名的问题
Dec 04 Vue.js
vue-quill-editor插入图片路径太长问题解决方法
Jan 08 Vue.js
原生JS封装vue Tab切换效果
Apr 28 Vue.js
vue基于Teleport实现Modal组件
May 31 Vue.js
Vue3.0写自定义指令的简单步骤记录
Jun 27 Vue.js
Vue3如何理解ref toRef和toRefs的区别
Feb 18 Vue.js
Vue.js中v-for指令的用法介绍
Mar 13 Vue.js
vue中控制mock在开发环境使用,在生产环境禁用方式
Apr 06 Vue.js
vue项目打包后路由错误的解决方法
Apr 13 Vue.js
vue elementUI批量上传文件
Apr 26 Vue.js
Vue组件化(ref,props, mixin,.插件)详解
May 15 Vue.js
vue3 自定义图片放大器效果的示例代码
Jul 23 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 数组遍历顺序理解
2009/09/09 PHP
fgetcvs在linux的问题
2012/01/15 PHP
php中global和$GLOBALS[]的分析之一
2012/02/02 PHP
Yii rules常用规则示例
2016/03/15 PHP
javascript在网页中实现读取剪贴板粘贴截图功能
2014/06/07 Javascript
jQuery 过滤方法filter()选择具有特殊属性的元素
2014/06/15 Javascript
javascript鼠标滑动评分控件完整实例
2015/05/13 Javascript
JavaScript实现类似淘宝的购物车效果
2017/03/16 Javascript
JS得到当前时间的方法示例
2017/03/24 Javascript
JS实现AES加密并与PHP互通的方法分析
2017/04/19 Javascript
JS实现简易的图片拖拽排序实例代码
2017/06/09 Javascript
浅谈js基础数据类型和引用类型,深浅拷贝问题,以及内存分配问题
2017/09/02 Javascript
Nodejs中的require函数的具体使用方法
2019/04/02 NodeJs
vue实现前台列表数据过滤搜索、分页效果
2019/05/28 Javascript
jQuery-Citys省市区三级菜单联动插件使用详解
2019/07/26 jQuery
vue中使用v-model完成组件间的通信
2019/08/22 Javascript
Express 配置HTML页面访问的实现
2020/11/01 Javascript
Python爬虫框架Scrapy安装使用步骤
2014/04/01 Python
Python实现的几个常用排序算法实例
2014/06/16 Python
Python中模块pymysql查询结果后如何获取字段列表
2017/06/05 Python
python获取程序执行文件路径的方法(推荐)
2018/04/26 Python
修改 CentOS 6.x 上默认Python的方法
2019/09/06 Python
浅析Python+OpenCV使用摄像头追踪人脸面部血液变化实现脉搏评估
2019/10/17 Python
Python API 操作Hadoop hdfs详解
2020/06/06 Python
如何编写python的daemon程序
2021/01/07 Python
浅谈Html5移动端ios/Android兼容性总结
2018/06/01 HTML / CSS
夏威夷灵感服装及配饰:Reyn Spooner
2018/09/18 全球购物
广州某公司软件工程师面试题
2014/12/22 面试题
寄语十八大感言
2014/02/07 职场文书
社区健康教育实施方案
2014/03/18 职场文书
2014年新生军训方案
2014/05/01 职场文书
走近毛泽东观后感
2015/06/04 职场文书
美德少年主要事迹材料
2015/11/04 职场文书
详解Python小数据池和代码块缓存机制
2021/04/07 Python
iPhone13再次曝光
2021/04/15 数码科技
pytorch 如何把图像数据集进行划分成train,test和val
2021/05/31 Python