Evan's blog Evan's blog
首页
关于
  • 分类
  • 标签
  • 归档
  • H5&CSS3
  • JS
  • TS
  • Node
  • Webpack
  • Vue2
  • Vue3
  • 微信小程序
  • Andorid
  • Flutter
推荐
GitHub (opens new window)

conanan

真相只有一个
首页
关于
  • 分类
  • 标签
  • 归档
  • H5&CSS3
  • JS
  • TS
  • Node
  • Webpack
  • Vue2
  • Vue3
  • 微信小程序
  • Andorid
  • Flutter
推荐
GitHub (opens new window)
  • 基础

  • 组件

    • 父子组件通讯
    • 非父子组件通讯
    • 插槽
    • 动态组件
      • tabs 示例
      • keep-alive
      • 缓存组件的生命周期
      • 示例
    • 异步组件
    • 生命周期
    • 组件的v-model
  • 动画

  • Composition Api

  • 高级语法

  • Vue源码

  • VueCLI&Vite

  • VueRouter

  • Vuex

  • 项目

  • Vue3.x
  • 组件
xugaoyi
2022-01-31
目录

动态组件

# 动态组件

# tabs 示例

  • v-on 监听的事件也可能不一样!!
  • v-bind 绑定的数据也可能不一样
<template>
  <tabs v-for="pane of panes" :key="pane.key">
    <component :is="pane.component" v-on="pane.event" v-bind="propData" />
  </tabs>
</template>

<script>
import Main from './Main.vue'
import Add from './Add.vue'

export default {
  components: {
    Main,
    Add,
  },
  data() {
    return {
      propData: {
        id: '1',
        name: 'conanan',
      },
      panes: [
        {
          key: '1',
          tab: 'main页面',
          component: Main,
          event: { mainEvent1, mainEvent2 },
        },
        {
          key: '2',
          tab: 'add页面',
          component: Add,
          event: { addEvent },
        },
      ],
    }
  },
}
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# keep-alive

和上面tabs的实现方式不一样!!这里component只有一个!!!

在开发中某些情况我们希望继续保持组件的状态,而不是销毁掉,这个时候我们就可以使用一个内置组件: keep-alive

keep-alive有一些属性:

  • include - string | RegExp | Array。只有名称匹配的组件会被缓存;
  • exclude - string | RegExp | Array。任何名称匹配的组件都会被缓存;
  • max - number | string。最多可以缓存多少组件实例,一旦达到这个数字,那么缓存组件中最近没有被访问的实例会被销毁

include 和 exclude prop 允许组件有条件地缓存:

  • 二者都可以用逗号分隔字符串、正则表达式或一个数组来表示;
  • 匹配首先检查组件自身的 name 选项

# 缓存组件的生命周期

  • 对于缓存的组件来说,再次进入时,我们是不会执行created或者mounted等生命周期函数的

  • 但是有时候我们确实希望监听到何时重新进入到了组件,何时离开了组件

  • 这个时候我们可以使用 activated 和 deactivated 这两个生命周期钩子函数来监听

# 示例

App.vue

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

    <!-- 2.动态组件 -->
    <keep-alive include="home,about">
      <component :is="currentTab"
                 name="coderwhy"
                 :age="18"
                 @pageClick="pageClick">
      </component>
    </keep-alive>
    

    <!-- 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;
      },
      pageClick() {
        console.log("page内部发生了点击");
      }
    }
  }
</script>

<style scoped>
  .active {
    color: red;
  }
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

About.vue

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

<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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

Category.vue

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

<script>
  export default {
    name: "category",  
    data() {
      return {
        counter: 0
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Home.vue

<template>
  <div @click="divClick">
    Home组件: {{name}} - {{age}}
  </div>
</template>

<script>
  export default {
    name: "home",  
    props: {
      name: {
        type: String,
        default: ""
      },
      age: {
        type: Number,
        default: 0
      }
    },
    emits: ["pageClick"],
    methods: {
      divClick() {
        this.$emit("pageClick");
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
编辑 (opens new window)
上次更新: 2022/03/23, 17:55:39
插槽
异步组件

← 插槽 异步组件→

最近更新
01
重点
04-12
02
搭建项目
04-04
03
TS补充
03-30
更多文章>
Theme by Vdoing | Copyright © 2019-2022 conanan | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式