详解Vue大护法——组件 (5)

尽管在Vue开发中,我们允许通过$parent来访问父组件,但是在真实开发中尽量不要这样做。子组件应该尽量避免直接访问父组件的数据,因为这样耦合度太高了。如果我们将子组件放在另外一个组件之内,很可能该父组件没有对应的属性,往往会引起问题。另外,更不好做的是通过$parent直接修改父组件的状态,那么父组件中的状态将变得飘忽不定,很不利于我的调试和维护。

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src=""></script> </head> <body> <div> <!-- 在Vue实例中使用父组件 --> <parent-cpn></parent-cpn> </div> </body> <!-- 父组件 --> <template> <div> <!-- 在父组件中使用子组件 --> <child-cpn></child-cpn> </div> </template> <!-- 子组件 --> <template> <div> <h2>我是子组件,哈哈哈</h2> <button type="button" @click="showParent">显示父组件的信息</button> </div> </template> <script type="text/javascript"> // 注册父组件 Vue.component('parent-cpn',{ template: '#parentCpn', data() { return { message: '我是父组件' } }, //注册子组件 components: { 'child-cpn': { template: '#childCpn', methods: { showParent() { console.log(this.$parent.message) } } } } }); let app=new Vue({ el: '#app' }) </script> </html>

image-20200718092349065

6.3.4非父子组件通信

刚才我们讨论的都是父子组件间的通信,那如果是非父子关系呢?非父子组件关系包括多个层级的组件,也包括兄弟组件的关系。在Vue1.x的时候,可以通过$dispatch和$broadcast完成。$dispatch用于向上级派发事件,$broadcast用于向下级广播事件。但是在Vue2.x都被取消了,在Vue2.x中,有一种方案是通过中央事件总线,也就是一个中介来完成。但是这种方案和直接使用Vuex的状态管理方案还是逊色很多。并且Vuex提供了更多好用的功能,所以这里我们暂且不讨论这种方案,后续我们专门学习Vuex的状态管理。

7.插槽slot 7.1编译作用域

在真正学习插槽之前,我们需要先理解一个概念:编译作用域。官方对于编译的作用域解析比较简单,我们自己来通过一个例子来理解这个概念:我们来考虑下面的代码是否最终是可以渲染出来的:

image-20200718092909574

<my-cpn v-show="isShow"></my-cpn>这段代码中,我们使用了isShow属性。isShow属性包含在组件中,也包含在Vue实例中。

答案:最终可以渲染出来,也就是使用的是Vue实例的属性。为什么呢?

官方给出了一条准则:父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。而我们在使用<my-cpn v-show="isShow"></my-cpn>的时候,整个组件的使用过程是相当于在父组件中出现的。那么他的作用域就是父组件,使用的属性也是属于父组件的属性。因此,isShow使用的是Vue实例中的属性,而不是子组件的属性。

7.2为什么使用插槽(slot)

slot翻译为插槽,在生活中很多地方都有插槽,电脑的USB插槽,插板当中的电源插槽。插槽的目的是让我们原来的设备具备更多的扩展性。比如电脑的USB我们可以插入U盘、硬盘、手机、音响、键盘、鼠标等等。

组件的插槽:

组件的插槽也是为了让我们封装的组件更加具有扩展性。让使用者可以决定组件内部的一些内容到底展示什么。

栗子:移动网站中的导航栏

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjjff.html