Vue.js进阶系列(8)--组件访问之父访子

  啥东西?怎么又来个父子组件的访问了?跟前几天的通信难道不是一回事儿?没错,他们确实不是一回事儿,通信主要是传递数据的,而访问是直接拿数据来操作。拿飞鸽传书做例子,通信就像鸽子,是用来传递信件的,而访问就像是收件人,是用来看信件并且写信的。
也是和通信一样,涉及到父组件访问子组件子组件访问父组件两种类型,今天小编就分享父组件访问子组件的两种方式。

一、通过$children

  children是复数,就意味着父组件通过children拿到的可能不止一个子组件,因为在Vue中明文规定是可以让父组件拥有一个或者多个子组件的。就像是二胎政策的开放,国家已经规定夫妻间可以拥有多个孩子一样。
  所以如果父组件通过$children拿到子组件的对象,一定要具体到是哪一个孩子。就像你父母在叫孩子的时候,一定会叫特殊昵称一样。下面小编为你们展示如何通过children访问子组件,先看下面的基础代码:

    <body>
        <div class="warp">
            <cnp></cnp>
            <button>按钮</button>
        </div>
        <template id="tmp">
            <div>
                <h2>我是子组件</h2>
            </div>
        </template>
        <script>
            var vm = new Vue({
                el:".warp",
                data:{
                    
                },
                components:{
                    cnp:{
                        template:"#tmp",
                        methods:{
                            showMessage(){
                                alert('我是通过$children访问的函数')
                            }
                        }
                    }
                }
            })
        </script>
    </body>

  子组件cnp为局部组件,并且有一个showMessage的方法,当调用这个方法就会弹出对话框。父组件依旧是我们的Vue老大,模板中有子组件cnp和按钮两个小老弟。
  下面小编希望当点击按钮的时候就通过$children来访问子组件中的showMessage方法。很明显,首先要为button绑定点击事件,然后在点击事件内部通过children来访问子组件中的showMessage方法。

// 为按钮绑定点击事件
<div class="warp">
    <cnp></cnp>
    <button @click="btnClick">按钮</button>
</div>
//在Vue老大的method方法中处理btnClick事件
methods:{
    btnClick(){
        console.log(this.$children);
        this.$children[0].showMessage()
    }
}

我们先来看看它到底是个啥玩意儿:

$children是这玩意儿.png

  没错,它是数组类型【别问我为啥知道,因为它有中括号】数组内的元素是VueComponent,也就是说是组件对象,并且也有一个children,子组件的children为一个空数组,因为它还没有孩子,所以children的内容是空的,最后也有showMessage函数。
效果图.gif

  可以看到,当点击按钮的时候确实弹出了弹出框的内容。
  但是,每个孩子都不是完美的,金无足赤人无完人,也有他缺陷。因为children访问某个子组件的时候需要通过索引值来访问,这就注定了它不是个完美的孩子,比如:
image.png

  原来只有三个子组件,想要访问第三个组件的话,通过this.$children[2]就可以获取,但是,保不准哪天遇到了奇葩客户,增加了很多无厘头的需求,然后父组件的模板就变成了下面的样子:

image.png

  我依旧不忘初心,想要访问第三个cnp,由于中间杀出了很多程咬金,我需要将下标值改成6才可以获取到。这就是children的缺陷,通过索引值来获取具体的子组件不够灵活,所以才产生了下面的方法:

二、通过refs

  既然都是访问子组件的,那么想必他们的用法是一样的,于是小编就信心满满的写成了下面的样子:

methods:{
    btnClick(){
            console.log(this.$refs);
    }
}

结果是这样的:

image.png

  天真了吧。傻了吧。它真不是个东西,是一个空对象!后来经过小编七七四十九天的炼制,终于炼出了灵丹妙药来惩治这个妖孽:首先要在子组件增加 “ref=XXX”的属性,然后再通过“$refs”访问,于是乎就有了下面的代码:

<div class="warp">
    <cnp></cnp>
    <cnp></cnp>
    <!--第一步:为子组件绑定ref=“a”的属性-->
    <cnp ref='a'></cnp>
    <button @click="btnClick">按钮</button>
</div>
methods:{
    btnClick(){
            console.log(this.$refs.a);
            <!--第二步:通过refs访问子组 -->
            this.$refs.a.showMessage();
    }
}

refe访问子组件.gif

image.png

妖孽成功的降服了!而且看到这个妖孽是一个对象类型的。
  要注意,使用refs访问的时候,一定要加上ref=“”的值。比如本例中的属性值是a,所以使用的时候是this.$refs.a.XXXX。至于为什么要加上ref属性呢,因为这样相当于做了标志,不管前面增加多少个标签,访问的依旧是属性值为a的子组件。你是我的狗,绑上狗绳,哪里溜达都不怕嘛~
  好啦~上面是小编今天为大家讲的关于组件访问中的组附件访问子组件,主要通过children和refs访问。
  小编要继续深造了(泡剧)了,(* ̄(oo) ̄)下期见

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容