当前位置: 首页 > article >正文

动态组件<component>

用法:

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


http://www.kler.cn/a/105440.html

相关文章:

  • 【概率论教程01】对贝叶斯定理的追忆
  • mongodb数据迁移的方法
  • Linux ———— 用户-组
  • 0基础学习PyFlink——用户自定义函数之UDAF
  • Android开发基础:SharedPreferences的使用
  • HarmonyOS鸿蒙原生应用开发设计- 流转图标
  • menuconfig 图形化配置原理说明三
  • 【经验分享】openGauss容灾集群搭建
  • android开发使用OkHttp自带的WebSocket实现IM功能
  • 了解神经网络
  • python:使用Flask-SQLAlchemy对数据库增删改查的简单示例
  • YouTrack 中如何设置邮件通知
  • 非小米笔记本小米妙享中心安装最新教程 3.2.0.464 兼容所有Windows系统
  • 13.4web自动化测试(Selenium3+Java)
  • [SpringCloud] Eureka 与 Ribbon 简介
  • linux deepin系统 php多版本
  • 1125:矩阵乘法《详解》
  • CCF CCSP2023参赛记 + 算法题题解
  • 【ARM Cortex-M 系列 4 番外篇 -- 常用 benchmark 介绍】
  • 行为型模式-策略模式