通常父子組件之間是需要相互傳數據的
一、父組件向子組件傳數據
1,父組件App.vue傳遞menus數組給子組件的menu
<!-- 父級往子級傳值步驟:
1.在子組件的屬性(props)驗證-->
2.給父組件的子組件標簽設置並綁定自定義屬性
(首先在子組件中驗證屬性,屬性名隨意,想要一個數組在li標簽中遍歷;接下來在父組件的子組件標簽中自定義屬性(屬性名與子組件驗證屬性名必須相同))
<template> <div id="app"> <Vheader></Vheader>
<!-- // 自定義標簽,可以自定義一個menu屬性,然后自定義綁定它(id、class、title是系統提供的屬性,menu是自定義屬性);'menus'是數組,即綁定數組 ;
即當前Vcontent組件有menu屬性了--> <!-- Vcontent組件怎么拿到menu屬性?(即需要父組件往子組件傳值,傳值約定:必須驗證props!!) --> <Vcontent:menu ='menus'></Vcontent> 通過使用v-bind綁定子組件的menu屬性,將menus數組傳遞給子組件
<!-- 將audio、ul、h3標簽移至Vcontent.vue中 --> <!-- <audio :src="audioSrc" autoplay="autoplay" controls=""> </audio> <ul> <li v-for='(item,index) in menus'> {{item}} </li> </ul> --> <!-- <h3>猛哥噸噸</h3> --> </div> </template> <script> import audio1 from'./assets/1.mp3' import Vheader from './components/Vheader.vue'
//導入子組件 import Vcontent from './components/Vcontent.vue' export default{ name:'App', data(){ return{ menus:['宮保雞丁','紅燒肉','酸辣湯'], //移至Vcontent.vue中 audioSrc:audio1 } }, components:{ Vheader,
//掛載子組件 Vcontent } } </script> <style scoped> </style>
2,子組件Vcontent.vue使用menu屬性接受父組件傳遞的menus
<template>
<div class="content">
<!-- <audio :src="audioSrc" autoplay="autoplay" controls=""> </audio> -->
<ul>
<!-- ???為什么將menus改成menu -->
<li v-for='(item,index) in menus'>
{{item}}
</li>
</ul>
<h3>猛哥噸噸</h3>
</div>
</template>
<script>
// 拋出整個組件
export default {
name:'Vcontent',
data(){
return{
// 為什么menus數據不放在Vcontent.vue子組件中,放在App.vue父組件中?
// 想要實現一開始加載項目時,App.vue就可以把數據拿到,即App.vue拿到后端數據,然后通過vue提供父子傳值的功能,數將據從App.vue里邊傳到子組件中
// 好處:子組件很多,一開始就把數據請求出來,分發各個子組件
// menus:['宮保雞丁','紅燒肉','酸辣湯'],
// audioSrc:audio1
//this指的是當前組件(Vcontent)的實例化vue對象,即每個組件的this都是不同的,即當前this拿不到App.vue里邊的東西
menus:this.menu
}
},
// 父子傳值,屬性(props)必須驗證
// 為什么驗證?
// 傳的值可以是字符串、數組、對象等,組件需要驗證一下傳的什么值
// 屬性是對象,對象里面有k:value,
props:{
// 此次傳來的menu1是數組
menu:Array
}
}
</script>
<style scoped>
</style>

