详解Vue的mixin策略

我之前一直以为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策略的资料请关注我们其它相关文章!

(0)

相关推荐

  • Vue之mixin全局的用法详解

    先贴上官方定义. 个人觉得全局mixin就是给全部Vue文件添加一些公用的实例(方法,过滤器and so on) 使用场景:货币单位,时间格式.这些如果在用到的页面使用的话代码会重复的很多,所以在全局混入这些实例会减少代码量,可维护性也比较高. ex: step1: 先定义mixin.js const mixin = { methods: { /** * 格式化时间 * @param {string|number|object|Array} dateTime - 时间,可以是一个字符串.时间戳.

  • 深入浅析Vue中mixin和extend的区别和使用场景

    Vue中有两个较为高级的静态方法mixin和extend,接下来我们来讨论下关于他们各自的原理和使用场景. Mixin: 原理: 先来看看官网的介绍: 参数:{Object} mixin 用法: 混入也可以进行全局注册.使用时格外小心!一旦使用全局混入,它将影响每一个之后创建的 Vue 实例.使用恰当时,这可以用来为自定义选项注入处理逻辑. // 为自定义的选项 'myOption' 注入一个处理器. Vue.mixin({ created: function () { var myOption

  • 记一次Vue.js混入mixin的使用(分权限管理页面)

    需求背景:在一个后台的管理系统中,不同的用户角色对应不同的用户权限.现要求,同一个页面对有操作权限的用户来说是可操作的,对无操作权限的用户来说是只读的,即操作按钮均失效.系统用Vue.js开发. 一.mixin的概念 官方文档这么说:混入是一种分发Vue组件中可服用功能的非常灵活的方式.混入对象可以包含任意组件选项.当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项. 我自己的理解:混入对象具有Vue组件可以声明的所有选项,如[components].[computed].[met

  • Vue中的混入的使用(vue mixins)

    使用场景: 例如我们在Vue单页面开发的时候当多个组件中都需要下拉刷新,或者使用的都是一个方法的时候,我们就可以使用vue mixins进行封装调用,以及继承,具体看代码. 选项合并 var mixin = { data: function () { return { message: 'hello' } }, created:function(){ console.log('我是mixins中的created') }, methods:{ show:function(num){ console

  • 使用vue中的混入mixin优化表单验证插件问题

    这段时间开发的时候使用到了这个表单校验插件,用起来比较麻烦就不说了,还有较严重的缺陷.自己最终还是抽空把这个插件进行了一些优化,虽然优化的方式和当初自己定下的方向不怎么相同,但是就使用体验上来说还是提高了很多. 1. 实际开发中遇到的问题 在上面的文章中提及了一些表单插件的问题,主要针对的是插件开发本身存在的问题.下面我总结下使用中存在的问题: 每个使用表单校验的元素都需要添加 v-check 类名,比较麻烦. 必须在提交表单按钮上使用 v-checkSubmit 指令进行表单校验,提交函数必须

  • Vue之Mixins(混入)的使用方法

    混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能.一个混入对象可以包含任意组件选项.当组件使用混入对象时,所有混入对象的选项将被"混合"进入该组件本身的选项. 当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行"合并". 比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先. var Mymixin = { data: function(){ return { message: 'hello', foo: 'ab

  • Vue 中mixin 的用法详解

    说下我对vue中mixin的一点理解 vue中提供了一种混合机制--mixins,用来更高效的实现组件内容的复用.最开始我一度认为这个和组件好像没啥区别..后来发现错了.下面我们来看看mixins和普通情况下引入组件有什么区别? 组件在引用之后相当于在父组件内开辟了一块单独的空间,来根据父组件props过来的值进行相应的操作,单本质上两者还是泾渭分明,相对独立. 而mixins则是在引入组件之后,则是将组件内部的内容如data等方法.method等属性与父组件相应内容进行合并.相当于在引入后,父

  • 在 Typescript 中使用可被复用的 Vue Mixin功能

    转到用 Typescript 写 Vue 应用以后,经过一轮工具链和依赖的洗礼,总算蹒跚地能走起来了,不过有一个很常用的功能 mixin,似乎还没有官方的解决方案. 既想享受 mixin 的灵活和方便,又想收获 ts 的类型系统带来的安全保障和开发时使用 IntelliSense 的顺滑体验. vuejs 官方组织里有一个 'vue-class-component' 以及连带推荐的 'vue-property-decorator',都没有相应实现.翻了下前者的 issue,有一条挂了好些时间的待

  • 浅谈Vue3 Composition API如何替换Vue Mixins

    想在你的Vue组件之间共享代码?如果你熟悉Vue 2 则可能知道使用mixin,但是新的Composition API 提供了更好的解决方案. 在本文中,我们将研究mixins的缺点,并了解Composition API如何克服它们,并使Vue应用程序具有更大的可伸缩性. 回顾Mixins功能 让我们快速回顾一下mixins模式,因为对于下一部分我们将要讲到的内容,请务必将其放在首位. 通常,Vue组件是由一个JavaScript对象定义的,它具有表示我们所需功能的各种属性--诸如 data,m

  • 详解vue项目中如何引入全局sass/less变量、function、mixin

    让我们考虑下场景:当使用rem/vw开发移动端的时候,你定义了一个px转rem的函数,或者是网站配色的全局变量等,然后到工程里为每个vue文件或者组件@import 'publicfilename.scss',那得重复做这样的工作很多很多...次,万一这些公用文件目录路径变怎么办呢,哭都来不及,想想都觉得恐怖呀! 接下来拯救我们的神器就要登场了---sass-resources-loader,它可以省去重复性的引入,还支持less,postcss等,具体用法如下: npm install -d

  • 深入了解Vue.js 混入(mixins)

    混入 (mixins)定义了一部分可复用的方法或者计算属性.混入对象可以包含任意组件选项.当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项. 来看一个简单的实例: var vm = new Vue({ el: '#databinding', data: { }, methods : { }, }); // 定义一个混入对象 var myMixin = { created: function () { this.startmixin() }, methods: { startmix

随机推荐