组件的复用
这里的工程和上一节的一样
先建立一个组件
MyButton.vue
引用这个组件
About.vue
页面:
1. MyButton.vue 就是一个组件,其它位置通过import来引入这个组件,就可以来使用了
2. 注意 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
如果不是这样:
data: () => ({ count: 0})
而是这样:
data: { count: 0}
额,会报错~
页面也不能正常:
..
通过 Prop 向子组件传递数据
新建一个子组件
MyTitle.vue
{ {blog}}
这里通过自定义的属性blog来传递数据,定义在子组件里面
在父组件里面使用,并传入数据
将数据绑定到blog属性上 :blog
页面:
当组件变得复杂,我们需要传递的不止一个数据,如果是多个数据可以通过以下方式:
子组件:MyTitle.vue
{ {blog.title}}
{
{blog.content}}
父组件:About.vue
页面:
通过事件向父级组件发送消息
一些功能可能要求我们和父级组件进行沟通。例如我们可能会引入一个可访问性的功能来放大博文的字号,同时让页面的其它部分保持默认的字号。
Vue 实例提供了一个自定义事件的系统来解决这个问题。我们可以在子组件里调用内建的 $emit 方法并传入事件的名字,来向父级组件触发一个事件
子组件:
{ {blog.title}}
{
{blog.content}}
父组件:
页面:可以点击放大或者缩小
有的时候我们可能想让子组件来决定文本放大多少,那么也就是用一个事件来抛出一个特定的值,只需要修改子组件的$emit,加上第二个参数:
然后当在父级组件监听这个事件的时候,我们可以通过 $event
访问到被抛出的这个值
或者,父组件的处理函数是一个方法,那么从子组件传过来的$event变成这个方法的第一个参数:
处理方法:
插槽
匿名插槽【木有名字的插槽:<slot></slot>】
新建一个子组件:
NoNameSlot.vue
父组件:
{ {i.content}}
一句话:子组件的 <slot></slot> 会被替换成父组件传入的任何内容,但是如果子元素里面没有<slot></slot>,父组件传入的内容会被抛弃
页面:
不信你看,三个p
具名插槽【有名字的插槽:<slot name="header"></slot>】
有时候我们需要多个插槽,不同的位置渲染不同的内容,那么就需要具名插槽了
子组件:MyLayout.vue
父组件:About.vue
这里是标题啊!
A paragraph for the main content.
And another one.
这里是脚丫子
页面:
可以看出,父组件在使用的时候,只需要通过指定slot的名字,就可以把指定内容送到对应的插槽上;而那些没有指定名字的,如果存在匿名插槽则会被送到匿名插槽的位置上。如果不存在,则不渲染。
作用域插槽【2.1.0+新增:可从子组件获取数据的可复用的插槽。引申:scope 用于表示一个作为带作用域的插槽的 <template> 元素,它在 2.5.0+ 中被 slot-scope 替代。】
前面两个都是从父组件获取数据,这个恰好反过来,从子组件获取数据。
子组件:
父组件:
按套路输出数据
- { {item}}
一锅端
{ {childData.items}} 不使用子组件提供的数据
作用域插槽退化为匿名插槽
slot-scope 任何名字都可以,注意在父组件里,childData通过引用子组件的绑定属性名称来获取数据
页面
动态组件【在不同组件之间进行动态切换】
建立三个子组件 ComponentA、ComponentB、ComponentC
组件A
内容一样,只是改个字母,这里不重复了。
父组件
页面:
--
当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。也就是说,切换是一个销毁/渲染的过程,失效的被销毁,展示的时候重新渲染。那么如果我们不想要这一浪费的行为,我们更希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来,只需要把组件用<keep-alive>包裹起来: