vue專案的一大亮點就是元件化。使用元件可以極大地提高專案中程式碼的複用率,減少程式碼量。但是使用元件最大的難點就是父子元件之間的通訊。
子通訊父
父元件
<template>
<div class="parent">
我是父元件
<!--父元件監聽子元件觸發的say方法,呼叫自己的parentSay方法-->
<!--通過:msg將父元件的資料傳遞給子元件-->
<children :msg="msg" @say="parentSay"></children>
</div>
</template>
<script>
import Children from './children.vue'
export default {
data () {
return {
msg: 'hello, children'
}
},
methods: {
// 引數就是子元件傳遞出來的資料
parentSay(msg){
console.log(msg) // hello, parent
}
},
// 引入子元件
components:{
children: Children
}
}
</script>複製程式碼
子元件
<template>
<div class="hello">
<div class="children" @click="say">
我是子元件
<div>
父元件對我說:{{msg}}
</div>
</div>
</div>
</template>
<script>
export default {
//父元件通過props屬性傳遞進來的資料
props: {
msg: {
type: String,
default: () => {
return ''
}
}
},
data () {
return {
childrenSay: 'hello, parent'
}
},
methods: {
// 子元件通過emit方法觸發父元件中定義好的函式,從而將子元件中的資料傳遞給父元件
say(){
this.$emit('say' , this.childrenSay);
}
}
}
</script>複製程式碼
子元件使用$emit方法呼叫父元件的方法,達到子通訊父的目的。
父通訊子
父元件
<!--Html-->
<template>
<!--父元件觸發click方法-->
<div class="parent" @click="say">
我是父元件
<!--通過ref標記子元件-->
<children ref="child"></children>
</div>
</template>
<script>
import Children from './children.vue'
export default {
data () {
return {
msg: "hello,my son"
}
},
methods: {
// 通過$refs呼叫子元件的parentSay方法
say(){
this.$refs.child.parentSay(this.msg);
}
},
// 引入子元件
components:{
children: Children
}
}
</script>複製程式碼
子元件
<template>
<div class="hello">
<div class="children" >
我是子元件
<div>
父元件對我說:{{msg}}
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
msg: ''
}
},
methods: {
// 父元件呼叫的JavaScript方法parentSay
parentSay(msg){
this.msg = msg;
}
}
}
</script>複製程式碼
父元件通過$refs
呼叫子元件的方法。以上就是父子元件通訊的方式,父子元件傳遞資料直接用props,或者使用$emit
和$refs
依靠事件來傳遞資料。
父子元件通訊提升篇
上文中,子通訊父是在子中觸發點選事件然後呼叫父元件的方法,父通訊子是在父中觸發點選事件呼叫子元件的方法。但是實際情況中可能存在子通訊父時子元件不允許有點選事件而事件在父中或者父通訊子時點選事件在子元件中。
子通訊父時擊事件在父元件
這種情況其實很常見,例如提交一個表單時表單的內容為子元件,而儲存按鈕在父元件上。此時點選儲存按鈕想要獲取子元件表單的值。這種情況下已經不單單是子通訊父和父通訊子了,需要將兩者結合在一起使用才能完成整個通訊過程。
實現的思路是在父元件中點選事件時,先通過父子通訊呼叫子元件的方法,然後在子元件中的該方法裡使用子父通訊呼叫父元件的另一個方法並將資訊傳遞回來。以下是程式碼演示:
父元件
<template>
<div class="parent" @click="getData">
我是父元件
<!--父元件監聽子元件觸發的transData方法,呼叫自己的transData方法-->
<!--通過ref標記子元件-->
<children ref="child" @transData="transData"></children>
</div>
</template>
<script>
import Children from './children.vue'
export default {
data () {
return {
msg: 'hello, children'
}
},
methods: {
getData(){
// 呼叫子元件的getData方法
this.$refs.child.getData();
},
// 引數就是子元件傳遞出來的資料
transData(msg){
console.log(msg) // hello, parent
}
},
// 引入子元件
components:{
children: Children
}
}
</script>複製程式碼
子元件
<template>
<div class="hello">
<div class="children" >
我是子元件
<div>
子元件的資料:{{childrenSay}}
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
childrenSay: 'hello, parent'
}
},
methods: {
// 子元件通過emit方法觸發父元件中定義好的函式,從而將子元件中的資料傳遞給父元件
getData() {
this.$emit('transData' , this.childrenSay);
}
}
}
</script>複製程式碼
另一種情況思路也和這個一樣,基礎就在與父通訊子和子通訊父的靈活運用。轉評贊就是最大的鼓勵