一、动态组件
1. 什么是动态组件
动态组件指的是动态切换组件的显示与隐藏
2. 如何实现动态组件渲染
vue 提供了一个内置的 <component> 组件
,专门用来实现动态组件的渲染
。
示例代码如下:
可以认为<component>是一个占位符
,给组件占位,它的is属性指定哪个组件的名称,就把哪个组件渲染到它所在的位置。
3. 使用 keep-alive 保持状态
默认情况下,切换动态组件时无法保持组件的状态,会被销毁,此时可以使用 vue 内置的 <keep-alive> 组件
保持动态组件的状态。
示例代码如下:
4. keep-alive 对应的生命周期函数
当组件被缓存
时,会自动触发组件的 deactivated
生命周期函数。
当组件被激活
时,会自动触发组件的 activated
生命周期函数。
当组件第一次被创建的时候,既会执行created生命周期(先),又会执行activated生命周期(后)。但组件被激活的时候只会触发activated生命周期,不再触发created,因为组件没有被创建。
只有在使用<keep-alive>时才能使用activated和deactivated生命周期
。
5. keep-alive 的 include 属性
include 属性用来指定:只有名称匹配的组件会被缓存
。多个组件名之间使用英文的逗号分隔:
补充:还使用exclude属性指定不需要被缓存的组件,与include只能用其中之一,不能同时使用。
补充:如果在“声明组件”的时候没有为组件指定name名称,则组件的名称默认就是“注册时候的名称”。
如果声明了,当提供了name属性之后,组件的名称,就是name属性的值。
export default {
name: MyRight
}
这时<keep-alive>
中的include或者exclude属性值应当换成相应的组件名称
实际开发中建议都给组件添加name属性起组件名。
对比一下:
-
组件的“注册名称”主要应用场景是:以标签的形式,把注册好的组件,渲染和使用到页面结构中;
-
组件声明时候的“name名称”的主要应用场景:结合标签实现组件缓存功能,以及在调试工具中看到组件的name名称。
二、插槽
1. 什么是插槽
插槽
(Slot)是 vue 为组件的封装者
提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分
定义为插槽。
可以把插槽认为是组件封装期间,为用户预留的内容的占位符
。
2. 体验插槽的基础用法
在封装组件时,可以通过<slot>
元素定义插槽,从而为用户预留内容占位符。示例代码如下:
实际上每个插槽都应该有name属性,来指定当前插槽的名称,如果省略了slot的name值,默认为default。默认情况下,在使用组件的时候提供的内容都会被填充到名字为default的插槽中。
如果要把指定内容填充到指定名称的插槽中,需要使用v-slot(简写为#)这个指令。v-slot后面要跟上插槽的名字,如v-slot:default
,指令不能直接用在元素身上,必须用在<template>
标签上,<template>
它是一个虚拟的标签,只会起到包裹性质效果
,不会渲染任何实质性的html元素。
2.1 没有预留插槽的内容会被丢弃
如果在封装组件时没有预留任何 插槽,则用户提供的任何自定义内容都会被丢弃。
2.2 后备内容
封装组件时,可以为预留的 <slot>
插槽提供后备内容
(默认内容)。如果组件的使用者没有为插槽提供任何内容,则后备内容会生效。示例代码如下:
3. 具名插槽
如果在封装组件时需要预留多个插槽节点,则需要为每个 <slot>
插槽指定具体的 name 名称。这种带有具体名称的插槽叫做“具名插槽”。示例代码如下:
3.1 为具名插槽提供内容
在向具名插槽提供内容的时候,我们可以在一个 <template>
元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称。示例代码如下
3.2 具名插槽的简写形式
跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #
。例如 v-slot:header可以被重写为 #header
总结:在子组件中封装插槽时slot节点用name属性定义插槽,在父组件使用插槽时template节点用v-slot命令指定内容渲染到哪个插槽里面。
4. 作用域插槽
在封装组件的过程中,可以为预留的 <slot> 插槽
绑定 props 数据,这种带有 props 数据的 <slot>
叫做“作用域插槽”。示例代码如下:
在封装组件时,为预留的<slot>声明数据对象
,提供属性对应的值,在使用插槽的时候接收该对象使用,这种用法叫作用域插槽。 建议将对象命名为scope
(作用域)。
为插槽绑数据时可以直接写死也可以v-bind绑定数据源中的数据。
5.基于slot插槽重构购物车案例
5.1count渲染到slot插槽中
5.2父传子更方便了!
子组件Count
完成效果:
5.3实现增加减少功能
父组件
在这里插入图片描述
三、自定义指令
1. 什么是自定义指令
vue 官方提供了 v-text、v-for、v-model、v-if 等常用的指令。除此之外 vue 还允许开发者自定义指令。
2. 自定义指令的分类
vue 中的自定义指令分为两类,分别是:
⚫ 私有自定义指令(组件自己定义自己使用)
⚫ 全局自定义指令 (全局定义的其他所有组件都可以访问到)
3. 私有自定义指令
在每个 vue 组件中,可以在 directives 节点下
声明私有自定义指令。
示例代码如下:
<h1 v-color>App 根组件</h1>
directives是自定义指令节点,里面包含了color自定义指令,指向一个配置的对象,里面有一个bind方法,bind方法的第一个形参是固定写法,是原生DOM对象,是指令绑定的元素
。
当指令被绑定到相应元素后,会立即触发指令中的bind方法。拿到el元素后就可以修改元素的颜色。
4. 使用自定义指令
在使用自定义指令时,需要加上 v- 前缀。
5. 为自定义指令动态绑定参数值
在 template 结构中使用自定义指令时,可以通过等号(=)的方式,为当前指令动态绑定参数值:
6. 通过 binding 获取指令的参数值
在声明自定义指令时,可以通过形参中的第二个参数,来接收指令的参数值:
<h1 v-color="color">App 根组件</h1>
<p v-color="'red'">测试</p> =====红色
其中value是使用的值,expression是用户写的v-color的值的表达式
7. update 函数
bind 函数只调用 1 次
:当指令第一次绑定到元素时调用
,当 DOM 更新时 bind 函数不会被触发
。update
函数会在每次 DOM 更新时被调用
。
示例代码如下:
<h1 v-color="color">App 根组件</h1>
<p v-color="'red'">测试</p>
<button @click="color='green'">改变color的颜色值</button>
directives: {
// 定义名为color的自定义指令,指向一个配置对象
color: {
bind(el,binding) {
el.style.color=binding.value
console.log(binding);
},
// 在DOM更新的时候会触发update函数
update(el,binding) {
console.log("触发了v-color的update函数");
el.style.color=binding.value
console.log(binding);
},
}
}
8. 函数简写
如果 bind和update 函数中的逻辑完全相同
,则对象格式的自定义指令
可以简写成函数格式
:
9. 全局自定义指令
全局共享的自定义指令需要通过“Vue.directive()”
进行声明,示例代码如下:
/*
*main.js
*/
// 全局自定义指令
Vue.directives('color', function(el,binding){
el.style.color = binding.value
})
(类似定义全局过滤器)这样其他组件都可以使用v-color指令。
实际开发中更常用全局自定义指令。
10.关于main.js中 的小提示
/*
*main.js
*/
Vue.config.productionTip = true
此时控制台信息。提示打包发布时要用生产模式。默认是false,无意义的!