Vue — 详解mixins混入使用,应用场景

本文深入解析Vue中的Mixins特性,介绍其概念、创建与使用方法,探讨Mixins与Vuex及公共组件的区别,并通过示例展示如何有效减少代码冗余。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

混入是vue官方文档提出的 关于vue复用性的一种方式,看了文档似懂,查找了下网上的讲解,整理下好好缕一缕这个东西

前言

当我们的项目越来越大,我们会发现组件之间可能存在很多相似的功能,你在一遍又一遍的复制粘贴相同的代码段(data,method,watch、mounted等),如果我们在每个组件中去重复定义这些属性和方法会使得项目出现代码冗余并提高了维护难度,针对这种情况官方提供了Mixins特性

一、什么是Mixins? mixins是一个js对象

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

mixins(混入),官方的描述是一种分发 Vue 组件中可复用功能的非常灵活的方式,mixins是一个js对象,它可以包含我们组件中script项中的任意功能选项,如data、components、methods 、created、computed等等。

我们只要将共用的功能以对象的方式传入 mixins选项中,当组件引用 mixins对象时所有mixins对象的选项都将被混入该组件本身的选项中来,这样就可以提高代码的重用性,使你的代码保持干净和易于维护。

image.png

放大看这张图:右边就是一个混入对象; 左边引用了混入对象

二、什么时候使用Mixins?

当我们存在多个组件中的数据或者功能很相近时,我们就可以利用mixins将公共部分提取出来,通过 mixins封装的函数,组件调用他们是不会改变函数作用域外部的。
作用: 减少data、methods、钩子的重复
🤭🤭🤭🤭
文章最后会举例应用场景~

三、如何创建Mixins?

在src目录下创建一个mixins文件夹,文件夹下新建一个myMixins.js文件。前面我们说了mixins是一个js对象,所以应该以对象的形式来定义myMixins,在对象中我们可以和vue组件一样来定义我们的data、components、methods 、created、computed等属性,并通过export导出该对象

image.png

四、如何使用Mixins?

前面在myMixins.js中输出一个混入对象,然后在需要调用的组件中引入myMixins.js文件即可

image.png

五、Mixins的特点

特点1:方法和参数在各组件中不共享,虽然组件调用了mixins并将其属性合并到自身组件中来了,但是其属性只会被当前组件所识别并不会被共享。

🤭也就是当前组件对mixins的属性的修改,其他也引用了这个mixins的组件并不会受影响。🤭

① 首先我们在混合对象myMixins.js中定义一个age字段和getAge方法

export const myMixins = {
  components:{},
  data() {
    return {
      age: 18,
    }
  },
  mounted() {
    this.getAge()
  },
  methods: {
    getAge() {
      console.log(this.age)
    }
  }
}

② 此时组件1引用了这个mixins,组件1中对age进行+1操作

// 这是组件1
import { myMixins } from "@/mixins/myMixins.js";
export default {
  mixins: [myMixins],
  data() {
    return {}
  },
  created() {
    this.age++   // 组件1的age变成了19啦
  },
}

③ 组件2不进行操作

export default {
  mixins: [myMixins],
  data() {
    return {}
  },
}

④ 我们分别切换到两个页面,查看控制台输出。会发现组件1改变了age里面的值,组件2中age值还是混合对象的初始值,并没有随着组件1的增加而改变

image.png

特点2:引入mixins后,组件会对其进行合并,将mixins中的数据和方法拓展到当前组件中来,如果当前组件也有同名称的属性或者方法,在合并的过程中会出现冲突,接下来我们详细了解Mixins合并冲突

六、Mixins合并冲突

【6.1】混入对象里的(components、methods 、computed、data)这些选项,混入组件时选项会被合并,重名冲突时优先采用组件的 🤭,组件中的键会覆盖混入对象的

① 我们在混入对象增加age属性、getAge1方法和getAge2方法

// myMixins.js
export const myMixins = {
  components:{},
  data() {
    return {
      age: 18,
    }
  },
  methods: {
    getAge1() {
      console.log("age1 from mixins =", this.age )
    },
    getAge2() {
      console.log("age2 from mixins =", this.age )
    },
  }
}

② 我们在引入了myMixins文件的组件中,增加age属性、getAge1方法和getAge3方法

// template.vue
import { myMixins } from "@/mixins/myMixins.js";
export default {
  mixins: [myMixins],
  data() {
    return {
      age: 20,
    }
  },
  mounted() {
    this.getAge1();
    this.getAge2();
    this.getAge3();
  },
  methods: {
    getAge1() {
      console.log('age1 from template =', this.age)
    },
    getAge3() {
      console.log('age3 from template =', this.age)
    },
  }
}

③ 我们会发现:
组件中的age覆盖了混合对象的age,
组件的getAge1方法覆盖了混合对象的getAge1方法

image.png

【6.2】值为函数(created、mounted)的选项,混入组件时选项会被合并调用,
🤭 混合对象里的钩子函数在组件里的钩子函数之前调用

// myMixins.js
export const myMixins = {
  components:{},
  data() {
    return {}
  },
  created() {
    console.log('xxx from mixins')
  }
}

