VUE2 组件间传值

概述

常见使用场景可以分为三类:

  • 父子通信:
    • 父向子传递数据是通过 props
    • 子向父是通过 events( $emit )
    • 通过父链 / 子链也可以通信( $parent / $children )
    • ref 也可以访问组件实例;provide / inject API。
  • 兄弟通信:Bus;Vuex;
  • 跨级通信:Bus;Vuex;provide / inject API、 a t t r s / attrs/ attrs/listeners

props/$emit

父组件中的数据在子组件中不能直接使用,要想在子组件中使用,步骤:
1、 父组件中调用子组件时绑定动态属性
2、 子组件中通过props接收父组件中传递过来的数据
3、 在子组件中使用

示例:父组件向子组件传递数据

  • 子组件
<template>
  <div>
    <h1>子组件</h1>
    <h3>插值表达式获取到:{{msg1}}</h3>
    <h3>插值表达式获取到:{{msg2}}</h3>
    <h3>插值表达式获取到:{{msg3}}</h3>
  </div>
</template>
<script>
  export default {
    name: 'Child',
    props: ['msg1', 'msg2', 'msg3']
  }
</script>
  • 父组件:
<template>
  <div>
    <h1>父组件</h1>
    <h-child v-bind:msg1="'来自父组件的数据'"    动态绑定
		:msg2="'data from parent'"   动态绑定的简写形式
		msg3="'data from parent'"   绑定字符串
	></h-child>
  </div>
</template>
<script>
  // 引入子组件
  import HChild from './Child'
  export default {
    name: 'Parent',
    components: {
      HChild
    }
  }
</script>

结果:
在这里插入图片描述

在子组件中使用props除了可以获取父组件的值之外,还可以验证父组件传递到子组件的数据的合法性,还可以获取父组件本身或者调用父组件中的方法。
示例:父组件向子组件传递数据

  • 父组件
<template>
  <div>
    <h1>父组件</h1>
    <h-child v-bind:msg="'来自父组件的数据'"		绑定数据
             :pfun="fun"				绑定方法
             :pComp=this				绑定对象
    ></h-child>
  </div>
</template>
<script>
  // 引入子组件
  import HChild from './Child'
  export default {
    name: 'Parent',
    components: {
      HChild
    },
    methods: {
      fun () {
        console.log('parent fun')
      }
    }
  }
</script>
  • 子组件
<template>
  <div>
    <h1>子组件</h1>
    <h3>插值表达式获取到:{{msg}}</h3>
    <button @click="pfun">调用父组件的方法</button>
    <br>
    <button @click="cfun">获取父组件</button>
  </div>
</template>
<script>
  export default {
    name: 'Child',
    props: {
      msg: {
        type: String,
        default: ''
      },
      pfun: {
        type: Function
      },
      pComp: {
        type: Object
      }
    },
    methods: {
      cfun () {
        console.log(this.pComp)
this.pComp.fun()
      }
    }
  }
</script>
  • 结果
    在这里插入图片描述

示例:子组件向父组件传递数据
子组件向父组件传值一般通过事件触发实现。

  • 子组件
<template>
  <div>
    <h1>子组件</h1>
    <button @click="passMsg">子组件向父组件传值</button>
  </div>
</template>
<script>
  export default {
    name: 'Child',
    methods: {
      passMsg () {
        this.$emit('showMsgEvent', '子组件向父组件传递的值')
      }
    }
  }
</script>
  • 父组件
<template>
  <div>
    <h1>父组件</h1>
    <h3>插值表达式获取到:{{msg}}</h3>
    <h-child  @showMsgEvent="showMsg"></h-child>
  </div>
</template>
<script>
  // 引入子组件
  import HChild from './Child'
  export default {
    name: 'Parent',
    data () {
      return {
        msg: ''
      }
    },
    components: {
      HChild
    },
    methods: {
      showMsg (val) {
        this.msg = val
      }
    }
  }
</script>

结果:
在这里插入图片描述

单击按钮后
在这里插入图片描述

$parent/children

p a r e n t s 是当前组件树的根 V u e 实例。如果当前实例没有父实例,此实例将会是其自己。既然可以获取到组件的实例,那么就可以调用组件的属性或是方法进行操作。换句话说即 p a r e n t s 让我们可以在子组件中访问到父组件的 d a t a 和方法。具体语法为: t h i s . parents是当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。 既然可以获取到组件的实例,那么就可以调用组件的属性或是方法进行操作。换句话说即parents让我们可以在子组件中访问到父组件的data和方法。具体语法为: this. parents是当前组件树的根Vue实例。如果当前实例没有父实例,此实例将会是其自己。既然可以获取到组件的实例,那么就可以调用组件的属性或是方法进行操作。换句话说即parents让我们可以在子组件中访问到父组件的data和方法。具体语法为:this.parent.数据
this.$parent.方法

示例:父组件向子组件传值:子组件主动获取父组件的数据和方法
  • 父组件:
<template>
  <div>
    <h1>父组件</h1>
    <h-child></h-child>
  </div>
</template>
<script>
  // 引入子组件
  import HChild from './Child'
  export default {
    name: 'Parent',
    components: {
      HChild
    },
    data () {
      return {
        msg: 'data from parent'
      }
    },
    methods: {
      fun () {
        console.log('parent fun')
      }
    }
  }
</script>
  • 子组件:
<template>
  <div>
    <h1>子组件</h1>
    <button @click="showParent">调用父组件的数据和方法</button>
  </div>
</template>
<script>
  export default {
    name: 'Child',
    methods: {
      showParent () {
        // 获取到所有的子组件
        console.log(this.$parent)
        // 获取指定子组件中的指定数据
        console.log(this.$parent.msg)
        // 调用子组件的方法
        this.$parent.fun()
      }
    }
  }
