【Vuejs】1025- Vue 組件通信的 8 種方式
前言
?做了半年的公司系統(tǒng),終于就在前天上線了。后期改BUG時間拖得太長了,出現(xiàn)的大部分BUG 是 前端 與后端 信息不對稱導(dǎo)致的,邏輯性錯誤不怎么多,業(yè)務(wù)比較用戶體驗上稍微差點,畢竟第一次做這么大的系統(tǒng)(100w+),通過這次系統(tǒng)的開發(fā),總結(jié)了不少經(jīng)驗,如何更好的跟后端人員協(xié)作開發(fā)以及如何設(shè)計來提高用戶體驗上,之前自己做開發(fā)沒關(guān)注這方面,只注重功能實現(xiàn),后期的這塊多補補。
?
項目上線后,接下來就是后期的維護更新了,最近時間終于不是之前那么忙碌了,簡單的對系統(tǒng)做了下復(fù)盤。由于項目采用的技術(shù)棧是Vue, 平常開發(fā)只注重功能實現(xiàn)了,接下來陸續(xù)會對Vue深入分析,來封裝常用業(yè)務(wù)組件,以及Vue源碼解析
本章將是對Vue 組件通信的8方法總結(jié),日常開發(fā)使用組件通信非常密切,熟悉組件通信可以更好的開發(fā)業(yè)務(wù)。

