1.is动态组件
动态组件
<!-- 动态使用组件 component:渲染一个“元组件”为动态组件。依 is 的值,来决定哪个组件被渲染。-->
<component :is="compName"></component>
<button type="button" @click="change()">切换组件</button>
2.keep-alive
介绍
<keep-alive>
包裹动态组件(v-if、is、router-view)时,会缓存组件实例,而不是销毁它们。<keep-alive>
是一个抽象包裹组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。
语法格式
1.无条件缓存
<keep-alive >包裹动态组件 </keep-alive>
2.有条件缓存
<keep-alive include|exclude = "组件的名字,组件的名字">包裹动态组件 </keep-alive>
include:哪些组件可以被缓存
exclude:哪些组件不被缓存
作用
1.主要用于保留组件状态或避免重新渲染。比如重新发起网络请求(商品列表 新闻列表 不怎么变化的内容)
2.还能避免切换动态组件时丢失组件上的数据状态等
代码实例
<template>
<div>
<h4>vue语法--keep-alive(组件缓存)</h4>
<keep-alive include="good,attr">
<component :is="compList[index]"></component>
</keep-alive>
<hr>
<button @click="prev">上一步</button>
<button @click="next">下一步</button>
<button>完成添加</button>
</div>
</template>
<script>
// 引入商品分类、详情、属性组件
import cateComp from "./cate.vue"
import goodComp from "./good.vue"
import attrComp from "./attr.vue"
export default {
components: {
cateComp,
goodComp,
attrComp
},
data() {
return {
compList: [
"cateComp",
"goodComp",
"attrComp"
],
index: 0
};
},
methods: {
// 上一个组件
prev() {
--this.index
},
// 下一个组件
next() {
++this.index
}
},
};
</script>
特殊的生命周期
activated(激活钩子函数) deactivated(失活的钩子函数)
总结
1.keep-alive可以实现组件实例的缓存,从而提高组件页面性能,比如避免重复请求网络数据
2.因为keep-alive的缓存机制会导致组件中的一些生命周期函数不会触发,可能会影响业务开发 ;
3.针对不会触发被缓存组件生命周期的问题,提供了两个钩子函数,一个是进入的activated,另一个是离开的
deactivated;
4.activated和deactivated只能用在缓存组价中
3.slot插槽
如果需要在父组件使用子组件时,来分发一些不同的内容展示在子组件中,可以使用插槽来实现
匿名插槽
语法格式:
子组件:
<slot></slot>
父组件:
<h3>我是头部标题</h3>
父组件:
<one-comp>
<p>我是头部</p>
<p>我是底部</p>
</one-comp>
子组件:
<slot></slot>
具名插槽
给插槽起具体名字,父组件根据插槽名字传递对应位置的标签结构
语法格式:
子组件:
<slot name="header"></slot>
父组件:
<h3 slot="header">我是头部标题</h3>
子组件:
<div>
<!-- 定义头部插槽 -->
<slot name="header"></slot>
<h6>具名插槽</h6>
<!-- 定义底部插槽 -->
<slot name="footer"></slot>
</div>
父组件:
<two-comp>
<p slot="header">我是头部</p>
<p slot="footer">我是底部</p>
</two-comp>
作用域插槽
在使用插槽的时候,希望父组件可以控制子组件中数据的展示
作用域插槽分为匿名作用域插槽和具名作用域插槽
语法格式:
1.匿名作用域插槽
子组件:
<slot :sonData="data"></slot>
父组件:
<template v-slot:default="prop">
<h3>{{prop.sonData.alas}}</h3>
</template>
prop:
此处代指用于接受孩子传递的数据,对象格式,可以接受多个数据
2.具名作用域插槽
子组件:
<slot :sonData="data" name="info"></slot>
父组件:
<template v-slot:info="prop">
<h3>{{prop.sonData.alas}}</h3>
</template>
子组件:
<!-- 作用域插槽 -->
<div>
<h6>作用域插槽</h6>
<!-- 展示学科信息 -->
<ul>
<li v-for="(item, index) in list" :key="index">
<!-- 通过作用域插槽给父亲传递每次遍历出来的数据 匿名-->
<!-- <slot :sonData="item"></slot> -->
<!-- 通过作用域插槽给父亲传递每次遍历出来的数据 具名-->
<slot name="one" :sonData="item"></slot>
<slot name="two" :sonData="item"></slot>
</li>
</ul>
</div>
父组件:
<!-- 3.作用域插槽 -->
<!-- 第一次调用子组件,显示每条数据中的name -->
<!-- <three-comp :list="list"> -->
<!-- props用来接受子组件传递的数据 v-slot:default == v-slot -->
<!-- <template v-slot:default="props">
<p>{{ props.sonData.name }}</p>
</template>
</three-comp> -->
<!-- 第二次调用子组件,显示每条数据中的alias -->
<!-- <three-comp :list="list">
<template v-slot:default="props">
<p>{{ props.sonData.alias }}</p>
</template>
</three-comp> -->
<!-- 第三次调用子组件,使用具名插槽 -->
<three-comp :list="list">
<template v-slot:one="props">
<p>{{ props.sonData.name }}</p>
</template>
<template v-slot:two="props">
<p>{{ props.sonData.alias }}</p>
</template>
</three-comp>
list: [
{ name: "java", alias: "后端" },
{ name: "web", alias: "前端" },
{ name: "ui", alias: "美工" }
]