二、子級往父級傳值
1.在子組件中觸發自定義事件 (傳值:字符串、數組、對象、數值、number)
this.$emit('自定義的事件名',傳值)
注:綁定到當前vue實例化對象里邊的屬性和事件前邊都要加一個$,$emit是vue內部提供的方法,
2.在父組件的子組件標簽中設置自定義事件
<Vheader @addMenu = 'addHandler'></Vheader>
addMenu:自定義事件名
addMenu等號后邊對應的addHandler:在當前組件中methods里邊聲明的事件
...
methods:{ addHandler(value){ alert(value);
///value就是傳過來的參數 this.menus.push(value); } },
子組件是通過事件向父組件傳遞數據,分如下兩種情況:
1.直接由當前Vcontent組件將'酸菜魚'傳到父組件App.vue的menus中,實現向數組中添加酸菜魚-->
<template>
<div class="content">
<!-- <audio :src="audioSrc" autoplay="autoplay" controls=""> </audio> -->
<ul>
<!-- Vue強烈建議我們在組件里邊用v-for遍歷時,加一個綁定的key,
<! ???為什么將menus改成menu -->
<li v-for='(item,index) in menus' :key = 'index'>
{{item}}
</li>
</ul>
<h3>猛哥噸噸</h3>
<!-- 如何將酸菜魚添加到數組中 -->
<!--1. 直接由當前Vcontent組件將'酸菜魚'傳到父組件App.vue的menus中,實現向數組中添加酸菜魚-->
<!--點擊button之后,調用addOneMenu函數,this.menu可以直接拿到父組件App.vue的數組,push('酸菜魚')之后,push的是menu菜單,
即自定義屬性,menu變化意味着Vcontent標簽中的menu屬性變化,意味着menus變化,即意味着data中menus數組變化,即li標簽中的menus變化,
接着v-for重新遍歷,將酸菜魚添加到當前Vcontent組件的列表中;為了證明酸菜魚是否也可以添加到父組件App.vue的menus中,
我們在父組件App.vue中也添加相同的li標簽,點擊按鈕之后,父組件App.vue的列表中也出現了酸菜魚,有一種響應式的綁定,
即可以直接在子組件Vcontent中向父組件App.vue的數組menus中添加值,即子傳父 -->
<button @click = 'addOneMenu'>添加</button>
</div>
</template>
<script>
// 拋出整個組件
export default {
name:'Vcontent',
data(){
return{
menus:this.menu
}
},
methods:{
addOneMenu(){
this.menu.push('酸菜魚')
}
},
props:{
menu:Array
}
}
</script>
<style scoped>
</style>
2.如何實現在Vheader組件中點擊button按鈕提交將菜單添加到Vcontent組件中(實現在其他組件中向父組件提交然后添加到Vcontent組件中)
點擊提交按鈕后,觸發addOneMenu函數,由this.$emit('addMenu','傳值')觸發一個addMenu自定義事件,接着傳值;接下來子組件中需要有一個addMenu這樣的自定義事件名;接下來需要在父組件中找關系,然后在父組件的子組件標簽中自定義事件名addMenu(必須與this.$emit的相同),addMenu等號后邊對應的addHandler方法是在當前組件中觸發的事件
<template>
<div class="header">
<h3>{{msg}}</h3>
<img :src="logoSrc" alt="">
<!--2.如何實現在Vheader組件中點擊button按鈕提交將菜單添加到Vcontent組件中(實現在其他組件中向父組件提交)-->
<!-- 點擊button按鈕后,觸發addOneMenu函數,但是this.menu拿不到菜單,沒有返回值;又Vheader和Vcontent是同級兄弟關系,兩個都連接着App.vue,
因此我們可以把數據由Vheader傳到App.vue(子傳父),在由App.vue傳到Vcontent中(父傳子),我們在Vheader中提交,把數據提交到App.vue,
然后通過父傳子傳給Vcontent
2.1.點擊button按鈕之后,調用addOneMenu函數,接着由
this.$emit('自定義事件的名字','要傳的值')觸發自定義事件;
2.2.觸發App.vue中Vheader標簽的自定義事件addMenu,並傳值(酸菜魚)給addHandler函數,this.menus.push(酸菜魚)添加至menus數組
2.3.data中menus數組多一個酸菜魚(即menus變化),然后觸發<Vcontent :menu ='menus'></Vcontent>的menu屬性傳值(props:{menu:Array}),
然后data函數menus中變化,最后至li標簽menus變化,接着v-for重新遍歷,將酸菜魚添加到Vcontent組件的列表中-->
<button @click = 'addOneMenu'>添加</button>
</div>
</template>
<script>
import logoSrc from '../assets/logo.png'
export default {
name:'Vheader',
data(){
return{
msg:'hello 組件結構',
logoSrc:logoSrc
}
},
methods:{
addOneMenu(){
// this.$emit('自定義事件的名字','要傳的值')可以觸發自定義事件
this.$emit('addMenu','酸菜魚');
}
}
}
</script>
<style scoped>
h3 {
color: yellow;
}
</style>
父組件App.vue
<template> <div id="app"> <!-- 子傳父: --> <!-- 1.首先要先自定義事件,通過自定義事件向父級傳值;Vheader可以自定義屬性,也可以自定義事件 2.給自定義事件命名addMenu(即addMenu為自定義事件名字),后邊''中也要對應一個事件,為addHandler,接着addHandler要在methods中聲明,
this.menus.push(value)就可以向menus數組添加數據,value是要添加的數據,也是子向父傳的值--> <Vheader @addMenu = 'addHandler'></Vheader> <Vcontent :menu ='menus'></Vcontent> </div> </template> <script> import audio1 from'./assets/1.mp3' import Vheader from './components/Vheader.vue' import Vcontent from './components/Vcontent.vue' export default{ name:'App', data(){ return{ menus:['宮保雞丁','紅燒肉','酸辣湯'], } }, methods:{ addHandler(value){ // alert(value) this.menus.push(value); } }, components:{ Vheader, Vcontent } } </script> <style scoped> </style>


