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>

 

 

posted @ 2021-01-27 18:21  python界泥石流  阅读(946)  评论(0编辑  收藏  举报