详解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 相关文章推荐
vue3.0实现点击切换验证码(组件)及校验
Nov 18 Vue.js
浅析VUE防抖与节流
Nov 24 Vue.js
vue表单验证之禁止input输入框输入空格
Dec 03 Vue.js
Vue-router中hash模式与history模式的区别详解
Dec 15 Vue.js
vue3.0中友好使用antdv示例详解
Jan 05 Vue.js
vue实现按钮切换图片
Jan 20 Vue.js
vue如何使用rem适配
Feb 06 Vue.js
详解Vue3.0 + TypeScript + Vite初体验
Feb 22 Vue.js
vue常用高阶函数及综合实例
Feb 25 Vue.js
Vue h函数的使用详解
Feb 18 Vue.js
vue使用echarts实现折线图
Mar 21 Vue.js
在vue中import()语法不能传入变量的问题及解决
Apr 01 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 操作文件的一些FAQ总结
2009/02/12 PHP
thinkphp模板继承实例简述
2014/11/26 PHP
php实现字符串首字母转换成大写的方法
2015/03/17 PHP
php is_executable判断给定文件名是否可执行实例
2016/09/26 PHP
推荐30个新鲜出炉的精美 jQuery 效果
2012/03/26 Javascript
js正文内容高亮效果的实现方法
2013/06/30 Javascript
js设置组合快捷键/tabindex功能的方法
2013/11/21 Javascript
JavaScript—window对象使用示例
2013/12/09 Javascript
Node.js开发者必须了解的4个JS要点
2016/02/21 Javascript
浅谈js和css内联外联注意事项
2016/06/30 Javascript
举例讲解jQuery对DOM元素的向上遍历、向下遍历和水平遍历
2016/07/07 Javascript
JavaScript 控制字体大小设置的方法
2016/11/23 Javascript
Vuex模块化实现待办事项的状态管理
2017/03/15 Javascript
nodejs和C语言插入mysql数据库乱码问题的解决方法
2017/04/14 NodeJs
细说webpack源码之compile流程-入口函数run
2017/12/26 Javascript
vue中使用gojs/jointjs的示例代码
2018/08/24 Javascript
JS监听滚动和id自动定位滚动
2018/12/18 Javascript
使用vue实现多规格选择实例(SKU)
2019/08/23 Javascript
使用Vue调取接口,并渲染数据的示例代码
2019/10/28 Javascript
[01:39](回顾)各路豪强针锋相对,几经鏖战四强产生
2014/07/01 DOTA
[19:26]TNC vs EG (BO3)
2018/06/07 DOTA
巧用python和libnmapd,提取Nmap扫描结果
2016/08/23 Python
python实现kMeans算法
2017/12/21 Python
pycharm运行和调试不显示结果的解决方法
2018/11/30 Python
Flask框架web开发之零基础入门
2018/12/10 Python
python实现的登录与提交表单数据功能示例
2019/09/25 Python
Python利用 utf-8-sig 编码格式解决写入 csv 文件乱码问题
2020/02/21 Python
python数据分析:关键字提取方式
2020/02/24 Python
马耳他航空公司官方网站:Air Malta
2019/05/15 全球购物
澳大利亚购买太阳镜和眼镜网站:Glamoureyes
2020/09/22 全球购物
业务主管岗位职责范本
2013/12/25 职场文书
商务英语专业求职信范文
2014/01/28 职场文书
社区党员公开承诺书
2014/08/30 职场文书
西安兵马俑导游词
2015/02/02 职场文书
离婚承诺书格式范文
2015/05/04 职场文书
dubbo服务整合zipkin详解
2021/07/26 Java/Android