Vue 組件之間傳值
1. 父組件 向 子組件 傳遞值
?
在父組件中引入子組件
注冊子組件
在頁面中使用,子組件標簽上 動態(tài)綁定傳入動態(tài)值 / 靜態(tài)值
在子組件中,使用 props來接受父組件傳遞過了的值「子組件接收的父組件的值分為引用類型和普通類型兩種:」
?
「普通類型:字符串(String)、數(shù)字(Number)、布爾值(Boolean)、空(Null)」 「引用類型:數(shù)組(Array)、對象(Object)」
#父組件
<template>
<div>
<!-- 傳遞值 -->
<Test
:obj="obj"
info="測試"/>
</div>
</template>
<script>
// 引入子組件
import Test from "../components/Test.vue";
export default {
name: "about",
// 注冊子組件
components: {
Test,
},
data() {
return {
obj: {
code: 200,
title: "前端自學(xué)社區(qū)",
},
};
},
};
</script>
<template>
<div>
<h1>{{obj.code}}</h1><br>
<h2>{{obj.title}}</h2>
<h3>{{info}}</h3>
</div>
</template>
<script>
export default {
name:'test',
props:{
obj:Object,
info: [String,Number] //info值為其中一種類型即可,其他類型報警告
}
}
</script>
?由于
?Vue是 單向數(shù)據(jù)流,子組件是不能直接 修改父組件的 值。
2. 子組件 向父組件傳遞值
?子組件通過綁定事件,通過
?this.$emit('函數(shù)名',傳遞參數(shù))
#父組件
<Test
:obj="obj"
info="測試"
@modify="modifyFatherValue"/>
<script>
// 引入子組件
import Test from "../components/Test.vue";
export default {
name: "about",
// 注冊子組件
components: {
Test,
},
data() {
return {
msg:'我是父組件'
};
},
methods:{
// 接受子組件傳遞來的值,賦值給data中的屬性
modifyFatherValue(e){
this.msg = e
}
}
};
</script>
# 子組件
<button @click="modifyValue">修改父組件的值</button>
<script>
export default {
name:'test',
methods:{
modifyValue(){
this.$emit('modify','子組件傳遞過來的值')
}
}
}
</script>
3. 父組件 通過 $refs / $children 來獲取子組件值
?
$refs:
獲取DOM 元素 和 組件實例來獲取組件的屬性和方法。 通過在 子組件 上綁定 ref,使用this.$refs.refName.子組件屬性 / 子組件方法
$children:?
當前實例的子組件,它返回的是一個子組件的集合。如果想獲取哪個組件屬性和方法,可以通過 this.$children[index].子組件屬性/f方法
示例 Text 組件
<script>
export default {
name:'test',
data() {
return {
datas:"我是子組件值"
}
},
props:{
obj:Object,
info: [String,Number]
},
methods:{
getValue(){
console.log('我是Test1')
}
}
}
</script>
示例 Text2組件
<template>
<div>
<h1>我是Test2</h1>
</div>
</template>
<script>
export default {
name:'test',
data() {
return {
datas:"我是Test2"
}
},
created(){
console.log( this.$parent.obj )
this.$parent.getQuery()
},
methods:{
getTest2(){
console.log(this.datas)
}
}
}
</script>
refs
<template>
<div>
// 給子組件上綁定 ref
<Test
ref="son"
/>
<Test2/>
</div>
</template>
// 通過 $refs 示例來獲取 子組件的屬性和方法
console.log( this.$refs.son.datas)
this.$refs.son.getValue()
$children
// 通過 $children 來獲取 子組件的屬性和方法
this.$children[0].getValue(); // 我是 Test1
this.$children[1].getTest2(); //我是 Test2
console.log(`---------${this.$children[1].datas}`); //我是Test2
4. 子組件 通過 $parent 來獲取父組件實例的屬性和方法
<script>
export default {
name:'test',
created(){
console.log( this.$parent.obj )
this.$parent.getQuery()
},
}
</script>
5. $attrs 和 $listeners 獲取父組件實例屬性和方法(組件嵌套情況下使用)
?「
$attrs」:包含了父作用域中不被認為 (且不預(yù)期為)props的特性綁定 (class 和 style 除外),并且可以通過 v-bind=”$attrs” 傳入內(nèi)部組件。當一個組件沒有聲明任何props時,它包含所有父作用域的綁定 (class 和 style 除外)。「
$listeners」:包含了父作用域中的 (不含 .native 修飾符) v-on 事件監(jiān)聽器。它可以通過 v-on=”$listeners” 傳入內(nèi)部組件。它是一個對象,里面包含了作用在這個組件上的所有事件監(jiān)聽器,相當于子組件繼承了父組件的事件。使用場景:多層嵌套組件的情況下使用,可以避免使用Vuex來做數(shù)據(jù)處理, 使用
?v-bind="$attrs" v-on="$listeners"很方便達到業(yè)務(wù)數(shù)據(jù)傳遞。
父組件
<template>
<div>
<Test3
:status="status"
:title="title"
@getData="getData" />
</div>
</template>
<script>
import Test3 from "../components/Test3.vue";
export default {
name:'person',
data(){
return {
title:'personal 組件',
status: false
}
},
methods:{
getData(){
console.log(this.title)
}
},
components:{
Test3
}
}
</script>
子組件1
<template>
<div>
<h1>Test3 組件</h1>
<br /><br />
// 通過 $attrs(屬性,除了【props中定義的屬性】) 和 $listeners(方法) 來給嵌套子組件傳遞父組件的屬性和方法
<Test4 v-bind="$attrs" v-on="$listeners"/>
</div>
</template>
<script>
// 引入子子組件
import Test4 from "../components/Test4";
export default {
name: "test3",
props: ["title"],
components: {
Test4,
},
created() {
console.log(this.$attrs); //{status: false}
console.log("-----------");
console.log(this.$listeners); // {getData: ?}
},
};
</script>
嵌套子組件
<template>
<div>
<h1>Test4 組件</h1>
</div>
</template>
<script>
export default {
name:'test4',
created(){
console.log('-----Test4------')
console.log(this.$attrs) //{status: false}
console.log(this.$listeners) // {getData: ?}
}
}
</script>
6. 跨組件之間傳值
?通過新建一個
js文件,導(dǎo)入vue, 導(dǎo)出vue實例;然后通過 給導(dǎo)出的實例 上綁定事件$emit事件 , 然后再通過$on監(jiān)聽觸發(fā)的事件,這樣就可以達到全局組件數(shù)據(jù)共享。使用場景:
它可以滿足任意場景傳遞數(shù)據(jù),
父子組件傳值,子父傳值,兄弟組件之間傳值,跨級組件之間傳值.通信數(shù)據(jù)比較簡單時,可以采用這種 方案,項目比較龐大,可以采用
?Vuex.
vue .js
/*
* @Description:
* @Author: ZhangXin
* @Date: 2021-01-22 15:48:56
* @LastEditTime: 2021-01-22 15:51:24
* @LastEditors: ZhangXin
*/
import Vue from 'vue'
export default new Vue()
組件A
<!--
* @Description:
* @Author: ZhangXin
* @Date: 2021-01-22 14:44:17
* @LastEditTime: 2021-01-22 16:25:33
* @LastEditors: ZhangXin
-->
<template>
<div>
<button @click="changeValue">改變</button>
</div>
</template>
<script>
import zxVue from '../util/newVue.js';
export default {
name:'person',
data(){
return {
title:'personal 組件',
status: false
}
},
methods:{
changeValue(){
// 通過給 vue實例綁定事件
zxVue.$emit("getTitle", this.title)
}
}
}
</script>
組件C
<!--
* @Description:
* @Author: ZhangXin
* @Date: 2021-01-22 15:07:30
* @LastEditTime: 2021-01-22 16:26:38
* @LastEditors: ZhangXin
-->
<template>
<div>
<h1>Test4 組件</h1>
<h1>{{ title }}</h1>
</div>
</template>
<script>
import zxVue from "../util/newVue";
export default {
name: "test4",
data() {
return {
title: "test4",
};
},
mounted(){
// 通過 vue 實例.$on 監(jiān)聽事件名,來接收跨級組件傳遞過來的值
zxVue.$on("getTitle", (item) => {
this.title = item;
console.log(item)
});
}
};
</script>
7. Vuex
?這里就不介紹了,完了單獨寫一篇文章精講
?Vuex
8. provide 和 inject 實現(xiàn)父組件向子孫孫組件傳值。(層級不限)
?
provide和inject這對選項需要一起使用,以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,并在起上下游關(guān)系成立的時間里始終生效。
provide:
是一個對象或返回一個對象的函數(shù) 該對象包含可注入其子孫的屬性。
inject:
是一個字符串數(shù)組 或者是一個對象 用來在子組件或者子孫組件中注入 provide提供的父組件屬性。使用場景:
?
provide/inject可以輕松實現(xiàn)跨級訪問父組件的數(shù)據(jù)
# provide
//對象
provide:{
name:'測試'
}
//返回對象的函數(shù)
provide(){
return {
name: '測試'
}
}
#inject
inject:['name']
父組件
<!--
* @Description:
* @Author: ZhangXin
* @Date: 2021-01-22 23:24:16
* @LastEditTime: 2021-01-22 23:49:50
* @LastEditors: ZhangXin
-->
<template>
<div>
<h1>我是父組件</h1>
<Son />
</div>
</template>
<script>
import Son from '../components/son/SonOne'
export default {
name:'father',
provide(){
return {
titleFather: '父組件的值'
}
},
components:{
Son
},
data(){
return{
title:'我是父組件 '
}
},
}
</script>
子組件
<template>
<div>
<h1>我是子孫組件</h1>
</div>
</template>
<script>
import SonTwo from '../son/SonTwo'
export default {
name:'sonone',
components:{
SonTwo
},
inject:['titleFather'],
created(){
console.log(`${this.titleFather}-----------SonTwo`)
},
data(){
return{
title:'我是子組件 '
}
},
}
</script>
子孫組件
<template>
<div>
<h1>我是子孫組件</h1>
</div>
</template>
<script>
import SonTwo from '../son/SonTwo'
export default {
name:'sonone',
components:{
SonTwo
},
inject:['titleFather'],
created(){
console.log(`${this.titleFather}-----------SonTwo`)
},
data(){
return{
title:'我是子組件 '
}
},
}
</script>

回復(fù)“加群”與大佬們一起交流學(xué)習~
點擊“閱讀原文”查看 120+ 篇原創(chuàng)文章
