# 动态组件
# 动态组件定义
动态组件指的是动态切换组件的显示与隐藏
# 实现动态组件渲染
| <template> |
| <div> |
| <button @click="comName = 'Left'">展示 Left</button> |
| <button @click="comName = 'Right'">展示 Right</button> |
| <component :is="comName"></component> |
| </div> |
| </template> |
| <script> |
| export default { |
| data () { |
| return { |
| comName: 'Left' |
| } |
| } |
| } |
| </script> |
# 使用 keep-alive 保持状态
默认情况下,切换动态组件时无法保持组件的状态。此时可以使用 vue 内置的 <keep-alive> 组件保持动态组件的状态
| <template> |
| <div> |
| <keep-alive> |
| <component :is="comName"></component> |
| </keep-alive> |
| </div> |
| </template> |
# keep-alive 生命周期函数
当组件被缓存时,会自动触发组件的 deactivated 生命周期函数
当组件被激活时,会自动触发组件的 activated 生命周期函数
| <script> |
| export default { |
| activated () { |
| console.log('Left 组件被激活了'); |
| }, |
| deactivated () { |
| console.log('Left 组件被缓存了'); |
| } |
| } |
| </script> |
# keep-alive 的 include 属性
include 属性用来指定:只有名称匹配的组件会被缓存。多个组件名之间使用英文的逗号分隔,也可以使用 exclude 属性,不能同时使用
| <template> |
| <div> |
| <keep-alive include="Left,Right"> |
| <component :is="comName"></component> |
| </keep-alive> |
| </div> |
| </template> |
# 插槽
# 插槽定义
插槽(Slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽
![image-20230116121918426]()
# 体验插槽的基础用法
在封装组件时,可以通过 <slot> 元素定义插槽,从而为用户预留内容占位符
| <template> |
| <p>这是 MyCom1 组件的第一个标签</p> |
| <solt></solt> |
| <p>这是 MyCom1 组件的最后一个标签</p> |
| </template> |
| <MyCom1> |
| <p>---用户自定义内容---</p> |
| </MyCom1> |
# 没有预留插槽的内容会被丢弃
如果在封装组件时没有预留任何 <slot> 插槽,则用户提供的任何自定义内容都会被丢弃
| <template> |
| <p>这是 MyCom1 组件的第一个标签</p> |
| |
| <p>这是 MyCom1 组件的最后一个标签</p> |
| </template> |
| <MyCom1> |
| <p>---用户自定义内容---</p> |
| </MyCom1> |
# 后备内容
封装组件时,可以为预留的 <slot> 插槽提供后备内容(默认内容)如果组件的使用者没有为插槽提供任何内容,则后备内容会生效
| <template> |
| <p>这是 MyCom1 组件的第一个标签</p> |
| <solt>这是插槽后备内容</solt> |
| <p>这是 MyCom1 组件的最后一个标签</p> |
| </template> |
# 具名插槽
如果在封装组件时需要预留多个插槽节点,则需要为每个 <slot> 插槽指定具体的 name 名称
| <template> |
| <solt name="default">默认名字就是default</solt> |
| </template> |
# 为具名插槽提供内容
在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称
| <template v-solt:header> |
| <h1>header---</h1> |
| </template> |
| |
| <template #header> |
| <h1>header---</h1> |
| </template> |
# 作用域插槽
在封装组件的过程中,可以为预留的 <slot> 插槽绑定 props 数据,这种带有 props 数据的 <slot> 叫做 “作用域插槽”
| <template> |
| <div> |
| <tbody> |
| <solt v-for="item in list" :user='item'></solt> |
| </tbody> |
| </div> |
| </template> |
# 使用作用域插槽
可以使用 v-slot: 的形式,接收作用域插槽对外提供的数据
| <template> |
| <div id="app"> |
| <MyCom> |
| <template v-solt:default="scope"> |
| <p></p> |
| </template> |
| </MyCom> |
| </div> |
| </template> |
# 解沟插槽 Prop
作用域插槽对外提供的数据对象,可以使用解构赋值简化数据的接收过程
| <template> |
| <div id="app"> |
| <MyCom> |
| <template v-solt:default="{user}"> |
| <p></p> |
| </template> |
| </MyCom> |
| </div> |
| </template> |
# 自定义指令
# 自定义指令定义
vue 官方提供了 v-text、v-for、v-model、v-if 等常用的指令,除此之外 vue 还允许开发者自定义指令
# 自定义指令分类
# 私有自定义指令
在每个 vue 组件中,可以在 directives 节点下声明私有自定义指令
| <script> |
| export default { |
| directive: { |
| color: { |
| bind (el) { |
| el.style.color = 'red' |
| } |
| } |
| } |
| } |
| </script> |
# 使用自定义指令
| <template> |
| <div> |
| <h1 v-color>App组件</h1> |
| </div> |
| </template> |
# 为自定义指令动态绑定数值
在 template 结构中使用自定义指令时,可以通过等号(=)的方式,为当前指令动态绑定参数值
| <template> |
| <div> |
| <h1 v-color="color">App组件</h1> |
| </div> |
| </template> |
| <script> |
| export default { |
| data () { |
| return { |
| color: 'red' |
| } |
| } |
| } |
| </script> |
# 通过 binding 获取指令的参数值
在声明自定义指令时,可以通过形参中的第二个参数,来接收指令的参数值
| <script> |
| export default { |
| directives: { |
| color: { |
| bind (el, binding) { |
| el.style.color = binding.value |
| } |
| } |
| } |
| } |
| </script> |
# update 函数
bind 函数只调用 1 次:当指令第一次绑定到元素时调用,当 DOM 更新时 bind 函数不会被触发,update 函数会在每次 DOM 更新时被调用
| <script> |
| export default { |
| directives: { |
| color: { |
| bind (el, binding) { |
| el.style.color = binding.value |
| }, |
| update (el, binding) { |
| el.style.color = binding.value |
| } |
| } |
| } |
| } |
| </script> |
# 函数简写
如果 insert 和 update 函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式
| <script> |
| export default { |
| directives: { |
| color (el, binding) { |
| el.style.color = binding.value |
| } |
| } |
| } |
| </script> |
# 全局自定义指令
在 main.js 中定义
| Vue.directive('color', function (el, binding) { |
| el.style.color = bingding.value |
| }) |
# axios
# 定义全局 axios
在 main.js 中导入
| import axios from 'axios' |
| Vue.prototype.$axios = axios |
# 调用全局 axios
| <script> |
| export default { |
| methods: { |
| async getInfo () { |
| const {data: res} = await this.$axios.get('http://www.baozi.com:3006/api/get') |
| } |
| } |
| } |
| </script> |
# 配置统一根路径
| import axios from 'axios' |
| axios.defaults.baseURL = 'http://www.baozi.com:3006' |
| Vue.prototype.$axios = axios |
| <script> |
| export default { |
| methods: { |
| async getInfo () { |
| const {data: res} = await this.$axios.get('/api/get') |
| } |
| } |
| } |
| </script> |
# 配置统一的根路径缺点
不利于接口路径的复用