共计 3794 个字符,预计需要花费 10 分钟才能阅读完成。
动态组件
动态的切换组件的显示与隐藏
vue 提供了一个内置的 <component>
组件,专门用来实现动态组件的渲染:
<-- 2. 通过 is 属性,动态指定要渲染的组件 -->
<component :is="comName = 'Left'"></component>
<-- 3. 点击按钮,动态切换组件的名称 -->
<button @click="comName = 'Left'">展示 Left 组件</button>
<button @click="comName = 'Right'">展示 Right 组件</button>
data() {
// 1. 当前要渲染的组件名称
return {
comName: 'Left'
}
}
使用 keep-alive
保持状态
默认情况下,切换动态组件时无法保持组件的状态;此时可以使用 vue 内置的 <keep-alive>
组件保持动态组件的状态:
<!-- keep-alive 可以把内部的组件进行缓存,而不是销毁组件 -->
<keep-alive>
<component :is="comName"></component>
</keep-alive>
keep-alive
对应的生命周期函数
当组件被缓存时,会自动触发组件的 deactivated
生命周期函数
当组件被激活时,会自动触发组件的 activated
生命周期函数
export default {
created() {
console.log('组件被创建了')
},
destroyed() {
console.log('组件被销毁了')
},
// 当组件第一次被创建的时候,即会执行 created 生命周期,也会执行 activated 生命周期
activated() {
console.log('Left 组件被激活了')
},
deactivated() {
console.log('Left 组件被缓存了')
},
}
keep-alive
的 include
属性
include
属性用来指定:只有名称匹配的组件会被缓存;多个组件之间用英文逗号分隔:
<keep-alive include="Left,Right">
<component :is="comName"></component>
</keep-alive>
exclude
属性,指定的组件不被缓存
include
和exclude
不能同时使用
// Right 组件
export default {
// 当提供 name 属性之后,组件的名称,就是 name 属性的值
// 组件的 “注册名称” 的主要应用场景是:以标签的形式,把注册好的组件,渲染和使用到页面结构之中
// 组件生命时候的 “name” 名称的主要应用场景:结合 <keep-alive> 标签实现组件缓存功能;以及在调试工具中看到组件的 name 名称
name: 'MyRight',
}
插槽
插槽(Slot)是 vue 为组件的封装着提供的能力;允许开发者在封装组件时,把不确定的、希望用户指定的部分定义为插槽
插槽基础语法
在封装组件时,可以通过 <slot>
元素定义插槽,从而为用户预留内置占位符:
// 封装组件 MyCom1
<template>
<p>这是 MyCom1 组件的第 1 个 p 标签</p>
<!-- 通过 slot 标签,为用户预留内容占位符(插槽),每一个插槽都要有一个 name 名称 -->
<slot name="default"></slot>
<p>这是 MyCom1 组件的第 2 个 p 标签</p>
</template>
// 使用组件 MyCom1
<MyCom1>
<!-- 在使用 MyCom1 组件时,为插槽指定具体的内容 -->
<template v-slot:default>
<p>~~~用户自定义的内容~~~</p>
</template>
</MyCom1>
具名插槽
如果在封装组件时需要预留多个插槽节点,则需要为每个 <slot>
插槽指定具体的 name
名称;这种带有具体名称的插槽叫做 “具名插槽”:
// 组件 Article
<dic class="article-container">
<header>
<!-- 把文章标题放到这里 -->
<slot name="title">标题</slot>
</header>
<main>
<!-- 把文章内容放到这里 -->
<slot name="article">内容</slot>
</main>
<footer>
<!-- 把文章作者放到这里 -->
<slot name="author">作者</slot>
</footer>
</div>
// 使用组件 Article
<Article>
<template #title>
<h2>文章标题</h2>
</template>
<template #article>
<P>文章内容<p>
</template>
<template #author>
<P>文章作者<p>
</template>
</Article>
没有指定
name
名称的插槽,会有隐含的默认名称叫做default
作用域插槽
在封装组件的过程中,可以为预留的 <slot>
插槽绑定一个 props
数据,这种带有 props
数据的 <slot>
叫做 “作用域插槽” :
// 组件 A
<tbody>
<!-- 下面的 slot 是一个作用域插槽 -->
<!-- 为预留的 slot 提供属性对应的值 -->
<slot name="a" msg="hello vue.js" :user="userinfo"></slot>
</tbody>
// 使用组件 A
<A>
// 把数据用等号 然后 使用 {} 解构出来
// scope
<template #a="{msg, user}">
<!-- <p>{{ scope }}<p> 输出是对象 { msg: 'hello vue.js', {name: '张三', age: 18} } -->
<p>{{ msg }}<p> <!-- hello vue.js -->
<p>{{ user.name }}<p> <!-- 张三 -->
</template>
</A>
自定义指令
vue 官方提供了 v-text
、v-for
、v-model
、v-if
等常用的指令;除此之外 vue 还允许开发者自定义指令
自定义指令的分类
- 私有自定义指令
- 全局自定义指令
私有自定义指令
在每个 vue 组件中,可以在 directives
节点下生命私有自定义指令:
<!-- 声明自定义指令时,指令的名字是 color -->
<!-- 使用自定义指令时,需要加上 v- 指令前缀 -->
<h1 v-color>App 组件</h1>
// 私有自定义指令的节点
directives: {
color: {
// 为绑定的 HTML 元素设置红色字体
bind(el) {
// 形参中的 el 是绑定了此指令的原生 DOM 对象
el.style.color = 'red'
}
}
}
为自定义指令动态绑定参数
在 template
结构中使用自定义指令时,可以通过 = 号赋值的方式,为当前指令动态绑定参数值
在声明自定义指令时,可以通过形参的第二个参数 binding
获取指令的参数值
<!-- 在使用指令时,动态为当前指令绑定参数值 color -->
<h1 v-color="color">App 组件</h1>
data() {
return {
// 定义 color 颜色
color: 'red'
}
},
directives: {
color: {
bind(el, binding) {
// 通过 binding 对象的 .value 属性,获取动态的参数值
el.style.color = binding.value
}
}
}
update
函数
bind
函数只调用 1 次:当指令第一次绑定到元素时调用,当 DOM 更像时 bind
函数不会被触发update
函数会在每次 DOM 更新时被调用:
directives: {
color: {
// 当指令第一次被绑定到元素时被调用
bind(el,binding) {
el.style.color = binding.value
},
// 每次 DOM 更新时被调用
bind(el,binding) {
el.style.color = binding.value
}
}
}
函数简写
如果 bind
和 update
函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式:
directives: {
// 在 bind 和 update 时,会触发相同的业务逻辑
color(el,binding) {
el.style.color = binding.value
}
}
全局自定义指令
全局共享的自定义指令需要通过 Vue.directive()
进行声明,写到 main.js 里面:
// 参数1:字符串,表示全局自定义指令的名字
// 参数2:对象,用来接收指令的数值
Vue.directive('color', {
bind(el, binding) {
el.style.color = binding.value
},
update(el, binding) {
el.style.color = binding.value
}
})
// 简写
Vue.directive('color', function(el, binding) {
el.style.color = binding.value
})
Vue.directive('color', (el, binding) => {
el.style.color = binding.value
})
总结
keep-alive
元素基本使用
<keep-alive>
标签、include
属性
插槽基本使用
<slot>
标签、具名插槽、作用域插槽、后备内容(插槽的默认内容)
自定义指令
- 私有自定义指令
directive: {}
- 全局自定义指令
Vue.directive()