此时我们点击上方三个按钮,下面内容需要与之对应切换对应的组件。

1、最简单的方式是通过v-if来判断,从而显示不同的组件。 

//App.vue
<template>
  <div>
    <button v-for="item in tabs" :key="item"
            @click="itemClick(item)"
            :class="{active: currentTab === item}">
      {{item}}
    </button>

    <!-- 1.v-if的判断实现 -->
    <template v-if="currentTab === 'home'">
      <home></home>
    </template>
    <template v-else-if="currentTab === 'about'">
      <about></about>
    </template>
    <template v-else>
      <category></category>
    </template>
  </div>
</template>

<script>
  import Home from './pages/Home.vue';
  import About from './pages/About.vue';
  import Category from './pages/Category.vue';

  export default {
    components: {
      Home,
      About,
      Category
    },
    data() {
      return {
        tabs: ["home", "about", "category"],
        currentTab: "home"
      }
    },
    methods: {
      itemClick(item) {
        this.currentTab = item;
      },
    }
  }
</script>

<style scoped>
  .active {
    color: red;
  }
</style>

2、通过动态组件的方式

动态组件是使用component组件,通过一个特殊的attribute is来实现:

//App.vue
<template>
  <div>
    <button v-for="item in tabs" :key="item"
            @click="itemClick(item)"
            :class="{active: currentTab === item}">
      {{item}}
    </button>

    <!-- 2.动态组件 -->
    component :is="currentTab"</component>
</template>

currentTab === item动态的选择点击的组件名称,然后:is="currentTab"动态切换到对应组件。如果我们需要给动态组件传参和监听事件,我们需要将属性和监听事件放到component上来使用。

<component :is="currentTab"
                 name="pp"
                 :age="18"
                 @pageClick="pageClick">
</component>

动态组件这样写完之后就能实现点击按钮跳转对应组件的事件,但是开发时,我们通常会在跳转到这个组件之后用户对组件内部做了一些更改,并且希望是默认保存:即切换了别的组件又切换回来时这个改过的数据依旧存在。这样我们就可以通过keep-alive属性来实现:

例如:对About组件增加一个点击按钮,点击可以递增。

//About.vue
<template>
  <div>
    About组件
    <button @click="counter++">{{counter}}</button>
  </div>
</template>

<script>
  export default {
    name: "about",  
    data() {
      return {
        counter: 0
      }
    },
  }
</script>
<style scoped></style>

此时我们将数字点击到10,切换到home组件后,about组件就会被销毁,再次点击about组件切换回来时会重新创建组件,即之前点到10的about组件不会被保存,重新变成了0. 

在开发中某些情况我们希望继续保持组件的状态,而不是销毁掉,这个时候我们就可以 使用一个内置组件: keep-alive
//App.vue
<keep-alive include="home,about">
      <component :is="currentTab"
                 name="pp"
                 :age="18"
                 @pageClick="pageClick">
      </component>
</keep-alive>
keep-alive有一些属性:
include: 只有名称匹配的组件会被缓 存;
exclude:任何名称匹配的组件都不会被缓存;
max: 最多可以缓存多少组件实例,一旦达 到这个数字,那么缓存组件中最近没有被访问的实例会被销毁;
对于缓存的组件来说,再次进入时,我们是 不会执行created或者mounted等生命周期函数 的:
      但是有时候我们确实希望监听到何时重新进入到了组件,何时离开了组件;
      这个时候我们可以使用 activated 和 deactivated 这两个生命周期钩子函数来监听;
//About.vue
<script>
  export default {
    name: "about",  
    data() {
      return {
        counter: 0
      }
    },
    created() {
      console.log("about created");
    },
    unmounted() {
      console.log("about unmounted");
    },
    activated() {
      console.log("about activated");
    },
    deactivated() {
      console.log("about deactivated");
    }
  }
</script>
Vue中实现异步组件
如果我们的项目过大了,对于 某些组件 我们希望 通过异步的方式来进行加载 (目的是可以对其进行分包处理),那么Vue中给我们提供了一个函数:defineAsyncComponent
defineAsyncComponent接受两种类型的参数:
类型一:工厂函数,该工厂函数返回一个Promise对象:
<template>
  <div>
    App组件
    <async-category></async-category>
  </div>
</template>

<script>
  import { defineAsyncComponent } from 'vue';
  const AsyncCategory = defineAsyncComponent(() => import("./AsyncCategory.vue"))
  export default {
    components: {
      AsyncCategory,
    }
  }
</script>
<style scoped></style>

类型二:接受一个对象类型,对异步函数进行配置:

<script>
  import { defineAsyncComponent } from 'vue';  

  import Loading from './Loading.vue';
  const AsyncCategory = defineAsyncComponent({
    loader: () => import("./AsyncCategory.vue"),
    //加载过程中显示的组件
    loadingComponent: Loading,
    //加载失败时显示的组件
    // errorComponent:Error,
    // 在显示loadingComponent组件之前, 等待多长时间
    delay: 2000,
    //定义组件是否可挂起|默认值:true
    suspensible:true
    /**
     * err: 错误信息,
     * retry: 函数, 调用retry尝试重新加载
     * attempts: 记录尝试的次数
     */
    onError: function(err, retry, attempts) {

    }
  })
</script>
异步组件和Suspense

 

Logo

前往低代码交流专区

更多推荐