Vue基础第六天
动态组件
多个组件使用一个挂载点,并且动态切换,这就是动态组件
需求:完成一个注册页面功能,2个按钮点击分别切换两个组件
步骤:
- 创建两个组件并引入
- 注册并使用组件
- 设置一个vue变量等于其中一个组件的名字
- 使用vue内置的component标签动态挂载,根据绑定的is属性显示名字对应的组件
<template>
<div>
<button @click="componentName = 'UserInfo'">个人信息</button>
<button @click="componentName = 'UserName'">登录信息</button>
<!-- vue内置标签component是动态组件挂载点,会根据绑定的is属性显示名字对应的组件 -->
<!-- 组件缓存 keep-alive 不会销毁组件 -->
<keep-alive>
<component :is="componentName" />
</keep-alive>
</div>
</template>
<script>
import UserInfo from "@/components/UserInfo.vue";
import UserName from "@/components/UserName.vue";
export default {
data() {
return {
componentName: "UserInfo",
};
},
components: {
UserInfo,
UserName,
},
};
</script>
<style>
</style>
注意:频繁的切换会导致组件频繁创建和销毁,造成性能不高
如何切换组件:改变is的值,为要显示的组件名即可
组件缓存
频繁的切换会导致组件频繁创建和销毁,造成性能不高
语法:
Vue内置的keep-alive组件 包起来要频繁切换的组件
好处:不会频繁的创建和销毁组件,页面更快呈现
组件激活和非激活
如何知道组件是出现还是消失了
两个新的生命周期方法
方法名:
- activated ---激活时触发
- deactivated ---失去激活状态激发
插槽
通过slot标签,让组件内可以接收不同的标签结构显示
基本使用
使用场景:
- 封装里的组件数据不确定‘
- 封装里的组件标签不确定
语法口诀:
- 组件内用
<slot></slot>占位 - 使用组件时组件名称夹着的地方,传入标签替换slot
TopBar组件
<template>
<div class="topBar">
<div class="left"></div>
<div class="right">
<!-- 插槽占位标签 -->
<slot/>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style lang="less" scoped>
.topBar {
display: flex;
justify-content: space-between;
border: 2px solid salmon;
}
</style>
App.vue
<template>
<div>
<!-- 员工页使用, 就要带导入员工新建员工按钮 -->
<TopBar>
<button>新增员工</button>
<button>导入员工</button>
</TopBar>
<!-- 工资页面使用需要一个报表按钮 -->
<TopBar>
<button>报表</button>
</TopBar>
</div>
</template>
<script>
import TopBar from '@/components/TopBar.vue'
export default {
components: {
TopBar
}
}
</script>
<style>
</style>
默认内容
如果外面不给传,想给个默认值显示内容
口诀:slot标签内放置内容,作为默认显示内容
效果:
- 不给组件传标签,slot内容原地显示
- 给组件传标签,则slot整体被换掉
<template>
<div class="topBar">
<div class="left"></div>
<div class="right">
<!-- 插槽占位标签 -->
<slot>
<!-- 如果外面没有传入, 默认显示的内容 -->
欢迎来到我的页面
</slot>
</div>
</div>
</template>
具名插槽
一个组件内有两处以上需要外部传入标签的地方
语法:
- slot使用name属性区分名字
- template配合v-slot:名字来分发对应标签
- v-slot可以简写为#
<div class="left">
<slot name="left"/>
</div>
<div class="right">
<!-- 插槽占位标签 -->
<slot name="right">
<!-- 如果外面没有传入, 默认显示的内容 -->
欢迎来到我的页面
</slot>
</div>
<TopBar>
<!-- v-slot: 可以被简化成# -->
<template #left>
一共 666 位员工
</template>
<template #right>
<button>新增员工</button>
<button>导入员工</button>
</template>
</TopBar>
<!-- 工资页面使用需要一个报表按钮 -->
<TopBar>
<template v-slot:left>
5月工资报表
</template>
<template v-slot:right>
<button>报表</button>
</template>
</TopBar>
作用域插槽
使用插槽时,想使用子组件里面的变量
口诀:
- 子组件,在slot上绑定属性和子组件内的值
- 使用组件,传入自定义标签,用template和v-slot="自定义变量名"
- scope变量名自动绑定slot上所有属性和值
子组件
<template>
<div class="topBar">
<div class="left">
<!-- 作用域插槽 语法: :自定义名字="传入的数据" -->
<slot name="left" :row="num">
{{ num.first }}
</slot>
</div>
<div class="right">
<!-- 插槽占位标签 -->
<slot name="right">
<!-- 里面的内容是默认值 -->
欢迎来到我的页面
</slot>
</div>
</div>
</template>
<script>
export default {
data() {
return {
num: {
first: "一月",
scoend: "二月",
},
};
},
};
</script>
<style lang="less" scoped>
.topBar {
display: flex;
justify-content: space-between;
border: 2px solid red;
}
</style>
App,vue
<template>
<div>
<TopBar>
<!-- 作用域插槽 语法 v-slot:left="自定义名字" -->
<!-- 使用 :{{ numm.row.scoend }} {{自定义名字.子组件自定义名字.参数}} -->
<template v-slot:left="numm"> {{ numm.row.scoend }} </template>
<!-- 具名插槽写法 <template v-slot:"自定义的name名字"></template> -->
<template v-slot:right>
<button>员工信息</button>
<button>员工人数</button>
</template>
</TopBar>
<TopBar>
<template #left> 年度工资人均50万 </template>
<!-- 简写 -->
<template #right>
<button>报表</button>
</template>
</TopBar>
<TopBar />
</div>
</template>
<script>
import TopBar from "@/components/TopBar.vue";
export default {
components: {
TopBar,
},
};
</script>
<style>
</style>
使用场景:封装一个灵活的表格组件
自定义指令
Vue内置指令不满足要求,自己定义一些指令来使用
注册
全局注册
在main.js文件下注册
局部注册
在使用的页面里注册
基本使用
<template>
<div>
<!-- 使用自定义指令, 跟普通vue指令一样, 请千万注意,要加上 v- 前缀 -->
<input type="text">
<br>
<input type="text">
<br>
<input v-autofocus type="text">
</div>
</template>
<script>
export default {
// 局部指令注册
// directives: {
// 指令名字符串: {
// 配置对象
// 可以指定使用这个指令的元素, 在不同生命周期执行的函数
// 在这些钩子函数的形参中, 默认第一个可以获取元素本身, 第二个可以用来传参
// inserted,
// update
// }
// }
directives: {
autofocus: {
inserted(el) {
console.log(el, '自动聚焦');
el.focus()
}
}
}
}
</script>
<style>
</style>