多层组件传值$listeners/$attrs和获取组件$ parent/$root/$children/$refs

多层组件传值

在组件中传值,在父子级组件很好就实现了,但是如果第一层的组件向第六层或者更高的层次传值时,我们就非常难办了,在我们以前学习的知识来实现。我们只有将通过给每个组件中设置属性,来依次接收它的父组件传给它的值;当我们需要向第一层传回数据时,我们又要给每个组件设置自定义事件,依次传递。可见非常的麻烦,所以提供了多层传值的方法。

$listeners和$attrs

使用方法非常简单只需要在路过的组件上v-bind="$attrs"  v-on="$listeners"

我们来三个组件来演示父组件向孙组件传数据,孙数据向父组件传数据。

box2孙组件代码:创建属性来接收爷爷组件传来的数据,创建自定义事件向爷爷组件传值

<template>
    <div class="box2">
        <h3>box3组件</h3>
        <p>{{title}}</p>
        <button @click="fn">点击修改爷爷组件数据</button>
    </div>
</template>
<script>
    export default{
        props:["title"],
        methods: {
            fn(){
              this.$emit("updategrand",this.msg)
            }
        },
        data() {
            return {
                msg:"我是孙组件的数据"
            }
        },
    }
</script>
<style>
.box2{
    width: 100px;
    height:150px;
    background-color: yellow;
}
</style>

box1父组件:就是起着一个桥梁的作用。

<template>
    <div class="box1">
        <h2>box1组件</h2>
        <!-- box1也可以获取传递的数据使用 -->
        <div>{{$attrs.title}}</div>
        <Box2 v-bind="$attrs" v-on="$listeners"></Box2>
    </div>
</template>
<script>
import Box2 from "./box2.vue"
    export default{
       components:{
        Box2
       },
    }
</script>
<style>
    .box1{
        width: 200px;
        height:200px;
        background-color: aqua;
    }
</style>

App爷爷组件,接收自定义事件传来的值,并向孙子组件传值

<template>
  <div class="app">
    <h1>app父组件</h1>
    <div>{{this.msg}}</div>
    <Box1 :title="msg" @updategrand="fm"></Box1>
  </div>
</template>

<script>
import Box1 from "@/components/box1.vue"
export default {
  data() {
    return {
      msg:"爷爷组件的数据"
    }
  },
  components:{
    Box1
  },
  methods: {
    fm(arg){
      this.msg=arg
    }
  },
}
</script>

<style>
  .app{
    width: 300px;
    height: 400px;
    background-color: aquamarine;
  }
</style>

页面效果:

 点击按钮后:

 

 获取组件

尽管框架为我们提供了多层组件传值的方法,但是我们还是要一层一层的去配置v-bind="$attrs"和v-on="$listeners"。

这里讲解一种更加方便的方式,就像以前学习JS的DOM时获取父节点、子节点们。

我们组件也可以获取,Vue为我们提供了四个获取组件的方法:

$parent:获取父组件对象,可直接操作父组件的data数据,不需要再使用属性传值,但是容易出现渲染混乱之后只渲染一个的情况;

$children:获取子组件们,返回的是一个数组,不能保证顺序,也不是响应式的;

$root:获取根组件;

$refs:可以在组件或者原生元素绑定ref属性(类似于id),在通过$refs来获取对应的组件或元素节点,只会在组件渲染完成之后生效,并且它们不是响应式的。你应该避免在模板或计算属性中访问 $refs。

我们来用一用,我们在上面box1组件中来依次在控制台都打印一下:

代码:

<template>
    <div class="box1">
        <h2>box1组件</h2>
        <!-- box1也可以获取传递的数据使用 -->
        <div>{{$attrs.title}}</div>
        <Box2 v-bind="$attrs" v-on="$listeners" ref="tt1"></Box2>
    </div>
</template>
<script>
import Box2 from "./box2.vue"
    export default{
       components:{
        Box2
       },
       mounted() {
        console.log(this.$parent);
        console.log(this.$root);
        console.log(this.$children);
        console.log(this.$refs.tt1);
       },
    }
</script>
<style>
    .box1{
        width: 200px;
        height:200px;
        background-color: aqua;
    }
</style>

当页面渲染完成时控制台的打印情况:

 可见都成功获取了,而且它们就是DOM操作时一样可以连调,如box1组件对象.$parent.$parent就可以得到其的爷爷组件对象。

当我们获取到了对应的组件对象就可以操作组件内的数据。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值