vue2.x中的provide和inject用法小結(jié)
一、Vue中 常見的組件通信方式可分為三類
父子通信
父向子傳遞數(shù)據(jù)是通過 props,子向父是通過 events($emit); 通過父鏈 / 子鏈也可以通信($parent / $children); ref 也可以訪問組件實例; provide / inject; $attrs/$listeners;
兄弟通信
Bus Vuex
跨級通信
Bus; Vuex; provide / inject、 $attrs / $listeners、
二、provide、inject
1、類型
provide:Object | () => Object inject: Array<string> | { [key: string]: string | Symbol | Object }
2、詳細(xì)
provide 選項應(yīng)該是一個對象或返回一個對象的函數(shù)。該對象包含可注入其子孫的 property。 在該對象中可使用 ES2015 Symbols 作為 key,但是只在原生支持 Symbol 和 Reflect.ownKeys 的環(huán)境下可工作。 inject 選項應(yīng)該是: 一個字符串?dāng)?shù)組,或 一個對象,對象的 key 是本地的綁定名,value 是: 在可用的注入內(nèi)容中搜索用的 key (字符串或 Symbol),或 一個對象,該對象的: from property 是在可用的注入內(nèi)容中搜索用的 key (字符串或 Symbol) default property 是降級情況下使用的 value provide 和 inject 主要在開發(fā)高階插件/組件庫時使用。并不推薦用于普通應(yīng)用程序代碼中。 這對選項是成對使用的。子孫組件想要獲取祖先組件得資源,那么怎么辦呢,總不能一直取父級往上吧,而且這樣代碼結(jié)構(gòu)容易混亂。這個就是這對選項要干的事情。
3、示例
爺組件
<template> <div> <button @click="changeMsg">祖組件觸發(fā)</button> <h1>祖組件</h1> <parent></parent> </div> </template> <script> import parent from './parent.vue'; export default { data(){ return{ obj:{ name:'JavaScript', }, developer:'布蘭登·艾奇', year:1995, update:'2021年06月', } }, provide(){ return { obj: this.obj, // 方式1.傳入一個可監(jiān)聽的對象 developerFn:() => this.developer, // 方式2.通過 computed 來計算注入的值 year: this.year, // 方式3.直接傳值 app: this, // 方式4. 提供祖先組件的實例 缺點:實例上掛載很多沒有必要的東西 比如:props,methods。 } }, components: { parent, }, methods:{ changeMsg(){ this.obj.name = 'Vue'; this.developer = '尤雨溪'; this.year = 2014; this.update = '2021年6月7日'; }, }, } </script>
父組件
<template> <div class="wrap"> <h4>子組件(只做中轉(zhuǎn))</h4> <child></child> </div> </template> <script> import child from './child.vue'; export default { components:{ child, }, } </script>
孫組件
<template> <div> <h5>孫組件</h5> <span>名稱:{{obj.name}}</span> | <span>作者:{{developer}}</span> | <span>誕生于:{{year}}</span> | <span>最后更新于:{{this.app.update}}</span> </div> </template> <script> export default { computed:{ developer(){ return this.developerFn() } }, inject:['obj','developerFn','year','app'], } </script>
對比一下前后差異:無論點擊多少次,孫組件中的誕生于 year 字段永遠(yuǎn)都是1995 并不會發(fā)生變化,通過 方式1、方式2、方式4傳值是可以響應(yīng)的。
正是官網(wǎng)所提到的:provide 和 inject 綁定并不是可響應(yīng)的。這是刻意為之的。然而,如果你傳入了一個可監(jiān)聽的對象,那么其對象的 property 還是可響應(yīng)的。
在孫組件中修改祖組件傳遞過來的值(方式1、方式4),發(fā)現(xiàn)對應(yīng)的祖組件中的值也發(fā)生了變化:
爺組件
<template> <div> <h1>祖組件</h1> <span>名稱:{{obj.name}}</span> | <span>最后更新于:{{update}}</span> <parent></parent> </div> </template> <script> import parent from './parent.vue'; export default { data(){ return{ obj:{ name:'JavaScript', }, update:'2021年06月', } }, provide(){ return { obj: this.obj, app: this, } }, components: { parent, }, } </script>
父組件不變
孫組件
<template> <div> <button @click="changeMsg">孫組件觸發(fā)</button> <h3>孫組件</h3> <span>名稱:{{obj.name}}</span> | <span>最后更新于:{{this.app.update}}</span> </div> </template> <script> export default { inject:['obj','app'], methods: { changeMsg(){ this.obj.name = 'React'; this.app.update = '2020年10月'; } }, } </script>
4、響應(yīng)式
方法一:傳遞的參數(shù)用一個方法返回
// 父組件 data() { return { name: "卷兒" } }, provide: function() { return { newName: () => this.name } // 子組件 inject: ['newName'], computed: { hnewName() { return this.newName() } } <!-- 子組件中的使用方式 --> <h2>{{ hnewName }}</h2> <!-- 推薦使用這種方法 --> <h2>{{ newName() }}</h2>
方法二:把需要傳遞的參數(shù)定義成一個對象
// 父組件 data() { return { obj: { name: "卷兒" } } }, provide: function() { return { // 傳遞一個對象 obj: this.obj } }, // 子組件 inject: ['obj'], computed: { // 也可以不用計算屬性重新定義 objName() { return this.obj.name } } <!-- 子組件中的使用方法 --> <h2>obj的name: {{objName}}</h2> <h2>obj的name: {{obj.name}}</h2>
三、 總結(jié)
慎用 provide / inject
既然 provide/inject 如此好用,那么,為什么 Vue 官方還要推薦我們使用 Vuex,而不是用原生的 API 呢?
答: 前面提到過,Vuex 和 provide/inject 最大的區(qū)別:Vuex 中的全局狀態(tài)的每次修改是可以追蹤回溯的,而 provide/inject 中變量的修改是無法控制的。換句話說,不知道是哪個組件修改了這個全局狀態(tài)。
Vue 的設(shè)計理念借鑒了 React 中的單向數(shù)據(jù)流原則(雖然有 sync 這種破壞單向數(shù)據(jù)流的家伙),而 provide/inject 明顯破壞了單向數(shù)據(jù)流原則。試想,如果有多個后代組件同時依賴于一個祖先組件提供的狀態(tài),那么只要有一個組件修改了該狀態(tài),那么所有組件都會受到影響。這一方面增加了耦合度,另一方面,使得數(shù)據(jù)變化不可控。如果在多人協(xié)作開發(fā)中,這將成為一個噩夢。
在這里,總結(jié)了使用 provide/inject 做全局狀態(tài)管理的原則:
- 多人協(xié)作時,做好作用域隔離;
- 盡量使用一次性數(shù)據(jù)作為全局狀態(tài)
一層嵌套的父子組件可以使用props來傳值,props本身就是有相應(yīng)性的。
根據(jù)自身代碼選擇合適的傳值方式,并不一定非要用provide/inject的傳值。
到此這篇關(guān)于vue2.x中的provide和inject用法的文章就介紹到這了,更多相關(guān)vue2.x provide和inject用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue Router中獲取路由傳遞過來的參數(shù)(方法詳解)
在VueRouter中,可以通過動態(tài)路由匹配和查詢參數(shù)`query`來傳遞參數(shù),并將路由參數(shù)或查詢參數(shù)作為組件的`props`傳遞,動態(tài)路由匹配使用`route.params`訪問參數(shù),查詢參數(shù)使用`route.query`訪問,本文給大家介紹Vue Router中獲取路由傳遞過來的參數(shù),感興趣的朋友一起看看吧2025-02-02Vue 中使用lodash對事件進行防抖和節(jié)流操作
這篇文章主要介紹了Vue 中使用lodash對事件進行防抖和節(jié)流操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07Vue?cli3.0創(chuàng)建Vue項目的簡單過程記錄
Vue CLI是一個基于Vue.js進行快速開發(fā)的完整系統(tǒng),下面這篇文章主要給大家介紹了關(guān)于Vue?cli3.0創(chuàng)建Vue項目的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08