Vue混入mixin

概念

vue官方文档中是这样说的:

        混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

        混入分为局部混入和全局混入,全局和局部的概念和全局组件、局部组件相同,这里不再赘述。  

弊端

        当你再项目中使用了过多的mixin,可能会造成项目难于维护的局面,这里说的难以维护指的是,你可能不能快速找到你的变量或者方法等是在何处定义的。

选项合并(需要多加注意)

当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。

        比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。

        同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。

        值为对象的选项,例如 methodscomponents 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。

代码示例

1、代码结构

我创建了一个mixin文件夹,里边创建了一个test1.js文件,代表的是一个混入对象,当然也可以创建多个js文件,代表多个混入对象,因为mixins接受的是一个数组。

2、App.vue(其中代码仅用于演示)

在app.vue中我使用了keep-alive包裹了router-view,这是为了演示混入和vuex的区别

vuex是全局状态管理,在修改state中的值时,所有依赖的组件都会重新render,而混入每个组件都是独立的数据,不会互相影响

<template>
  <div id="app">
    <img src="./assets/logo.png" />
    <button @click="goPage1">testPage1</button>
    <button @click="goPage2">testPage2</button>
    <button @click="goPage3">testPage3</button>
    <keep-alive>
      <router-view />
    </keep-alive>
  </div>
</template>

<script>
export default {
  name: 'App',
  methods: {
    goPage1 () {
      this.$router.push('/testPage1')
    },
    goPage2 () {
      this.$router.push('/testPage2')
    },
    goPage3 () {
      this.$router.push('/testPage3')
    }
  }
}
</script>

3、test1.js

混入对象和vue组件中的各个生命周期、数据等的定义是一致的

export const test1 = {
  data () {
    return {
      count: 1
    }
  },
  created () {
    console.log('我是mixin混入对象')
  }
}

4、pageOne.vue

在这个页面中,我们提供了一个修改count的方法,此方法改变数据不会影响到其他使用此混入对象的页面。

这里能读取到this.count是如上文所说:

当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

如下图所示:我们改变了页面1中混入对象的count值,但页面2中的值并没有受到影响。 

<template>
  <div>
    <h1>我是页面1</h1>
    <h2>count:{{ count }}</h2>
    <button @click="addCount">增加count</button>
  </div>
</template>

<script>
import { test1 } from '@/mixin/test1.js'
export default {
  mixins: [test1],
  methods: {
    addCount () {
      this.count++
    }
  }
}
</script>

<style></style>

5、pageTwo.vue

在这个页面中,会执行两个console,先执行的是混入对象中created中的console.log('我是mixin混入对象'),后执行当前组件的created方法中的console.log('我是页面2')

这也就是上文说的:

同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。

如下图所示:当我们点击testPage2时,先打印的“我是mixin混入对象”,后打印了“我是页面2” 

<template>
  <div>
    <h1>我是页面2</h1>
    <h2>count:{{ count }}</h2>
  </div>
</template>

<script>
import { test1 } from '@/mixin/test1.js'
export default {
  mixins: [test1],
  created () {
    console.log('我是页面2')
  }
}
</script>

<style></style>

 6、pageThree.vue

此页面组件中也定义了一个和混入对象同名的count变量,页面中展示的数据为3,并不是混入对象中的1,这也是上文所说:

数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。

如下图:我们可以看到,页面1和页面2的值都为1,而页面3的值为3 

<template>
  <div>
    <h1>我是页面3</h1>
    <h2>count:{{ count }}</h2>
  </div>
</template>

<script>
import { test1 } from '@/mixin/test1.js'
export default {
  mixins: [test1],
  data () {
    return {
      count: 3
    }
  }
}
</script>

<style></style>

全局混入 

请谨慎使用全局混入,因为它会影响每个单独创建的 Vue 实例 (包括第三方组件)。

自定义选项合并策略

自定义选项将使用默认策略,即简单地覆盖已有值。如果想让自定义选项以自定义逻辑合并,可以向 Vue.config.optionMergeStrategies 添加一个函数:

Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
  // 返回合并后的值
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值