插槽(slot):将父组件中的内容与子组件的模板进行混合使用。可以弥补视图的不足。
使用插槽的目的 :使组件更具有扩展性。
(1)匿名插槽(默认插槽):有且只能有一个
☀️举个例子:
Son.vue代码段:
<template>
<div>
<h2>子组件h2>
<p>西安邮电大学p>
<slot>slot>
div>
template>
<script>
export default {
name: "Son"
}
script>
<style scoped>
style>
Father.vue代码段:
<template>
<div>
<son>
<button>演示按钮button>
son>
div>
template>
<script>
import Son from "./Son.vue";
export default {
name: "Father"
}
script>
<style scoped>
style>
App.vue代码段:
import Father from "./components/Father.vue";
<template>
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
<Father/>
template>

(2)具名插槽:当子组件的功能复杂时,子组件的插槽可能并非是一个。每个插槽给个名称。 比如封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边。那么,外面在给插槽插入内容时,如何区分插入的是哪一个呢?
这时候,就需要给slot指定一个name属性,也就是具名插槽。
a、子组件中定义插槽:
b、父组件中使用插槽:
☀️举个例子:
Father.vue代码段:
<template>
<div>
<Son>
<template v-slot:top>
<button>顶部按钮button><br/>
template>
<template v-slot:center>
<input type="text"/>
template>
<template v-slot:bottom>
<h2>具名插槽h2>
template>
<template v-slot:default> //dafault代表匿名的插槽
<button>匿名插槽button>
template>
Son>
div>
template>
<script>
import Son from './Son.vue'
export default {
name: "Father",
components: {
Son
}
}
script>
<style scoped>
style>
Son.vue代码段:
<template>
<div>
<slot name="top">slot>
<slot name="center">slot>
<slot name="bottom">slot>
<slot>slot>
div>
template>
<script>
export default {
name: "Son"
}
script>
<style scoped>
style>
App.vue代码段同上:
import Father from "./components/Father.vue";
<template>
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
<Father/>
template>

