vue3组合式API

  • A+
所属分类:Web前端
摘要

为什么要用组合式API,我们来看看它是如何解决vue2的局限性的vue2组件采用配置式API,props,data,methods等相关的配置会被放在一起,导致同样的功能块分散,并和其他的功能块混合。我们希望统一功能块的代码可以放在一起,增加可读性

vue3组合式API

为什么要用组合式API,我们来看看它是如何解决vue2的局限性的

1.vue2的局限性

  1. 当组件内容越来越多,逻辑越来越复杂,可读性就会降低,并且难以维护。

vue2组件采用配置式API,props,data,methods等相关的配置会被放在一起,导致同样的功能块分散,并和其他的功能块混合。我们希望统一功能块的代码可以放在一起,增加可读性

vue3组合式API
  1. vue2的代码复用机制存在缺点,(Mixins)
  • 容易冲突
  • 依赖关系不明确,不易维护
  • 函数式的mixins不能在实例化过程中使用
  1. vue2对ts的支持度不够友好

2.组合式API的基本用法

组合式API是vue3新增的语法,它并没有替代vue2的配置API,vue2原先的用法不变。组合式API只是更高级的语法

1. setup和ref方法

 1<template>
2  <div>
3    <p>Capacity: {{ capacity }}</p>
4    <button @click="increaseCapacity()">Increase Capacity</button>
5    <h2>Attending</h2>
6    <ul>
7      <li v-for="(name, index) in attending" :key="index">{{ name }}</li>
8    </ul>
9  </div>
10</template>
11
12<script>
13import { ref } from "vue";
14export default {
15  setup() {
16    const capacity = ref(4);
17    function increaseCapacity({
18      capacity.value++;
19    }
20    const attending = ref(["Tim""Bob""Joe"]);
21    return { capacity, attending, increaseCapacity };
22  }
23};
24
</script>

使用ref创建响应式数据,模板中使用ref对象会自动结构[ref].value,不需要手写.value

2. reactive和computed方法

 1<template>
2  <p>Spaces Left: {{ spacesLeft }} out of {{ capacity }}</p>
3  <h2>Attending</h2>
4  <ul>
5    <li v-for="(name, index) in attending" :key="index">
6      {{ name }}
7    </li>
8  </ul>
9  <button @click="increaseCapacity()">Increase Capacity</button>
10</template>
11
12<script>
13import { reactive, computed, toRefs } from "vue";
14export default {
15  setup() {
16    const event = reactive({
17      capacity4,
18      attending: ["Tim""Bob""Joe"],
19      spacesLeft: computed(() => {
20        return event.capacity - event.attending.length;
21      })
22    });
23    function increaseCapacity({
24      event.capacity++;
25    }
26    return { ...toRefs(event), increaseCapacity };
27  }
28};
29
</script>

直接解构event会导致响应式失效,使用toRefs解构可以规避

3. 可复用的setup

 1<template>
2  ...
3</template>
4<script>
5import useEventSpace from "@/use/event-space";
6import useMapping from "@/use/mapping";
7export default {
8  setup() {
9    return { ...useEventSpace(), ...useMapping() }
10  }
11};
12</script>
13
14<!-- event-space.js -->
15import { ref, computed } from "vue";
16export default function useEventSpace({
17  const capacity = ref(4);
18  const attending = ref(["Tim""Bob""Joe"]);
19  const spacesLeft = computed(() => {
20    return capacity.value - attending.value.length;
21  });
22  function increaseCapacity({
23    capacity.value++;
24  }
25  return { capacity, attending, spacesLeft, increaseCapacity };
26}

4. setup中的生命周期

  • vue3中 beforeDestroy 和 destroyed 更名为 beforeUnmount 和 unmounted
  • setup中使用生命周期函数需在函数前加on
  • setup中不需要使用beforeCreate和created周期函数,- setup中函数的执行顺序是 beforeCreate() -> setup() -> created()
  • 新增两个生命周期:onRenderTracked 和 onRenderTriggered

5. watch

 1<template>
2  <div>
3    Search for <input v-model="searchInput" /> 
4    <div>
5      <p>Number of events: {{ results }}</p>
6    </div>
7  </div>
8</template>
9<script>
10import { ref, watch } from "@vue/composition-api";
11import eventApi from "@/api/event.js";
12export default {
13  setup() {
14    const searchInput = ref("");
15    const results = ref(0);
16    watch(() => {
17      results.value = eventApi.getEventCount(searchInput.value);
18    });
19    <span class="hljs-keyword">return</span> { searchInput, results };
20  }
21};
22
</script>
23
24<!-- watch 传参 -->
25watch(searchInput, (newVal, oldVal) => {
26  ...
27});
28watch([firstName, lastName], ([newFirst, newLast], [oldFirst, oldLast]) => {
29  ...   
30});

vue3组合式API