键盘敲烂,月薪过万作业不做,等于没学
当前系列: Vue.js 修改讲义

$root和$parent

可以在子组件中访问根元素($root)和父元素($parent)。(复习:以$开头标识全局属性/方法

演示用代码:root => yz-welcome => yz-enroll

<yz-welcome></yz-welcome>
Vue.component('yz-welcome', {
    template: `<p @click="hello">hello, <yz-enroll></yz-enroll> </p>`, data() {
        return {
            id: 23
        }
    },
    methods: {
        hello() {
            console.log(this.$root.sname);
        }
    }
})
Vue.component('yz-enroll', {
    template: ` <a @mouseover="enroll">报到</a>`,
    methods: {
        enroll() {
            console.log(this.$parent.id);    //能$root么? }
    }
})


依赖注入

直接使用$root和$parent有两个问题:

  • 在多层级嵌套中,$root和$parent之间的组件无法直接获取($parent.$parent太丑,(*/ω\*))
  • $root和$parent没隐私(封装)啊!

为了便于演示,再生成一个组件:

Vue.component('yz-order', {
    template: ` <small>预定时间</small>`,
    methods: {
    }
})
yz-enroll中调用:
template: ` <a>报到 <yz-order></yz-order> </a>`

形成:root => yz-welcome => yz-enroll => yz-order 的嵌套层级。

所以,vue提供了:

  • provide:由祖先组件提供
    provide既可以是Object,也可以说返回一个Object的函数,但是:如果要使用this指代vue实例,需要使用函数(推荐
  • inject:由子孙组件使用

provide和inject类似于一个大号的props,将数据/方法从祖先组件传到子孙组件中。

注意:不要直接使用父组件方法


$ref

$children:获取的是所有的子组件。

要获取某一个特定的child,方法类似于之前事件中的$refs

  • 通过 ref 这个 attribute 为子组件赋予一个 ID 引用
    <yz-welcome ref="welcome"></yz-welcome>
    <input type="textbox" ref="major" />
  • 在父组件中通过this.$refs.XXX获得该子组件
    vm.$refs.welcome.id
    注意:只能是父调子(演示:ref在根实例vm下的yz-welcome中)
    <yz-welcome ref="welcome"></yz-welcome>
    不能是调孙子/后代(演示:ref在yz-welcome下的template中)
    template: `<p ref="welcome">hello, <yz-enroll></yz-enroll> </p>`,

另外,$refs 只会在组件渲染完成之后生效,比如:生命周期created阶段还没有完成渲染

// created: undefined
mounted: function () {
    console.log(this.$refs.welcome.id);    //正常 }


事件

还可以用编程的方式,调用vue实例方法:

  • 绑定一个事件:$on(eventName, eventHandler) 
  • 解绑一个事件:$off(eventName, [eventHandler])
  • 绑定一次性事件:$once(eventName, eventHandler)

之前学习的$emit()其实也类似。

学习的关键是理解父子组件间通过事件传递消息/进行通讯的实质:

<!-- 没有声明的greet事件处理 -->
<yz-welcome></yz-welcome>
Vue.component('yz-welcome', {
    template: `<p @click="$emit('greet')">hello</p>`,  //greet是$emit出来的
    //不是写在parent component里,而是自己的mounted()函数中!
    mounted() {
        //绑定事件到当前vue实例上
        this.$on("greet", function () {
            console.log("hello, 新同学");
        })
    }
})


循环引用

@想一想@:组件能不能自己调用自己?(复习:函数递归

先准备一段循环嵌套的数据:

const vm = new Vue({
    el: "#yz-hello",
    data: {
        node: {
            name: "根",
            children: {
                name: "枝",
                children: {
                    name: "叶",
                    children: null
                }
            }
        }
    }
})
然后,一个自己调用自己的template和vue component
Vue.component('yz-welcome', {
    template: `
    <div v-if="node"> <!--注意这个递归终止条件-->
        {{node.name}}
        <yz-welcome :node="node.children"></yz-welcome>
    </div>`,
    props: ["node"]
})
最后,开始调用
<yz-welcome :node="node"></yz-welcome>


作业

  1. 扩展循环引用,做出一个多枝多叶的树状内容呈现(对应:文章目录管理)
  2. 分别利用声明式和编程式,完成树的展开折叠
学习笔记
源栈学历
键盘敲烂,月薪过万作业不做,等于没学

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 Vue.js 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码