元件通訊可以分為父子元件通訊、非父子元件通訊,可以是資料的傳遞,也可以是方法的傳遞,先介紹資料的相互傳遞,再介紹方法的相互傳遞。
父元件到子元件傳遞資料:
一、通過props,父元件可以傳遞動態和靜態資料。
//父元件
<template>
<div id="app">
//第一種靜態資料 <HelloWorld msg="我是父元件的資料"/>
//第二種動態繫結 <HelloWorld :msg="message"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
data(){
return{
message: '我來自父元件'
}
},
components: {
HelloWorld
}
}
</script>
複製程式碼
//子元件
<template>
<div class="hello">
來自父元件的值:{{msg}}
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: ['msg']
//或者 props: { msg: String//指定傳入的型別 }
//或者 props: { msg: String,default: '預設值' //指定預設值 }
}
</script>複製程式碼
二、provide / inject
provide 和 inject 主要為高階外掛/元件庫提供用例。並不推薦直接用於應用程式程式碼中。並且這對選項需要一起使用,以允許一個祖先元件向其所有子孫後代注入一個依賴,不論元件層次有多深,並在起上下游關係成立的時間裡始終生效。
//父元件
<template>
<div>
<child-dom>
</child-dom>
</div>
</template>
<script>
import childDom from "./components/ChildDom.vue";
export default {
data() {
return{
}
},
provide: {
house: '房子',
car: '車子',
money: '¥10000'
},
methods:{
},
components:{childDom},
}
</script>複製程式碼
//子元件
<template>
<div>
</div>
</template>
<script>
export default {
data() {
return{
}
},
inject: {
house: {
default: '沒房'
},
car: {
default: '沒車'
},
money: {
default: '¥4500'
}
},
created () {
console.log(this.house, this.car, this.money)
},
methods:{
}
}
</script>
複製程式碼
子元件傳值給父元件
一、通過props的回撥
//父元件
<template>
<div id="app">
<HelloWorld :msg="message"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
data(){
return{
}
},
methods: {
message: (data)=>{
console.log('我是父元件的方法,在子元件中被觸發了')
console.log('來自子元件的值是:'+data)
}
},
components: {
HelloWorld
}
}
</script>複製程式碼
//子元件
<template>
<div class="hello" @click="msg('來自子元件的值~~')">
來自父元件的方法,點我執行
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: ['msg']
}
</script>複製程式碼
二、通過$emit
//父元件
<template>
<div id="app">
<HelloWorld @getData="message"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
data(){
return{
}
},
methods: {
message: (data)=>{
console.log('來自子元件的值是:'+data)
}
},
components: {
HelloWorld
}
}
</script>複製程式碼
//子元件
<template>
<div class="hello" @click="goFun">
點選傳值給父元件
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data(){
return{
s: 1111
}
},
methods: {
goFun(){
this.$emit('getData',this.s)
}
}
}
</script>複製程式碼
三、.sync修飾實現雙向繫結
//父元件
<template>
<div id="app">
<HelloWorld :show.sync='valueChild'/>
父元件值:{{valueChild}}
<button @click="changeValue">點選</button>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
data(){
return{
valueChild:true
}
},
methods: {
changeValue(){
console.log('父元件的值被修改:'+this.valueChild)
this.valueChild =!this.valueChild
}
},
components: {
HelloWorld
}
}
</script>複製程式碼
//子元件
<template>
<div>
<div>
<p>子元件值:{{show}}</p>
<button @click.stop="closeDiv">修改</button>
</div>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
methods: {
closeDiv() {
this.$emit('update:show', !this.show); //觸發 input 事件,並傳入新值
}
},
props:['show']
}
</script>複製程式碼
關係型元件跨級傳遞(根元件、兒子元件、孫子元件)
一、使用 $attrs 和 $listeners
通過 $attrs 將值連續往下傳遞(和props傳遞類似),傳遞過程中可以只選擇當前需要的值,元件中可以通過 inheritAttrs:false 保持當前元件的屬性純淨度。通過 $listeners 可以在(…子元件)中 this. $emit(“upRocket”,11111)來觸發父元件中的事件,從而達到傳值給父元件的目的。
//父元件
<template>
<div>
<child-dom
:foo="foo"
:coo="coo"
@upRocket="reciveRocket"
>
</child-dom>
</div>
</template>
<script>
import childDom from "./components/ChildDom.vue";
export default {
data() {
return {
foo:"Hello, world",
coo:"Hello,rui"
}
},
methods:{
reciveRocket(data){
console.log("我是根元件,這是接受的孫子元件的資料"+data)
}
},
components:{childDom},
}
</script>複製程式碼
//子元件
<template>
<div>
<p>foo:{{foo}}</p>
<childDomChild v-bind="$attrs" v-on="$listeners"></childDomChild>
</div>
</template>
<script>
import childDomChild from './childDomChild';
export default {
name:'child-dom',
props:["foo"],
inheritAttrs:false,
components:{childDomChild}
}
</script>複製程式碼
//孫子元件
<template>
<div>
<p>coo:{{coo}}</p>
<button @click="startUpRocket">傳送資料到根元件</button> </div>
</template>
<script>
export default {
name:'child-dom',
props:["coo"],
methods: {
startUpRocket() {
this.$emit("upRocket");
}
}
}
</script>複製程式碼
二、$parent $children
其實通過 $ r e f 可以獲取到子元件中的一些掛載屬性和值, 父元件如果要獲取子元件的方法可以通過this.$refs.mychild.funName("…");這種方式,給子元件指定ref名稱。同理,通過 $parent $children可直接運算元據和方法。
- this. $parent查詢當前元件的父元件。
- this.$children查詢當前元件的直接子元件,可以獲取到全部直接子元件, 需要注意$children 並不保證順序,也不是響應式的。可以通過this.$root.$children[0].$children[0].$children[0].msg連續查詢
- this.$root查詢根元件,並可以配合$children遍歷全部元件
//父元件
<template>
<div>
父元件的值:{{msg}}
<child-dom>
</child-dom>
<button @click="change">父元件點選修改</button>
</div>
</template>
<script>
import childDom from "./components/ChildDom.vue";
export default {
data() {
return{
msg: 0
}
},
methods:{
change(){
this.msg = this.$children[0].childMsg
this.$children[0].childMsg = '子元件的值被父元件修改了'
}
},
mounted(){
},
components:{childDom},
}
</script>複製程式碼
//子元件
<template>
<div>
子元件的值:{{childMsg}}
<button @click="decrease()">子元件點選修改</button>
</div>
</template>
<script>
export default {
name:'child-dom',
data() {
return {
childMsg : 111
};
},
methods: {
decrease() {
this.childMsg = this.$parent.msg
this.$parent.msg = "子元件修改了父元件的值"
}
}
}
</script>複製程式碼
非關係元件傳值
一、EventBus
適用於小型專案,可以達到任意元件相互通訊的效果
//元件a
<template>
<div>
{{fontCount}}
<child-dom>
</child-dom>
</div>
</template>
<script>
//import Vue from 'vue' //export const EventBus = new Vue()
import { EventBus } from "./assets/bus.js";
import childDom from "./components/ChildDom.vue";
export default {
data() {
return{
fontCount: 0
}
},
methods:{
},
mounted(){
EventBus.$on("decreased", ({num}) => {
this.fontCount -= num
});
},
components:{childDom},
}
</script>複製程式碼
//元件b
<template>
<div>
<button @click="decrease()">-</button>
</div>
</template>
<script>
import { EventBus } from "../assets/bus.js";
export default {
name:'child-dom',
data() {
return {
num: 1,
deg:180
};
},
methods: {
decrease() {
EventBus.$emit("decreased", {
num:this.num
});
}
}
}
</script>複製程式碼
二、vuex