vue2—— mixin 超级详细!!!

2024-04-29 08:12

本文主要是介绍vue2—— mixin 超级详细!!!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

mixin

Mixin是面向对象程序设计语言中的类,提供了方法的实现。其他类可以访问mixin类的方法而不必成为其子类

Mixin类通常作为功能模块使用,在需要该功能时“混入”,有利于代码复用又避免了多继承的复杂

vue中的mixin

先来看一下官方定义

mixin(混入),提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。

本质其实就是一个js对象,它可以包含我们组件中任意功能选项,如datacomponentsmethodscreatedcomputed等等

我们只要将共用的功能以对象的方式传入 mixins选项中,当组件使用 mixins对象时所有mixins对象的选项都将被混入该组件本身的选项中来

Vue中我们可以局部混入全局混入

局部混入

首先在 src 同级目录下 创建 mixin/index.js 文件 

export const mixins = {data() {return {msg: "我是mixin中的数据",};},computed: {},created() {console.log("我是 mixin 中的 created 生命周期函数");},mounted() {},methods: {geMes(){console.log("我是点击事件 hhhhh");}},
};

在组件中使用

<script>
import { mixins } from "./mixin/index";
export default {name: "app",mixins: [mixins],created() {console.log("我是app的生命周期 created",this.msg);this.geMes()}
};
</script>

结果

以上代码引入 mixin 的方法很简单,直接使用vue提供给我们的mixins 属性:mixins:[mixins]

总结:

  • mixin 中的生命周期函数会和组件中的生命周期函数一起合并执行
  • mixin 中的data数据在组件中也可以使用
  • mixin 中的方法在组件内部可以直接调用
  • 生命周期函数 合并后 执行顺序:先执行mixin中的,后执行组件的

那么多个组件使用相同的 mixin, 当mixin被修改了 其他组件数据会发生变化吗?

在 components中创建一个 demo 组件

代码如下

// demo.vue
<template><div><p>我是 demo 组件</p><p>我使用了 mixin 中的数据 msg —————— {{ msg }}</p></div>
</template><script>
import { mixins } from "@/mixin/index";
export default {
name: "app",mixins: [mixins],
}
</script>

 

 app组件

// app.vue
<template><div><!-- 组件 --><demo/><!-- app 本体内容 --><div>我是app页面的按钮 点击修改mixin中的msg <p>mixin —————— {{ msg }}</p><button @click="setMsg">修改msg</button></div></div>
</template><script>
import demo from './components/demo.vue';
import { mixins } from "./mixin/index";
export default {components: { demo },name: "app",mixins: [mixins],methods: {setMsg() {this.msg = "我被修改了!!!"}}};

结果

结论

在app组件更改了 msg,demo没有变化,所以 不同组件中的mixin 是相互独立的

全局混入

在mian.js 挂载mixin就可以每个组件使用了

import Vue from 'vue'
import App from './App.vue'
import { mixins } from "./mixin/index";
Vue.mixin(mixins)Vue.config.productionTip = falsenew Vue({render: h => h(App),
}).$mount('#app')

请谨慎使用全局混入,因为它会影响每个单独创建的 Vue 实例 (包括第三方组件)。大多数情况下,只应当应用于自定义选项,就像上面示例一样。推荐将其作为插件发布,以避免重复应用混入。

选项合并

当mixin中定义的属性或方法的名称与组件中定义的名称发生冲突怎么办?

从源码上看 可以分为如下几种类型

  • 替换型
  • 合并型
  • 队列型
  • 叠加型

替换型

替换型合并有propsmethodsinjectcomputed

strats.props =
strats.methods =
strats.inject =
strats.computed = function (parentVal: ?Object,childVal: ?Object,vm?: Component,key: string
): ?Object {if (!parentVal) return childVal // 如果parentVal没有值,直接返回childValconst ret = Object.create(null) // 创建一个第三方对象 retextend(ret, parentVal) // extend方法实际是把parentVal的属性复制到ret中if (childVal) extend(ret, childVal) // 把childVal的属性复制到ret中return ret
}
strats.provide = mergeDataOrFn

 同名的propsmethodsinjectcomputed会被后来者代替

 

合并型

和并型合并有:data

