动态组件的使用方式:
<template>
<div>
<Navbar></Navbar>
<Home v-if="componentName == '首页'"></Home>
<List v-else-if="componentName == '列表'"></List>
<Center v-else-if="componentName == '我的'"></Center>
<Tabbar></Tabbar>
<!--我们发现上面有5个组件,其中Home,List,Center三个组件会根据v-if条件渲染,
最终只会有一个组件渲染出来,那我们可以改成动态组件来表示,代码如下-->
<Navbar></Navbar>
<!--这个componentName就是组件的名称比如你的子组件名称叫Navbar那他就是Navbar-->
<!--is表示你这个动态组件应该是一个什么组件?如果是Home则会渲染成Home组件-->
<component :is="componentName"></component>
<Tabbar></Tabbar>
</div>
</template>
<script>
import store from "./components/store";
import Navbar from "./components/Navbar.vue" //导入Navbar组件模板
import Home from "./components/Home.vue";
import List from "./components/List.vue";
import Center from "./components/Center.vue";
import Tabbar from "./components/Tabbar.vue";
export default {
inheritAttrs: false,
data() {
return {
nvaTitle: "首页",
componentName: "Home"
}
},
components: {
Navbar,
Home,
List,
Center,
Tabbar
},
provide() {
return {
app: this, //向外提供一个值,这个值的名称是我们自己定义的,this表示当前根组件对象(可以供其他组件可以直接获取到)
}
},
mounted() { //钩子函数,项目已启动则订阅
var obj = {
"我的": "Home",
"列表": "List",
"首页": "Center"
}
//订阅
store.subscribe((name) => { //参数name传递的值其实就是"我的","列表","首页"
this.componentName = obj[name] //如果name是"我的",那么obj[name] 的值就是Home,
})
}
}
</script>
动态组件的使用案例
我有7个组件 App.vue是根组件,它里面有5个子组件Navbar,Home,List,Center,Tabbar
其中Navbar是导航,Tabbar是底部,Home,List, Center则是内容。
现在是点击底部Tabbar组件中的【首页,列表,我的】要显示不同的内容:
如点击【首页】中间应该显示的是Home组件
如点击【列表】中间应该显示的是List组件
如点击【我的】中间应该显示的是Center组件
如下图
App.vue
<template>
<div>
<!-- <Navbar></Navbar>
<Home v-if="componentName == '首页'"></Home>
<List v-else-if="componentName == '列表'"></List>
<Center v-else-if="componentName == '我的'"></Center>
<Tabbar></Tabbar> -->
<!--我们发现上面有5个组件,其中Home,List,Center三个组件会根据v-if条件渲染,
最终只会有一个组件渲染出来,那我们可以改成动态组件来表示,代码如下-->
<Navbar></Navbar>
<!--这个componentName就是组件的名称比如你的子组件名称叫Navbar那他就是Navbar-->
<!--is表示你这个动态组件应该是一个什么组件?如果是Home则会渲染成Home组件-->
<component :is="componentName"></component>
<Tabbar></Tabbar>
</div>
</template>
<script>
import store from "./components/store";
import Navbar from "./components/Navbar.vue" //导入Navbar组件模板
import Home from "./components/Home.vue";
import List from "./components/List.vue";
import Center from "./components/Center.vue";
import Tabbar from "./components/Tabbar.vue";
export default {
inheritAttrs: false,
data() {
return {
nvaTitle: "首页",
componentName: "Home"
}
},
components: {
Navbar,
Home,
List,
Center,
Tabbar
},
provide() {
return {
app: this, //向外提供一个值,这个值的名称是我们自己定义的,this表示当前根组件对象(可以供其他组件可以直接获取到)
}
},
mounted() { //钩子函数,项目已启动则订阅
var obj = {
"我的": "Home",
"列表": "List",
"首页": "Home"
}
//订阅
store.subscribe((name) => { //参数name传递的值其实就是"我的","列表","首页"
this.componentName = obj[name] //如果name是"我的",那么obj[name] 的值就是Home,
})
}
}
</script>
Navbar.vue
<template>
<div>
<button>返回</button>
<span>{{nvaTitle}}</span>
<button>首页</button>
</div>
</template>
<script>
import store from "./store"
export default {
data(){
return{
nvaTitle:"首页"
}
},
components: {
},
mounted(){
store.subscribe(this.mysubscribe)
},
methods:{
mysubscribe(value){
this.nvaTitle=value
}
}
}
</script>
<style scoped>
div {
display: flex;
width: 100%;
justify-content: space-between;
height: 50px;
line-height: 50px;
background: gray;
}
</style>
Tabbar.vue
<template>
<ul>
<TabbarItem v-for="item in datalist" :key="item" :itemStr="item"></TabbarItem>
</ul>
</template>
<script>
import TabbarItem from "./TabbarItem.vue"
export default {
data() {
return {
datalist: ["首页", "列表", "我的"]
}
},
components: {
TabbarItem
}
}
</script>
<style scoped>
ul {
display: flex;
position: fixed;
bottom: 0;
width: 100%;
height: 50px;
line-height: 50px;
}
li {
flex: 1;
text-align: center;
}
</style>
TabbarItem.vue
<template>
<li @click="handelClick">
{{ itemStr }}
</li>
</template>
<script >
import store from "./store"
export default {
props: ["itemStr"],
inject: ["app"],//在App.vue根组件中通过provide向外提供了一个app的值,我们可以通过注入的方式获取
methods: {
handelClick() {
//this.app.nvaTitle = this.itemStr //这个app就是根组件,根组件中有一个nvaTitle的对象,我们可以重新给他赋值,它的值变化后就会自动流向需要这个值的子组件。
store.publish(this.itemStr);
this.app.nvaTitle = this.itemStr;
}
}
}
</script>
Home.vue
<template>
<div>
Home
</div>
</template>
List.vue
<template>
<div>
List
</div>
</template>
Center.vue
<template>
<div>
Center
</div>
</template>
store.js
export default {
datalist: [], //存放带一个参数的函数集合
//订阅
subscribe(fun) {
this.datalist.push(fun) //将一个带一个参数的函数添加到datalist中
},
//发布
publish(value) {
this.datalist.forEach(fun=>{
fun(value) //遍历datalist中的函数并且立即执行 (函数带几个参数需要自己根据自己的实际情况来决定)
})
}
}
动态组件的数据缓存<KeepAlive>
我在Home组件的input中填写了数据,当切换到List组件中,再返回Home组件,需要保持之前填写的数据还在,那么就需要用到KeepAlive
<KeepAlive>是让他包裹的组件保持活着,而不是切换组件的时候将其它组件移除
include属性表示哪些组件需要缓存。 三种写法:include="home,list" 或者 include=["home,list"] 或者 include="/home|list/" 这里我需要home和list组件需要缓存,
exclude属性表示哪些缓存不需要缓存。三种写法:exclude="home,list" 或者 exclude=["home,list"] 或者 exclude="/home|list/" 这里我需要home和list组件不需要缓存,
注意:当用到include或exclude后,需要component动态组件所需要表示的组件中给他取一个名字 举列:在Home组件中给Home组件取一个名叫home,取List组件中给他取一个名字叫list,去Center组件中给他取一个名字叫center
案列
父组件
<template>
<div>
<Navbar></Navbar>
<!--我有个需求:因为Home,List,Center组件是会随时切换的,点下【我的】就会切换到Home组件,点下【列表】就会切换到List组件,
我在Home组件的input中填写了数据,当切换到List组件中,再返回Home组件,需要保持之前填写的数据还在,那么就需要用到KeepAlive
<KeepAlive>是让他包裹的组件保持活着,而不是切换组件的时候将其它组件移除
include属性表示哪些组件需要缓存。 三种写法:include="home,list" 或者 include=["home,list"] 或者 include="/home|list/" 这里我需要home和list组件需要缓存,
exclude属性表示哪些缓存不需要缓存。三种写法:exclude="home,list" 或者 exclude=["home,list"] 或者 exclude="/home|list/" 这里我需要home和list组件不需要缓存,
注意:当用到include或exclude后,需要component动态组件所需要表示的组件中给他取一个名字 举列:在Home组件中给Home组件取一个名叫home,取List组件中给他取一个名字叫list,去Center组件中给他取一个名字叫center
-->
<KeepAlive include="home,list"> <!-- <KeepAlive exclude="center"></KeepAlive> -->
<component :is="componentName"></component>
</KeepAlive>
<Tabbar></Tabbar>
</div>
</template>
<script>
import store from "./components/store";
import Navbar from "./components/Navbar.vue" //导入Navbar组件模板
import Home from "./components/Home.vue";
import List from "./components/List.vue";
import Center from "./components/Center.vue";
import Tabbar from "./components/Tabbar.vue";
export default {
inheritAttrs: false,
data() {
return {
nvaTitle: "首页",
componentName: "Home"
}
},
components: {
Navbar,
Home,
List,
Center,
Tabbar
},
provide() {
return {
app: this, //向外提供一个值,这个值的名称是我们自己定义的,this表示当前根组件对象(可以供其他组件可以直接获取到)
}
},
mounted() { //钩子函数,项目已启动则订阅
var obj = {
"我的": "Center",
"列表": "List",
"首页": "Home"
}
//订阅
store.subscribe((name) => { //参数name传递的值其实就是"我的","列表","首页"
this.componentName = obj[name] //如果name是"我的",那么obj[name] 的值就是Home,
})
}
}
</script>
Home子组件
<template>
<div>
Home
<input type="text">
</div>
</template>
<script>
export default{
name:"home" //组件的名称叫home
}
</script>
List子组件
<template>
<div>
List
<input type="text">
</div>
</template>
<script>
export default{
name:"list" //组件的名称叫list
}
</script>
Center子组件
<template>
<div>
Center
<input type="text">
</div>
</template>
<script>
export default{
name:"center" //组件的名称叫center
}
</script>