一、动态组件
- 动态组件就是
根据组件的名字来渲染组件
- 动态组件在切换的时候会引起组件的
挂载和卸载
keep-alive:缓存组件
,用这个进行缓存数据,而且动态组件在在切换时就不在挂载和卸载了
1、发布评论和评论列表的切换
<div id="box">
<button @click="cname='List'">评论列表</button>
<button @click="cname='PublicComments'">发布评论</button>
<keep-alive>
<component :is="cname"></component>
</keep-alive>
</div>
<script>
let List = {
template: "<div>列表组件</div>",
created() {
console.log("list created")
},
unmounted() {
console.log("list unmounted")
},
activated() {
console.log("list activated")
},
deactivated() {
console.log("list deactivated")
}
}
let PublicComments = {
template: `<div>发布评论组件
<input type='text' />
</div>`,
activated() {
console.log("PublicComments activated")
},
deactivated() {
console.log("PublicComments deactivated")
},
created() {
console.log("PublicComments created")
},
unmounted() {
console.log("PublicComments unmounted")
}
}
Vue.createApp({
components: {
List, PublicComments
},
data() {
return {
cname: "List"
}
},
}).mount("#box")
</script>
2、后台管理系统
方法一:
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #dcdedd;
}
#app {
width: 1200px;
height: 700px;
margin: 0 auto;
display: flex;
}
li {
list-style: none;
}
.right {
flex: 1;
}
ul {
height: 700px;
width: 250px;
background-color: #00152a;
color: #fff;
font-size: 20px;
}
ul>li {
width: 250px;
height: 60px;
text-align: center;
line-height: 60px;
margin: 10px 0;
cursor: pointer;
}
.active {
background-color: #006fb1;
}
.top {
width: 100%;
height: 80px;
background-color: #fff;
font-size: 30px;
line-height: 80px;
text-align: center;
}
.bottom>li {
height: 530px;
font-size: 30px;
line-height: 530px;
text-align: center;
background-color: #fff;
margin: 10px 0 10px 10px;
}
.Copyright {
width: 950px;
height: 70px;
font-size: 18px;
line-height: 70px;
text-align: center;
color: rgb(104, 103, 103);
background-color: #fff;
}
</style>
<div id="app">
<ul>
<li v-for="(item, index) in list" :key="item.id" @click="tab(index)" :class="{active:index === type}">
{{item.name}}
</li>
</ul>
<div class="right">
<Top></Top>
<ol class="bottom">
<li v-for="(item, index) in list" :key="item.id" v-show="index === type">
{{item.name}}
</li>
</ol>
<Bottom></Bottom>
</div>
</div>
<script>
const Top = {
template: `<div class="top">头部</div>`
}
const Bottom = {
template: `<div class="Copyright">© xxx公司版权所有</div>`
}
Vue.createApp({
components: {
Top, Bottom
},
data() {
return {
type: 1,
list: [
{ id: 1, name: '管理中心' },
{ id: 2, name: '商品管理' },
{ id: 3, name: '会员管理' },
{ id: 4, name: '订单管理' },
]
}
},
methods: {
tab(index) {
this.type = index
}
},
}).mount("#app")
</script>
方法二:动态组件
<style>
* {
padding: 0;
margin: 0;
}
html,
body,
#box {
height: 100%;
}
.layout {
display: flex;
height: 100%;
background: #ccc;
}
.nav {
text-align: center;
height: 100%;
background: #00152a;
color: white;
width: 200px;
font-size: 20px;
}
.nav li {
line-height: 50px;
height: 50px;
cursor: pointer;
}
li:hover {
background-color: #006fb1;
}
.header {
width: 100%;
height: 80px;
font-size: 20px;
line-height: 80px;
text-align: center;
font-weight: 600;
background-color: #fff;
}
.main {
flex: 1;
}
.footer {
height: 60px;
text-align: center;
line-height: 60px;
background-color: #fff;
}
.center {
background-color: #fff;
margin: 10px;
text-align: center;
font-size: 30px;
height: calc(100% - 80px - 60px);
}
</style>
<div id="box">
<Main-layout></Main-layout>
</div>
<script>
let ManageCenter = {
template: "<div class='center'>管理中心</div>"
}
let GoodsManage = {
template: "<div class='center'>商品管理</div>"
}
let MemberManage = {
template: "<div class='center'>会员管理</div>"
}
let OrderManage = {
template: "<div class='center'>订单管理</div>"
}
let MainLayout = {
components: {
ManageCenter, GoodsManage, MemberManage, OrderManage
},
data() {
return {
cname: "ManageCenter"
}
},
template: `<div class="layout">
<div class="nav">
<ul>
<li @click='cname="ManageCenter"'>管理中心</li>
<li @click='cname="GoodsManage"'>商品管理</li>
<li @click='cname="MemberManage"'>会员管理</li>
<li @click='cname="OrderManage"'>订单管理</li>
</ul>
</div>
<div class="main">
<div class="header">头部</div>
<component :is="cname"></component>
<div class="footer"> 版权 © 2022 </div>
</div>
</div>`
}
Vue.createApp({
components: {
MainLayout
}
}).mount("#box")
</script>
二、插槽
- 没有名字的插槽叫
匿名插槽
- 有名字的插槽叫
具名插槽
- 可以携带数据的插槽叫
作用域插槽或数据插槽
<div id="box">
{{str}}
<Com>
<template v-slot:default>
<span>用户名</span>
</template>
<template v-slot:btn="props">
<button @click="receive(props.n)">添加 </button>
</template>
</Com>
</div>
<script>
let Com = {
data() {
return {
txt: ""
}
},
template: `
<div>
<slot></slot>
<input type="text" v-model="txt" />
<slot name="btn" :n="txt"></slot>
</div>`
}
Vue.createApp({
components: {
Com
},
data() {
return {
str: ""
}
},
methods: {
receive(n) {
this.str = n;
}
}
}).mount("#box")
</script>