• 动态组件<component>


    用法:

    1. <template>
    2. <div>
    3. <Navbar>Navbar>
    4. <Home v-if="componentName == '首页'">Home>
    5. <List v-else-if="componentName == '列表'">List>
    6. <Center v-else-if="componentName == '我的'">Center>
    7. <Tabbar>Tabbar>
    8. <Navbar>Navbar>
    9. <component :is="componentName">component>
    10. <Tabbar>Tabbar>
    11. div>
    12. template>
    13. <script>
    14. import store from "./components/store";
    15. import Navbar from "./components/Navbar.vue" //导入Navbar组件模板
    16. import Home from "./components/Home.vue";
    17. import List from "./components/List.vue";
    18. import Center from "./components/Center.vue";
    19. import Tabbar from "./components/Tabbar.vue";
    20. export default {
    21. inheritAttrs: false,
    22. data() {
    23. return {
    24. nvaTitle: "首页",
    25. componentName: "Home"
    26. }
    27. },
    28. components: {
    29. Navbar,
    30. Home,
    31. List,
    32. Center,
    33. Tabbar
    34. },
    35. provide() {
    36. return {
    37. app: this, //向外提供一个值,这个值的名称是我们自己定义的,this表示当前根组件对象(可以供其他组件可以直接获取到)
    38. }
    39. },
    40. mounted() { //钩子函数,项目已启动则订阅
    41. var obj = {
    42. "我的": "Home",
    43. "列表": "List",
    44. "首页": "Center"
    45. }
    46. //订阅
    47. store.subscribe((name) => { //参数name传递的值其实就是"我的","列表","首页"
    48. this.componentName = obj[name] //如果name是"我的",那么obj[name] 的值就是Home,
    49. })
    50. }
    51. }
    52. script>

    案例

    我有7个组件 App.vue是根组件,它里面有5个子组件Navbar,Home,List,Center,Tabbar

    其中Navbar是导航,Tabbar是底部,Home,List, Center则是内容。

    现在是点击底部Tabbar组件中的【首页,列表,我的】要显示不同的内容:

    如点击【首页】中间应该显示的是Home组件

    如点击【列表】中间应该显示的是List组件

    如点击【我的】中间应该显示的是Center组件

    如下图

    App.vue

    1. <template>
    2. <div>
    3. <Navbar>Navbar>
    4. <component :is="componentName">component>
    5. <Tabbar>Tabbar>
    6. div>
    7. template>
    8. <script>
    9. import store from "./components/store";
    10. import Navbar from "./components/Navbar.vue" //导入Navbar组件模板
    11. import Home from "./components/Home.vue";
    12. import List from "./components/List.vue";
    13. import Center from "./components/Center.vue";
    14. import Tabbar from "./components/Tabbar.vue";
    15. export default {
    16. inheritAttrs: false,
    17. data() {
    18. return {
    19. nvaTitle: "首页",
    20. componentName: "Home"
    21. }
    22. },
    23. components: {
    24. Navbar,
    25. Home,
    26. List,
    27. Center,
    28. Tabbar
    29. },
    30. provide() {
    31. return {
    32. app: this, //向外提供一个值,这个值的名称是我们自己定义的,this表示当前根组件对象(可以供其他组件可以直接获取到)
    33. }
    34. },
    35. mounted() { //钩子函数,项目已启动则订阅
    36. var obj = {
    37. "我的": "Home",
    38. "列表": "List",
    39. "首页": "Home"
    40. }
    41. //订阅
    42. store.subscribe((name) => { //参数name传递的值其实就是"我的","列表","首页"
    43. this.componentName = obj[name] //如果name是"我的",那么obj[name] 的值就是Home,
    44. })
    45. }
    46. }
    47. script>

    Navbar.vue

    1. <template>
    2. <div>
    3. <button>返回button>
    4. <span>{{nvaTitle}}span>
    5. <button>首页button>
    6. div>
    7. template>
    8. <script>
    9. import store from "./store"
    10. export default {
    11. data(){
    12. return{
    13. nvaTitle:"首页"
    14. }
    15. },
    16. components: {
    17. },
    18. mounted(){
    19. store.subscribe(this.mysubscribe)
    20. },
    21. methods:{
    22. mysubscribe(value){
    23. this.nvaTitle=value
    24. }
    25. }
    26. }
    27. script>
    28. <style scoped>
    29. div {
    30. display: flex;
    31. width: 100%;
    32. justify-content: space-between;
    33. height: 50px;
    34. line-height: 50px;
    35. background: gray;
    36. }
    37. style>

    Tabbar.vue

    1. <template>
    2. <ul>
    3. <TabbarItem v-for="item in datalist" :key="item" :itemStr="item">TabbarItem>
    4. ul>
    5. template>
    6. <script>
    7. import TabbarItem from "./TabbarItem.vue"
    8. export default {
    9. data() {
    10. return {
    11. datalist: ["首页", "列表", "我的"]
    12. }
    13. },
    14. components: {
    15. TabbarItem
    16. }
    17. }
    18. script>
    19. <style scoped>
    20. ul {
    21. display: flex;
    22. position: fixed;
    23. bottom: 0;
    24. width: 100%;
    25. height: 50px;
    26. line-height: 50px;
    27. }
    28. li {
    29. flex: 1;
    30. text-align: center;
    31. }
    32. style>

    TabbarItem.vue

    1. <template>
    2. <li @click="handelClick">
    3. {{ itemStr }}
    4. li>
    5. template>
    6. <script >
    7. import store from "./store"
    8. export default {
    9. props: ["itemStr"],
    10. inject: ["app"],//在App.vue根组件中通过provide向外提供了一个app的值,我们可以通过注入的方式获取
    11. methods: {
    12. handelClick() {
    13. //this.app.nvaTitle = this.itemStr //这个app就是根组件,根组件中有一个nvaTitle的对象,我们可以重新给他赋值,它的值变化后就会自动流向需要这个值的子组件。
    14. store.publish(this.itemStr);
    15. this.app.nvaTitle = this.itemStr;
    16. }
    17. }
    18. }
    19. script>

    Home.vue

    1. <template>
    2. <div>
    3. Home
    4. div>
    5. template>

    List.vue

    1. <template>
    2. <div>
    3. List
    4. div>
    5. template>

    Center.vue

    1. <template>
    2. <div>
    3. Center
    4. div>
    5. template>

    store.js

    1. export default {
    2. datalist: [], //存放带一个参数的函数集合
    3. //订阅
    4. subscribe(fun) {
    5. this.datalist.push(fun) //将一个带一个参数的函数添加到datalist中
    6. },
    7. //发布
    8. publish(value) {
    9. this.datalist.forEach(fun=>{
    10. fun(value) //遍历datalist中的函数并且立即执行 (函数带几个参数需要自己根据自己的实际情况来决定)
    11. })
    12. }
    13. }

    动态组件的数据缓存

    我在Home组件的input中填写了数据,当切换到List组件中,再返回Home组件,需要保持之前填写的数据还在,那么就需要用到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

    案列

    父组件

    1. <template>
    2. <div>
    3. <Navbar>Navbar>
    4. <KeepAlive include="home,list">
    5. <component :is="componentName">component>
    6. KeepAlive>
    7. <Tabbar>Tabbar>
    8. div>
    9. template>
    10. <script>
    11. import store from "./components/store";
    12. import Navbar from "./components/Navbar.vue" //导入Navbar组件模板
    13. import Home from "./components/Home.vue";
    14. import List from "./components/List.vue";
    15. import Center from "./components/Center.vue";
    16. import Tabbar from "./components/Tabbar.vue";
    17. export default {
    18. inheritAttrs: false,
    19. data() {
    20. return {
    21. nvaTitle: "首页",
    22. componentName: "Home"
    23. }
    24. },
    25. components: {
    26. Navbar,
    27. Home,
    28. List,
    29. Center,
    30. Tabbar
    31. },
    32. provide() {
    33. return {
    34. app: this, //向外提供一个值,这个值的名称是我们自己定义的,this表示当前根组件对象(可以供其他组件可以直接获取到)
    35. }
    36. },
    37. mounted() { //钩子函数,项目已启动则订阅
    38. var obj = {
    39. "我的": "Center",
    40. "列表": "List",
    41. "首页": "Home"
    42. }
    43. //订阅
    44. store.subscribe((name) => { //参数name传递的值其实就是"我的","列表","首页"
    45. this.componentName = obj[name] //如果name是"我的",那么obj[name] 的值就是Home,
    46. })
    47. }
    48. }
    49. script>

    Home子组件