Vue 之 mixins 和 provide/inject

一、mixins

1、简介

mixins 又称 混入,是指将一些可复用的代码(JS、生命周期钩子函数等等)抽离出来,定义成mixins模块,然后混入到多个组件中,从而实现组件间的逻辑代码共享,减少重复代码。当组件使用mixins模块时,mixins模块内部的代码将会被“混合”进组件的代码,代码“混合”逻辑与Vue.extend()相同,具体逻辑下面有讲解。

2、基础使用

mixins模块在组件内是通过与datamountedmethods等钩子函数同级的mixins钩子调用的,该钩子的值是一个数组,里面包含要混入当前组件的mixins模块,这些模块的混入顺序按照mixins钩子数组的排列顺序执行,而且mixins模块内如果包含生命周期钩子函数,则模块内的钩子函数执行顺序先于组件本身的钩子函数。

案例代码:
// 定义一个mixin模块 mixin.js
export default {created: function () { console.log('这里是mixin1模块的created') }
}// 在组件实例中引入并使用定义的mixin模块
// 引入mixin模块
import mixin from "../mixins/mixin";
export default {created: function () { console.log('这里是组件本身的created') },// 使用mixin模块mixins: [mixin]
}
执行结果:

在这里插入图片描述

3、选项合并

​ 当组件与引入的mixins模块含有同名选项时,这些钩子将依照下面的规则进行合并( Vue.extend()的合并逻辑相同):

​ ① mixins模块中的data数据对象,将与组件的data数据进行递归合并,如果存在同名数据,则取组件内的数据值。

​ 当组件引入多个mixins模块时,将按照mixins钩子数组的排列顺序进行合并,如果mixins模块之间存在同名数据,则取排序最后的那个mixins模块的数据值,当然,如果该数据在组件内也存在,则还是取组件内的数据值。