再看看引用了mixins的组件

import { myMixins } from "@/mixins/myMixins.js";
export default {
  mixins: [myMixins],
  data() {
    return {}
  },
  created() {
    console.log('xxx from template')
  }
}

结果 mixins自己的created 比 引用了mixins的组件里的created先执行

image.png

七、全局混入

严重警告:一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。
使用恰当时,这可以用来为自定义选项注入处理逻辑。

// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
  created: function () {
    var myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})

new Vue({
  myOption: 'hello!'
})
// => "hello!"

不建议使用全局混入,全局注册之后会对所有组件都生效,影响比较大,项目大的情况下,建议使用局部注册

八、同时引入多个mixin对象

同时引入多个 mixins: [mixinsTest2,mixinsTest]

在使用局部注册的时候,可同时引入多个混入对象,执行顺序和引入顺序一致,此处便不再赘述了。

结论: 引入多个以后,,我们先引入的先被使用,先引用,先使用!

九、与vuex的区别

vuex:用来做状态管理的,里面定义的变量在每个组件中均可以使用和修改,在任一组件中修改此变量的值之后,其他组件中此变量的值也会随之修改。

Mixins:可以定义共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。

十、与公共组件的区别

组件:在父组件中引入组件,相当于在父组件中给出一片独立的空间供子组件使用,然后根据props来传值,但本质上两者是相对独立的。

Mixins:则是在引入Mixins之后,Mixins与组件中的属性和方法进行合并,相当于扩展了父组件的对象与方法,可以理解为形成了一个新的组件。

😄😄

另外,vue不建议,子组件直接修改props接收到的父组件的数据,但是,混入可以做到组件的属性或者方法覆盖混入对象的

混入的应用场景

假设我们需要在每个组件上添加name和time。在created、destroyed时,打出提示,并给出存活时间。

一共有五个组件,请问怎么做?
做法1:给每个组件添加data和created, destroyed钩子,重复5次
做法2:使用mixin减少重复。

做法1:

<template>
    <div>child1</div>
</template>
<script>
    export default{
        data(){
            return {
                name:'child1',
                time_birth:undefined,
                time_dead:undefined
            }
        },
        created(){
            this.time_birth=new Date();
            console.log(this.name+'出生了');
        },
        beforeDestroy(){
            this.time_dead=new Date();
            console.log(`${this.name}死了,共存活了${this.time_dead-this.time_birth}ms`);
        }
    }
</script>

// 依次对组件2 3 4 5 分别执行这些操作。。。

做法1小结: 代码重复太多,基本上每个组件都在复刻第一个组件的样式,这样下来,代码的维护性是十分低的。万一有一天要改需求了怎么办?又倒回去重新修改5次吗?5次并不是真正的5次,万一是10次,100次呢?很显然,这种做法并不可取。接下来来看另外一种做法。

做法2:
创建混入对象:

const myMixin = {
    data(){
            return {
                /* 每个组件的名字不同,用另外的方法赋值。即每个组件自己带上自己的名字即可。 */
                name:undefined,
                time_birth:undefined,
                time_dead:undefined
            }
        },
        created(){
            if(!this.name){
                throw new Error('need name');  // 名字是用的组件里data的name
            }
            this.time_birth=new Date();
            console.log(this.name+'出生了');
        },
        beforeDestroy(){
            this.time_dead=new Date();
            console.log(`${this.name}死了,共存活了${this.time_dead-this.time_birth}ms`);
        }
}
export default myMixin;

组件里

<template>
    <div>child1</div>
</template>
<script>
    /* 首先导入公共部分的js内容 */
    import myMixin from './Mixins/public.js';
    export default{
        data(){
            return {
                /* 其他组件就写自己组件的名字即可 */
                name:'child1',
            }
        },
        /* 使用导入的public模块 */
        mixins:[myMixin],
    }
</script>

用了混入后,组件只需要引用混入对象,然后在data里填写组件的名字,再挂载一下混入对象,就好了。

