vue-cli3父子组件传值
通常父子组件之间是需要相互传数据的
一、父组件向子组件传数据
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>



浙公网安备 33010602011771号