案例代码:
// 定义一个mixin1.js模块
export default {data() {return {a: 1, // 第一个混入模块中的变量ab: 11 // 第一个混入模块中的变量b}},
}
// 定义一个mixin2.js模块
export default {data() {return {a: 2, // 第二个混入模块中的变量ab: 22 // 第二个混入模块中的变量b}},
}// 在组件实例中引入并使用定义的mixin模块
// 引入两个mixin模块
import mixin1 from "../mixins/mixin1";
import mixin2 from "../mixins/mixin2";
export default {data() {return {b: 0, // 组件内的变量b};},mounted() {// 组件内不存在这个变量 两个混入模块存在同名变量 最终值取决于模块引用顺序console.log("经过合并后变量a的值是-----", this.a);// 组件内存在这个变量 最终值取组件内的值console.log("经过合并后变量b的值是-----", this.b);},// 使用两个mixin模块 注意先后顺序 决定同名变量的最终取值mixins: [mixin1, mixin2],
}
执行结果:

在这里插入图片描述

​ ② mixins模块中的钩子函数,将与组件内的同名钩子函数合并成一个数组,依次执行,且mixins模块中的钩子函数在组件同名钩子函数之前调用执行。不同名的钩子函数,依旧按照钩子函数的先后顺序执行。

​ 当组件引入多个mixins模块时,如果mixins模块之间存在同名钩子函数,则会按照mixins钩子数组的排列顺序合并成一个数组,排列顺序与执行顺序相同,排序靠前的mixins模块中的同名钩子函数先执行,排序靠后的后执行,最终才会执行组件本身的同名钩子函数。

案例代码:
// 定义一个mixin1.js模块
export default {created: function () { console.log('这里是mixin1模块的created') },
}
// 定义一个mixin2.js模块
export default {created: function () { console.log('这里是mixin2模块的created') },mounted: function () { console.log('这里是mixin2模块的mounted') },
}// 在组件实例中引入并使用定义的mixin模块
// 引入两个mixin模块
import mixin1 from "../mixins/mixin1";
import mixin2 from "../mixins/mixin2";
export default {created() {console.log("这里是组件本身的created");},// 使用两个mixin模块 注意先后顺序 决定同名钩子函数的执行顺序mixins: [mixin1, mixin2],
}
执行结果:

在这里插入图片描述

​ ③ mixins模块中的methodscomponents等值为对象的选项,将会与组件内部的对应选项合并为一个对象,当对象中的键名发生冲突时,则取组件内的键名对应的值。

​ 当组件引入多个mixins模块时,如果mixins模块之间的选项存在同名冲突时,则会按照mixins钩子数组的排列顺序进行覆盖,后面的mixins会覆盖前面的mixins,键名对应的值将取排在最后的mixins模块中对应的值,当然,如果该键名在组件内也存在,则最终还是取组件内的对应的值。

案例代码:
// 定义一个mixin1.js模块
export default {methods: {test() {console.log('这里是mixin1模块methods中的test函数')},test1() {console.log('这里是mixin1模块methods中的test1函数')}},
}
// 定义一个mixin2.js模块
export default {methods: {// 如果mixin模块之间存在键名冲突 则以组件中mixin数组的引用顺序为准// 取排序最后的键名对应的值test1() {console.log('这里是mixin2模块methods中的test1函数')}},
}// 在组件实例中引入并使用定义的mixin模块
// 引入两个mixin模块
import mixin1 from "../mixins/mixin1";
import mixin2 from "../mixins/mixin2";
export default {mounted() {this.test();this.test1();},// 使用两个mixin模块 注意先后顺序 决定键名冲突的最终结果mixins: [mixin1, mixin2],methods: {// 如果mixin模块与组件本身键名冲突 则以组件为最终结果test() {console.log("这里是组件本身methods中的test函数");},},}
执行结果:

在这里插入图片描述

总结:

​ 当一个组件使用了多个mixins时,它们的顺序很重要。因为当mixins之间的选项存在冲突时,后面的mixins会覆盖前面的mixins。而且同名钩子函数的执行顺序也取决于多个mixins的顺序。

​ 当组件与mixins的选项存在冲突时,一切以组件为准。

​ 在使用多个mixins时,记得注意命名冲突问题。

4、全局混入

​ 上面我们举的例子都是在组件中依次引入mixins模块,如果我们想要在多个组件中,甚至是所有组件中都引入某个mixins模块,如果在每个组件中都引入一次,就太过繁琐。此时我们可以使用全局混入特性。

​ 全局混入是指将声明的mixins模块,在main.js文件中的全局Vue实例创建之前,通过Vue.mixin()方法,挂载到Vue上。其作用相当于全局引入了mixins模块,会影响到每一个单独创建的Vue页面实例和组件,因此请慎用该特性!!!

​ 如果全局混入的mixins模块中包含生命周期钩子函数,那么该钩子函数将会根据当前页面做包含的Vue实例数量来决定执行的次数,main.js文件的中的 全局Vue实例也算。

案例代码:
// 定义一个allmixin.js 模块
export default {created: function () { console.log('这里是全局mixin模块的created') },methods: {test() {console.log('这里是全局mixin模块methods中的test函数')}},
}// 在main.js中引入并进行全局混入
import Vue from 'vue'
import App from './App.vue'
import allMixin from './mixins/allMixin'
// 一定要在 new Vue 之前  否则不起作用
Vue.mixin(allMixin)
// 创建全局Vue实例
new Vue({render: h => h(App),
}).$mount('#app')// 此时的页面结构
// mian.js的new Vue -> APP.vue -> test.vue
执行结果:

在这里插入图片描述

5、自定义选项

​ 我们该可以结合this.$options自定义选项来使用全局混入,只有使用自定义选项的组件才会触发相关逻辑,从而局限mixins模块中部分代码的作用范围:

案例代码:
// 定义一个allmixin.js 模块
export default {created: function () {// 自定义选项 并接收传递的值const myOptionValue = this.$options.myOption// 输出传递的值if (myOptionValue) {console.log('-*------', myOptionValue)}},
}// 在main.js中引入并进行全局混入
import Vue from 'vue'
import App from './App.vue'
import allMixin from './mixins/allMixin'
// 一定要在 new Vue 之前  否则不起作用
Vue.mixin(allMixin)
// 创建全局Vue实例
new Vue({render: h => h(App),
}).$mount('#app')// 在组件使用全局混入中自定义的选项
export default {data() {return {}},// 使用自定义选项myOption: "这是我向自定义选项传递的字符串",
}
执行结果:

在这里插入图片描述

mixins模块中的自定义选项在合并时,使用的是默认策略,即简单的覆盖已有的值。当然我们也可以通过Vue.config.optionMergeStrategies来自定义合并逻辑:

// 自定义合并逻辑
Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {// 返回合并后的值
}
// 或者
// 采用现有逻辑 与methods相同
Vue.config.optionMergeStrategies.myOption = Vue.config.optionMergeStrategies.methods

二、provide/inject

1、简介

provide/inject 是Vue在2.2.0版本新增的特性,该特性可以实现祖先组件向其后代组件跨层级传递数据,无论两者中间相隔多少组件层级,相对于传统的props传递方式,减少了传递数据的繁琐操作,提升了代码的可读性和可维护性。该特性与React 框架的上下文特性很相似。

​ 但是过多的使用provide/inject 特性,会增加组件之间的耦合性,降低组件的可复用性,因此使用该特性时要谨慎,不可滥用。而且provideinject的绑定并不是响应式的,传递的数据并不会自动响应数据变化,如果想要响应数据变化,请借助datacomputed

2、provide

provide选项需要在祖先组件中使用,作用是向后代组件传递数据,其选项值为一个对象或一个返回值为对象的函数,对象的属性即为要向其后代组件传递的数据。传递的数据可以是任意类型的数据,如基本类型、对象、函数等等。

provide选项中支持使用 ES2015 Symbols 作为 key,但是只在原生支持 SymbolReflect.ownKeys 的环境下可工作

案例代码:
// provide 的选项值为一个对象
export default {data() {return {}},provide: {a: "这是祖先组件向后代组件传递的字符串数据",b: {c: "这是祖先组件向后代组件传递的对象数据",},f: function () {console.log("这是祖先组件向后代组件传递的函数数据");},},
}// provide 的选项值为一个返回值为对象的函数
export default {data() {return {}},provide() {return {a: "这是祖先组件向后代组件传递的字符串数据",b: {c: "这是祖先组件向后代组件传递的对象数据",},f: function () {console.log("这是祖先组件向后代组件传递的函数数据");},};},
}

3、inject

inject选项是在后代组件中使用,作用是接收祖先组件传递的数据,其选项值为一个字符串数组(推荐)或一个对象。更推荐使用字符串数组的形式,其中数组元素对应的是provide对象中的key,通过this.数组字符串元素的形式来访问祖先组件传递的对应数据;如果使用对象形式,则需要通过键值对来接收数据,键名表示当前组件内的访问名称,value为字符串,对应的是provide对象中的key,通过this.键名的形式来访问祖先组件传递的对应数据。

案例代码:
// inject 的选项值为一个字符串数组(推荐)
export default {data() {return {}},inject: ["a", "b", "f"],
}// inject 的选项值为一个对象(不推荐)
export default {data() {return {}},inject: {a: "a",b: "b",f: "f",},
}// 在后代组件中通过inject接收传递的数据之后 调用传递的数据
mounted() {console.log("inject接收的祖先组件传递过来的字符串数据-----", this.a);console.log("inject接收的祖先组件传递过来的对象数据-----", this.b);console.log("inject接收的祖先组件传递过来的函数数据-----", this.f);
},
执行结果:

在这里插入图片描述

4、进阶知识

① 在Vue的2.2.1版本之后,后代组件中通过inject接收传递的数据,会在propsdata初始化之前得到,因此我们可以使用inject中的数据给propsdata中的数据设置默认值。

export default {inject: ['foo'],props: {a: {default() {return this.foo}}},data() {return {b: this.foo}},
}

② 在Vue的2.5.0 版本之后,我们可以给选项值为对象形式的inject中的数据设置默认值,使其在祖先组件中变成可选项,即在不传递数据时,后代组件依旧能正常工作。from属性设置数据源,default属性设置默认值。

props设置默认值类似,如果直接将非原始值(复杂数据类型)作为默认值,那么它将成为所有子组件实例之间共享的引用,相互之间会产生影响。因此我们需要对非原始值(复杂数据类型)使用一个工厂方法,以便于每次使用默认值时都获得一个新的副本,而不是共享同一个引用。

export default {inject: {// 当组件内名称与祖先组件的key相同时,可省略form属性foo: { default: 'foo' },// 当组件内名称与祖先组件的key不同时,需要通过form属性指定对应的数据bar: {from: 'barFather',default: 'bar'},// 对复杂数据类型使用一个工厂方法arr: {from: 'arr',default: () => [1, 2, 3]},},data() {return {}},
}

三、参考资料

Vue官方文档

ChatGPT

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/12360.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员必备软件,插件,idea常用快捷键--持续更新

1.好用的软件 1.1 截图软件--snipaste 这个软件最好用的就是他可以把截图置顶 1.2 文档查看软件--sublime 他支持多种格式的文件查询,关键是有标第几行 1.3 记笔记软件--语雀 md也在用,为什么选择语雀,因为他支持网页,电脑端,安卓端,苹果端,主要是能放图片 1.4 数据库软件 na…

调取Https接口遇到的坑及解决方式

目录 踩坑的过程 背景 前提 开始排查问题原因 结论 关于Https协议的接口 Java实现调取Https接口方式 1.RestTemplate跳过验证 2.校验方式 3.Forest框架调取接口 参考文档 踩坑的过程 背景 现在有一个平台提供的接口,是Https形式的,但是呢&am…

【NLP】LSTM 唐诗生成器

目标:使用 github 唐诗宋词数据库的 json 数据,训练一共唐诗生成器 数据源:https://github.com/chinese-poetry/chinese-poetry 查看原始数据格式 原始数据包含 作者、正文、标题、id四个部分,这里仅仅使用诗词正文进行训练 …

大力推广 Bard 的谷歌,警告自家员工:慎用 AI 聊天机器人!

整理 | 郑丽媛 出品 | CSDN(ID:CSDNnews) 有了去年 ChatGPT 的领跑后,此后各家科技巨头都陆续在 AI 领域积极布局,其中谷歌的 Bard 更被业界视作 ChatGPT 的有力竞争者。 因此很难想到,Alphabet&#xff0c…

GPT-4测评,大家先别急,图片输入还没来

昨天GPT-4朋友圈刷屏,我更新了一篇小文章,极简罗列GPT-4的一些情报: 1 ChatGPT Plus用户才可试用GPT-4 2 试用阶段每四小时最多100条信息 3 知识库还是2021年 4 上下文长度为8192个token 5 是多模态,但是图片输入仍处于研究预…

chatgpt赋能Python-pythonlabels

Python Labels: 了解Python中标签的作用 Python是一种流行的编程语言,它有着广泛的应用场景。在Python中,标签(Labels)是一个非常重要的概念,可以帮助开发者更好地组织代码和进行调试。本文将介绍Python中的标签&…

dede采集插件自动采集文章图片自定义接口

为什么要用Dede采集插件?如何利用免费Dede采集插件让网站收录以及关键词排名。我们知道,网站结构是seo优化过程中不可忽视的一个非常重要的环节,网站结构分为物理结构和逻辑结构,物理结构一般指的是虚拟空间中很多目录和文件的摆放…

呼吁!少用ChatGPT,多支持开源!

【深度学习革命 - 从历史到未来 Genius Makers: The Mavericks Who Brought AI to Google, Facebook, and the World】这本书里详述了为何西方人工智能界(AI)对于 AI 如此戒慎恐惧,深忧它被少数白人(绝大多数为男性)统…

ChatGPT对未来教育的影响:或将成为奇点

ChatGPT横空出世,不难想象,不久的将来,公司经理只要按一下按钮或者对语音机器人发个指令,就可以将一个粗略的文档转换成优雅的演示文稿,而无需劳烦公司文秘。这无疑颠覆了我们早已熟稔于心的工作场景。 不论是这一次人…

“慎用ChatGPT”!

中国财经报 2023-04-11 4月10日,中国支付清算协会网站发布“关于支付行业从业人员谨慎使用ChatGPT等工具的倡议”,全文如下: 近期,ChatGPT等工具引起各方广泛关注,已有部分企业员工使用ChatGPT等工具开展工作。但是&am…

带你系统的认识CHATGPT

近期CHATGPT火遍全球,各行各业的顶尖人才都在讨论着CHATGPT的发展趋势,中产们都研究着怎么使用CHATGPT产生更大的价值 今天我带大家系统的认识一下CHATGPT. 要说到CHATGPT,我们不得不先介绍一下OPENAI,它是一家人工智能研发公司,CHATGPT是它旗下的产品. OPENAI目前开放的产品有…

与chatGPT神聊,引领你深入浅出系统调用

在操作系统的教学中,系统调用的作用不言而喻,但是,对系统调用常常是雾里看花,似乎明白,又难以真正的触及,即使在代码中调用了系统调用,比如调用fork()创建进程&#xff0…

从零开始开发自己的chatgpt平台 之 SSE(Server-Sent Events)客户端和服务端

提示:如果你认为本文对你有帮助,请点一下关注,后面会有更多人工智能方面的文章。 文章目录 前言一、SSE是什么?二、SSE服务端三、客户端四、SSE双向通信总结 如果有问题可以联系我**:https://gitee.com/xiaoyuren/gpt3…

中国院士称“我国已具备 ChatGPT 发展基础”

中国工程院院士王坚称「我国已具备支撑 ChatGPT 发展的算力基础」,“解好电力行业的关键问题,有可能会引领下一波AI浪潮。”中国工程院院士、阿里云icon创始人王坚2月17日在南方电网总部参加第四届电力调度AI应用大赛时表示。 我认为要开发出chatGPT这样…

Prompt 用法大全!让 ChatGPT 更智能的六种策略(中)

如果遵循以下六种策略来构建 Prompt 提示词,在和 ChatGPT 对话中我们将获得更好、更符合我们要求的回答。 这些策略,后几种更适合在编程调用 ChatGPT API 时使用,不过也适用直接和 ChatGPT 对话,让它更好的理解我们的意图。 1、写…

ChatGPT迎来华人产品负责人Peter Deng

6月1日,ChatGPT新任产品负责人Peter Deng在领英发布动态,宣布正式以“消费者产品副总裁”的身份加入了OpenAI,他写道,“我很高兴能够领导ChatGPT背后杰出的产品、设计和工程团队,目标是让AI对每个人都有用、易获得且有…

第十四届大学生服务外包创新创业大赛总结和心得

前言 比赛已经过去一个多月了,但是当时在为数不多的时间里学东西和完成项目的场景还历历在目,最后我们也获得了省三等的成绩,这对我们五个大一的学生来说已经非常满足了。 比赛介绍 相关连接:服务外包网址 比赛内容&#xff1a…

年薪高达 267 万元,ChatGPT 催生高薪职业,无需编程背景

整理 | 朱珂欣 出品 | CSDN程序人生(ID:coder_life) ChatGPT 的兴起,催生了一个“与众不同”的新职业 —— prompt engineer (提示工程师)。 主要职责是负责为 AI 聊天机器人生成的文本、图片、音频等内…

【关于ChatGPT的30个问题】25、ChatGPT的性能和效果如何?/ By 禅与计算机程序设计艺术

25、ChatGPT的性能和效果如何? 目录 25、ChatGPT的性能和效果如何? ChatGPT的性能涉及的方面 语言模型

ChatGPT专业应用:生成奖项方案

正文共 925 字,阅读大约需要 4 分钟 人力资源等必备技巧,您将在4分钟后获得以下超能力: 生成奖项方案 Beezy评级 :A级 *经过寻找和一段时间的学习,一部分人能掌握。主要提升效率并增强自身技能。 推荐人 | Kim 编辑者…