(3)作用域插槽:父组件在使用的时候可以替换slot插槽中的显示页面结构,但展示的数据还是来源于子组件。
a、子组件中定义:
b、父组件中使用:
{{ 变量名.子组件中插槽绑定的属性名
☀️举个例子:
Son.vue代码段:
<template>
<div>
<slot :lang="languageList" name="sp">slot>
<slot :lang="languageList" name="cz">slot>
div>
template>
<script>
export default {
name: "Son",
data(){
return {
languageList:['Javascript','c++','Java','Python']
}
}
}
script>
<style scoped>
style>
Father.vue代码段:
<template>
<div>
<Son>
<template v-slot:sp="slotProps">
<h2>{{ slotProps.lang.join('--') }}h2>
template>
Son>
<hr/>
<Son>
<template v-slot:cz="slotProps">
<ul>
<li v-for="(item,index) in slotProps.lang" :key="index">{{ item }}li>
ul>
template>
Son>
div>
template>
<script>
import Son from './Son.vue'
export default {
name: "Father",
components: {
Son
}
}
script>
<style scoped>
style>

注意:
数据来源于子组件,展示方式由父组件决定
‘v-slot:‘指令可以缩写为’#’
上例中Father.vue代码段的改写如下(效果相同):
<Son>
<template #sp="slotProps">
<h2>{{ slotProps.lang.join('--') }}h2>
template>
Son>
<hr/>
<Son>
<template #cz="slotProps">
<ul>
<li v-for="(item,index) in slotProps.lang" :key="index">{{ item }}li>
ul>
template>
Son>
过渡动画:在组件的插入、移除、更新时可以附带转场效果,即使用过渡动画
在vue中内置了transition组件,可以用它来包装要展示过渡动画的的组件,在transition组件的name属性指定要执行的动画的名称,vue约定了一系列CSS类名来定义各个过渡过程中组件的状态。
组件
动画名-enter-from :表示动画开始
动画名称-enter-active:整个运动状态
动画名称-enter-to:结束状态
动画名-leave-from:离开时的状态
动画名-leave-active:离开过渡生效时的状态
动画名-leave-to:离开的结束状态
互斥动画:是多个组件的过渡动画。即当一个元素显示时,其他元素隐藏
☀️举个例子:
test.vue代码段:
<template>
<h2>动画测试h2>
<button @click="myClick">显示/隐藏button>
<transition name="ani">
<div v-if="show" class="demo">div>
<div v-else class="demo2">div>
transition>
template>
<script>
export default {
name: "Test",
data(){
return {
show : false
}
},
methods:{
myClick(){
this.show = !this.show
}
}
}
script>
<style scoped>
.demo{
width: 100px;
height: 100px;
background-color: blue;
}
.demo2{
width: 100px;
height: 100px;
background-color: red;
}
.ani-enter-from {
width: 0px;
height: 0px;
background-color: red;
}
.ani-enter-active{
transition: width 2s , height 2s, background-color 2s;
}
.ani-enter-to{
width: 100px;
height: 100px;
background-color: blue;
}
.ani-leave-from{
width: 100px;
height: 100px;
background-color: blue;
}
.ani-leave-active{
transition: width 2s , height 2s, background-color 3s;
}
.ani-leave-to{
idth: 0px;
height: 0px;
background-color: red;
}
style>
App.vue代码段:
import Test from "./components/Test.vue";
<template>
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
<Test/>
template>
设置动画过程中的监听回调:表示在组件的加载或卸载过程中,有一系列的生命周期函数被调用。
@before-enter=“beforeEnter”
@enter=“enter”
@after-enter=“afterEnter”
@before-leave=“beforeLeave”
@leave=“Leave”
@after-leave=“afterLeave”
☀️举个例子:
One.vue代码段:
<template>
<button @click="myClick">显示/隐藏button>
<transition name="ani"
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@before-leave="beforeLeave"
@leave="Leave"
@after-leave="afterLeave"
>
<div v-if="show" class="demo">div>
transition>
template>
<script>
export default {
name: "One",
data(){
return{
show:false
}
},
methods:{
myClick(){
this.show = !this.show
},
beforeEnter(){
console.log('beforeEnter')
},
enter(el,done){
console.log('动画开始'+el)
console.log(done)
},
afterEnter(el){
console.log('afterEnter')
},
beforeLeave(el){
console.log('beforeLeave')
},
Leave(el){
console.log('leave')
},
afterLeave(){
console.log('afterLeave')
}
}
}
script>
<style scoped>
.demo{
width:100px;
height: 100px;
background-color: blue;
margin-bottom: 10px;
}
.ani-enter-from{
width:0px;
height:0px;
background-color: red;
}
.ani-enter-active{
transition:width 2s ,height 2s,background-color 2s;
}
.ani-enter-to{
width:100px;
height: 100px;
background-color: blue;
}
.ani-leave-from{
width: 100px;
height: 100px;
background-color: blue;
}
.ani-leave-active{
transition: width 2s , height 2s, background-color 3s;
}
.ani-leave-to{
idth: 0px;
height: 0px;
background-color: red;
}
style>
App.vue代码段:
import One from "./components/One.vue"
<template>
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
<One/>
template>
列表过渡动画:使用来实现列表元素的动画效果
注意:若使用列表动画,列表中的每个元素(列表项)必须要有一个唯一的key值
☀️举个例子:
ListDemo.vue代码段:
<template>
<button @click="myClick">添加元素button>
<button @click="delClick">删除元素button>
<transition-group name="list">
<div v-for="(item,index) in items" :key="index">
元素:{{ item }}
div>
transition-group>
template>
<script>
export default {
name: "ListDemo",
data(){
return {
items: [1,2,3,4,5]
}
},
methods:{
myClick(){
this.items.push(this.items[this.items.length-1]+1)
},
delClick(){
if (this.items.length > 0){
this.items.pop()
}
}
}
}
script>
<style scoped>
.list-enter-active,
.list-leave-active {
transition: all 1s ease;
}
.list-enter-from,
.list-leave-to{
opacity: 0;
}
style>
App.vue代码段:
import ListDemo from "./components/ListDemo.vue";
<template>
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
<ListDemo/>
template>