</script>

注意:子组件获取父组件中的数据的方法的代码不能直接写在钩子函数mounted中。
结果:
在这里插入图片描述

示例:子组件向父组件传值

  • 子组件:
<template>
  <div>
    <h1>子组件</h1>
  </div>
</template>
<script>
  export default {
    name: 'Child',
    data () {
      return {
        msg: 'msg from child'
      }
    },
    methods: {
      fun () {
        console.log('child fun')
      }
    }
  }
</script>
  • 父组件:
<template>
  <div>
    <h1>父组件</h1>
    <h-child></h-child>
  </div>
</template>
<script>
  // 引入子组件
  import HChild from './Child'
  export default {
    name: 'Parent',
    components: {
      HChild
    },
    mounted () {
      // 获取到所有的子组件,结果是一个数组
      console.log(this.$children)
      // 获取指定子组件中的指定数据
      console.log(this.$children[0].msg)
      // 调用子组件的方法
      this.$children[0].fun()
    }
  }
</script>

注意:

  • $children并不保证顺序,也不是响应式的。使用 $children 来进行数据绑定时,可以考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源
  • $children 是一个数组,是直接儿子的集合,儿子里面有个 _uid 属性,可以知道它是第几个元素,_uid是元素的唯一标识符,根据这个属性,我们可以进行其他的操作
    结果
    在这里插入图片描述

$ref:父组件主动获取子组件的数据和方法

$refs 让我们可以在父组件中进行操作子组件的数据以及方法,使用步骤:

  1. 在父组件中调用子组件时定义一个ref
  2. 在父组件中通过this.$refs.<ref中定义的子组件名>.属性/方法

示例:子组件向父组件传值:

  • 子组件:
<template>
  <div>
    <h1>子组件</h1>
  </div>
</template>
<script>
  export default {
    name: 'Child',
    data () {
      return {
        msg: 'msg from child'
      }
    },
    methods: {
      fun () {
        console.log('child fun')
      }
    }
  }
</script>
  • 父组件:
<template>
  <div>
    <h1>父组件</h1>
    <h-child ref="children"></h-child>
  </div>
</template>
<script>
  // 引入子组件
  import HChild from './Child'
  export default {
    name: 'Parent',
    data () {
      return {
        msg: 'data from parent'
      }
    },
    components: {
      HChild
    },
    mounted () {
      // 获取到所有的子组件,结果是一个对象
      console.log(this.$refs.children)
      // 获取指定子组件中的指定数据
      console.log(this.$refs.children.msg)
      // 调用子组件的方法
      this.$refs.children.fun()
    }
  }
</script>

结果
在这里插入图片描述

兄弟组件之间传值

原理事件广播方式,步骤:
1、 新建一个js文件,然后引入vue并实例化,最后暴露这个实例
2、 在广播和接收广播的组件中都引入上步中定义的实例
3、 通过 e m i t ( ) 广播数据 4 、通过 emit()广播数据 4、 通过 emit()广播数据4、通过on()接收数据

示例:

  • App.vue
<template>
  <div id="app">
    <v-home></v-home>
    <v-news></v-news>
  </div>
</template>
<script>
  import Home from './views/Home';
  import News from './views/News';
  export default {
    name: 'app',
    components:{
      'v-home':Home,
      'v-news':News
    }
  }
</script>
  • 在src/utils目录中创建bus.js文件,代码如下:
import Vue from 'vue';  //1、引入一个空的Vue实例
export default new Vue();   //2、实例化Vue实例并暴露出去
  • Home.vue
<template>
  <div>
    <h2> Home首页 </h2><br>
    <button @click="broadcast2News">给News广播数据</button>
  </div>
</template>
<script>
  import bus from '../utils/bus'
  export default {
    methods: {
      broadcast2News(){//广播数据
        bus.$emit('data2news', '来自Home的数据');
      }
    }
  }
</script>
  • News.vue
<template>
  <div>
    <h2> News头部</h2><br>
  </div>
</template>
<script>
  import bus from '../src/bus'
  export default {
    mounted(){
      bus.$on('data2news',function (shuJu) {
        console.log(shuJu);
      });
    }
  }
</script>

结果:
在这里插入图片描述

a t t r s / attrs/ attrs/listeners:多级组件间传值

  • $attrs:将父组件中不包含props的属性传入子组件,通常配合interitAttrs选项一起使用
  • $listeners:监听子组件中数据的变化,传递给父组件

示例:$attrs
第一步:App.vue

<template>
  <div id="app">
    <h2>最外层组件</h2>
    <!-- 统一传值 -->
    <v-parent :msgA="msg1" :msgB="msg2" :msgC="msg3"></v-parent>
  </div>
</template>
<script>
  // 引入子组件
  import Parent from './views/Parent'
  export default {
    name: 'Parent',
    components: {
      'v-parent': Parent
    },
    data () {
      return {
        msg1: 'aaaaa',
        msg2: 'bbbbb',
        msg3: 'ccccc'
      }
    }
  }
</script>

第二步:Parent.vue

<template>
  <div>
    <h2>中间组件</h2>
    <h-child v-bind="$attrs"></h-child>
  </div>
</template>
<script>
  // 引入子组件
  import HChild from './Child'
  export default {
    name: 'Parent',
    components: {
      HChild
    }
  }
</script>

第三步:Child.vue

<template>
  <div>
    <h2> 数据接收方 </h2><br>
  </div>
</template>
<script>
  export default {
    mounted () {
      console.log(this.$attrs)
    }
  }
</script>

结果:
在这里插入图片描述

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梁云亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值