strats.data = function(parentVal, childVal, vm) {    return mergeDataOrFn(parentVal, childVal, vm)
};function mergeDataOrFn(parentVal, childVal, vm) {    return function mergedInstanceDataFn() {        var childData = childVal.call(vm, vm) // 执行data挂的函数得到对象var parentData = parentVal.call(vm, vm)        if (childData) {            return mergeData(childData, parentData) // 将2个对象进行合并                                 } else {            return parentData // 如果没有childData 直接返回parentData}}
}function mergeData(to, from) {    if (!from) return to    var key, toVal, fromVal;    var keys = Object.keys(from);   for (var i = 0; i < keys.length; i++) {key = keys[i];toVal = to[key];fromVal = from[key];    // 如果不存在这个属性,就重新设置if (!to.hasOwnProperty(key)) {set(to, key, fromVal);}      // 存在相同属性,合并对象else if (typeof toVal =="object" && typeof fromVal =="object") {mergeData(toVal, fromVal);}}    return to

mergeData函数遍历了要合并的 data 的所有属性,然后根据不同情况进行合并:

  • 当目标 data 对象不包含当前属性时,调用 set 方法进行合并(set方法其实就是一些合并重新赋值的方法)
  • 当目标 data 对象包含当前属性并且当前值为纯对象时,递归合并当前对象值,这样做是为了防止对象存在新增属性

队列型

队列性合并有:全部生命周期和watch

function mergeHook (parentVal: ?Array<Function>,childVal: ?Function | ?Array<Function>
): ?Array<Function> {return childVal? parentVal? parentVal.concat(childVal): Array.isArray(childVal)? childVal: [childVal]: parentVal
}LIFECYCLE_HOOKS.forEach(hook => {strats[hook] = mergeHook
})// watch
strats.watch = function (parentVal,childVal,vm,key
) {// work around Firefox's Object.prototype.watch...if (parentVal === nativeWatch) { parentVal = undefined; }if (childVal === nativeWatch) { childVal = undefined; }/* istanbul ignore if */if (!childVal) { return Object.create(parentVal || null) }{assertObjectType(key, childVal, vm);}if (!parentVal) { return childVal }var ret = {};extend(ret, parentVal);for (var key$1 in childVal) {var parent = ret[key$1];var child = childVal[key$1];if (parent && !Array.isArray(parent)) {parent = [parent];}ret[key$1] = parent? parent.concat(child): Array.isArray(child) ? child : [child];}return ret
};

生命周期钩子和watch被合并为一个数组,然后正序遍历一次执行

叠加型

叠加型合并有:componentdirectivesfilters

strats.components=
strats.directives=strats.filters = function mergeAssets(parentVal, childVal, vm, key
) {    var res = Object.create(parentVal || null);    if (childVal) { for (var key in childVal) {res[key] = childVal[key];}   } return res
}

叠加型主要是通过原型链进行层层的叠加

小结:

  • 替换型策略有propsmethodsinjectcomputed,就是将新的同名参数替代旧的参数
  • 合并型策略是data, 通过set方法进行合并和重新赋值
  • 队列型策略有生命周期函数和watch,原理是将函数存入一个数组,然后正序遍历依次执行
  • 叠加型有componentdirectivesfilters,通过原型链进行层层的叠加

mixin的优缺点

从上面的例子看来,使用mixin的好处多多,但是凡是都有两面性,这里总结几点优缺点供大家参考:

 优点

  • 提高代码复用性
  • 无需传递状态
  • 维护方便,只需要修改一个地方即可

缺点

  • 命名冲突
  • 滥用的话后期很难维护
  • 不好追溯源,排查问题稍显麻烦
  • 不能轻易的重复代码

总结

mixin给我们提供了方便的同时也给我们带来了灾难,所以有很多时候不建议滥用它,但是在有些场景下使用它又是非常合适的,这就得根据自己来取舍了。所以在很多时候我们需要考虑用公共组件还是使用mixin。

这篇关于vue2—— mixin 超级详细!!!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/945559

相关文章

vite搭建vue3项目的搭建步骤

《vite搭建vue3项目的搭建步骤》本文主要介绍了vite搭建vue3项目的搭建步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1.确保Nodejs环境2.使用vite-cli工具3.进入项目安装依赖1.确保Nodejs环境

Nginx搭建前端本地预览环境的完整步骤教学

《Nginx搭建前端本地预览环境的完整步骤教学》这篇文章主要为大家详细介绍了Nginx搭建前端本地预览环境的完整步骤教学,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录项目目录结构核心配置文件:nginx.conf脚本化操作:nginx.shnpm 脚本集成总结:对前端的意义很多

前端缓存策略的自解方案全解析

《前端缓存策略的自解方案全解析》缓存从来都是前端的一个痛点,很多前端搞不清楚缓存到底是何物,:本文主要介绍前端缓存的自解方案,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、为什么“清缓存”成了技术圈的梗二、先给缓存“把个脉”:浏览器到底缓存了谁?三、设计思路:把“发版”做成“自愈”四、代码

通过React实现页面的无限滚动效果

《通过React实现页面的无限滚动效果》今天我们来聊聊无限滚动这个现代Web开发中不可或缺的技术,无论你是刷微博、逛知乎还是看脚本,无限滚动都已经渗透到我们日常的浏览体验中,那么,如何优雅地实现它呢?... 目录1. 早期的解决方案2. 交叉观察者:IntersectionObserver2.1 Inter

Vue3视频播放组件 vue3-video-play使用方式

《Vue3视频播放组件vue3-video-play使用方式》vue3-video-play是Vue3的视频播放组件,基于原生video标签开发,支持MP4和HLS流,提供全局/局部引入方式,可监听... 目录一、安装二、全局引入三、局部引入四、基本使用五、事件监听六、播放 HLS 流七、更多功能总结在 v

Python中isinstance()函数原理解释及详细用法示例

《Python中isinstance()函数原理解释及详细用法示例》isinstance()是Python内置的一个非常有用的函数,用于检查一个对象是否属于指定的类型或类型元组中的某一个类型,它是Py... 目录python中isinstance()函数原理解释及详细用法指南一、isinstance()函数

Python的pandas库基础知识超详细教程

《Python的pandas库基础知识超详细教程》Pandas是Python数据处理核心库,提供Series和DataFrame结构,支持CSV/Excel/SQL等数据源导入及清洗、合并、统计等功能... 目录一、配置环境二、序列和数据表2.1 初始化2.2  获取数值2.3 获取索引2.4 索引取内容2

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

vue监听属性watch的用法及使用场景详解

《vue监听属性watch的用法及使用场景详解》watch是vue中常用的监听器,它主要用于侦听数据的变化,在数据发生变化的时候执行一些操作,:本文主要介绍vue监听属性watch的用法及使用场景... 目录1. 监听属性 watch2. 常规用法3. 监听对象和route变化4. 使用场景附Watch 的

前端导出Excel文件出现乱码或文件损坏问题的解决办法

《前端导出Excel文件出现乱码或文件损坏问题的解决办法》在现代网页应用程序中,前端有时需要与后端进行数据交互,包括下载文件,:本文主要介绍前端导出Excel文件出现乱码或文件损坏问题的解决办法,... 目录1. 检查后端返回的数据格式2. 前端正确处理二进制数据方案 1:直接下载(推荐)方案 2:手动构造