用法:
<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>
案例
我有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中的函数并且立即执行 (函数带几个参数需要自己根据自己的实际情况来决定)
})
}
}