咱们须要实现的需求是可以使使用者经过 <toggle>
组件动态地改变包含在它内部的内容。vue
熟悉 vue 的童鞋可能立刻会想到不一样的解决方案,好比使用 slot
并配合 v-if
,咱们这里采用另一种方法,利用 vue 提供的 provide/inject
属性按照复合组件的思想来实现。git
这里简单介绍下 provide/inject
的功能,它容许某个父组件向子组件注入一个依赖项(这里的父子关系能够跨域多个层级,也就是祖先与后代),若是咱们在其余 mvvm 框架对比来看的话,你能够发现其余框架也具备相同的特性,好比:angularjs
require
属性来声明注入逻辑想进一步了解的话,能够参考官方文档github
在 vue 中,这里咱们会分别实现三个组件,依次为:api
toggle-button
: 表明开关,用来渲染父组件的开关状态toggle-on
: 根据父组件 toggle 的开关状态,渲染当状态为开时的内容toggle-off
: 根据父组件 toggle 的开关状态,渲染当状态为关时的内容在上一篇文章中,咱们已经实现了 toggle 组件,这里咱们要作一些更改。首先,须要使用 provide 属性增长一个提供依赖的逻辑,以下:跨域
provide() { return { toggleComp: { status: this.status, toggle: this.toggle } } }
这里的 status 是该组件 data 中的声明的一个可监听对象,这个对象包含一个 on 属性来表明组件的开关状态,而 toggle 则是 methods 中的一个组件方法。框架
关于为何这里不直接使用 on 属性来表明开关状态,而使用一个可监听对象,是由于 provide
和 inject
绑定并非可响应的,同时官方文档也指出,这是刻意而为,因此为了享受到 vue 响应性带来的便利性,咱们这里传入 status 这个可监听对象。mvvm
对于其余三个组件,其内部实现逻辑十分简单,相信读者经过参考在线代码实例立刻就能看懂,这里只提一下关于 inject
声明注入依赖的逻辑,以下:ide
inject: { toggleComp: "toggleComp" }
这里的 "toggleComp"
与以前的 provide 对象中声明的 key 值所对应,而 inject 对象的 key 值当前组件注入依赖项的变量名称,以后,子组件便可以经过 this.toggleComp
来访问父组件的属性与方法。ui
经过复合组件的方式,咱们将 toggle
组件划分为了三个更小的、职责更加单一的子组件。同时因为 toggle-on
和 toggle-off
都使用 slot 来动态地注入组件调用者在其内部包含的自定义渲染逻辑,其灵活性获得了进一步的提高,只要这三个组件是做为 toggle
组件的子组件来调用,一切都将正常运行。
你能够下面的连接来看看这个组件的实现代码以及演示:
一般状况下,在设计和实现职能分明的组件时,可使用这种模式,好比 tabs
与 tab
组件,tabs
只负责 tab
的滚动、导航等逻辑,而 tab
自己仅负责内容的渲染,就如同这里的 toggle
和 toggle-button
、`toggle-on
、toggle-off
同样。
欢迎关注公众号 全栈101,只谈技术,不谈人生