<think>好的,我现在需要帮助用户了解Vue2中mixins的用法,包括教程、示例和详解。根据用户提供的引用内容,我需要整理出一个结构清晰、分步解释的回答,并生成相关问题。首先,我需要回顾Vue2的mixins相关知识,确保信息准确。 首先,mixins作用是复用组件选项,比如方法、数据、生命周期钩子等。用户提供的引用中提到了局部混入和全局混入两种方式,以及合并策略和注意事项。我需要将这些信息组织起来,分步骤说明。 第一步,介绍mixins的基本概念,可能引用引用[5]中的内容,说明mixins接收混入对象数组,合并选项的方式。然后给出一个基本示例,比如创建一个mixin对象,包含数据和方法,并在组件中通过mixins选项引入,如引用[2]中的示例。 第二步,详细说明如何使用mixins,分局部和全局。局部混入可以参考引用[2]和引用[3]中的示例代码,展示如何创建mixin并在组件中引入。全局混入则需要使用Vue.mixin(),如引用[1]和引用[4]所示,但要注意全局混入的影响范围,可能影响所有实例,需谨慎使用。 第三步,合并策略是关键部分,需要解释不同选项的合并方式。例如,数据对象会递归合并,冲突时组件数据优先;生命周期钩子会被合并成数组,依次调用;方法、计算属性等组件选项会覆盖mixin的同名选项。这部分引用[5]中有说明,需要详细展开。 第四步,注意事项,比如命名冲突的避免,全局混入的风险,以及mixins的适用场景。可以引用用户提供的引用中的相关内容,例如引用[4]提到的全局混入的影响,以及引用[5]中的合并逻辑。 接下来,示例部分需要给出具体的代码,可能结合引用中的例子,比如创建一个日志功能的mixin,然后在组件中使用。同时,展示局部和全局混入的代码示例,并解释执行结果,如引用[3]中的created钩子调用mixin的方法。 最后,总结mixins的优势和局限性,强调合理使用。生成的相关问题需要考虑用户可能进一步想了解的内容,比如mixinsVue3的组合式API对比,替代方案,处理冲突的方法,优缺点,以及实际项目中的应用场景。 需要确保回答符合用户的要求,使用中文,结构清晰,分步骤说明,并正确引用提供的参考资料。同时,检查LaTeX格式是否符合要求,行内公式用$...$,独立公式用$$...$$,但在这个问题中可能涉及较少数学公式,但要注意代码块的使用是否正确,如示例中的代码用三个反引号包裹,并标明语言。 现在组织这些内容,确保每个部分都有对应的引用支持,并自然添加引用标识。例如,在讲解局部混入时引用[2][3],全局混入引用[1][4],合并策略引用[5]等。同时,生成的相关问题要围绕mixins的深入使用、问题解决、比较等方面展开。</think>### Vue2 mixins 使用教程与示例详解 #### 一、Mixins 基础概念 MixinsVue2 中实现代码复用的核心机制,允许将组件的选项(如数据、方法、生命周期钩子)提取为独立模块,供多个组件复用。其核心逻辑是**选项合并**:若组件与 Mixin 存在同名属性,Vue 会按特定规则合并[^5]。 #### 二、Mixins 使用步骤 ##### 1. 局部混入(组件级) **步骤1:创建 Mixin 对象** 新建一个 `.js` 文件(如 `myMixin.js`),定义可复用逻辑: ```javascript // myMixin.js export const myMixin = { data() { return { count: 0 } }, methods: { increment() { this.count++ } }, mounted() { console.log('Mixin mounted') } } ``` **步骤2:在组件中引入** 通过 `mixins` 选项注入组件: ```javascript // Home.vue import { myMixin } from '@/mixins/myMixin' export default { mixins: [myMixin], mounted() { this.increment() // 调用 Mixin 方法 console.log(this.count) // 输出 1 } } ``` 组件会合并 Mixin 的 `data`、`methods` 和生命周期钩子[^2][^3]。 --- ##### 2. 全局混入(慎用) 通过 `Vue.mixin()` 注册全局 Mixin,影响**所有后续创建的 Vue 实例**: ```javascript // main.js Vue.mixin({ created() { if (this.$options.logMessage) { console.log(this.$options.logMessage) } } }) new Vue({ logMessage: '全局混入生效', // ... }) ``` 此例中,所有组件在 `created` 阶段都会检查 `logMessage` 并打印[^1][^4]。 --- #### 三、合并策略详解 | 选项类型 | 合并规则 | 示例冲突处理 | |-----------------|--------------------------------------------------------------------------|----------------------------------| | **数据对象** | 递归合并,组件数据优先 | 组件 `data: {count: 5}` 覆盖 Mixin | | **生命周期钩子**| 合并为数组,Mixin 钩子**先执行** | Mixin 的 `mounted` 先于组件的 | | **方法/计算属性**| 组件选项覆盖 Mixin 同名选项 | 组件的 `increment()` 替换 Mixin | | **自定义选项** | 需通过 `Vue.config.optionMergeStrategies` 自定义合并函数(如权限校验) | 参考 Vue 官方文档配置 | --- #### 四、注意事项 1. **命名冲突风险** 若组件与 Mixin 有同名方法或数据,组件内容会覆盖 Mixin[^5]。建议通过命名约定(如 `mixin_xxx`)规避。 2. **全局混入的副作用** 全局 Mixin 会影响所有实例,可能导致难以追踪的 Bug。建议仅用于日志、权限等底层通用逻辑[^4]。 3. **替代方案** Vue3 的 Composition API 提供了更灵活的 `setup()` 函数,可替代 Mixins 实现逻辑复用。 --- #### 五、完整示例:日志功能复用 **Mixin 定义** ```javascript // loggerMixin.js export default { methods: { log(message) { console.log(`[${this.$options.name}]: ${message}`) } } } ``` **组件使用** ```javascript // UserList.vue import loggerMixin from '@/mixins/loggerMixin' export default { name: 'UserList', mixins: [loggerMixin], created() { this.log('组件已加载') // 输出 [UserList]: 组件已加载 } } ``` ---
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值