yayxs / front-end-video-tutorial

前端知识视频化 / 视频分享 / 视频教程
11 stars 3 forks source link

【vue3、vue-next】Vue Composition API Learning #4

Open yayxs opened 4 years ago

yayxs commented 4 years ago

前言

不知道在哪个瞬间,尤大 发了一条微博,我就知道"大事不妙"。要来了……千呼万唤始出来vue3 就在这个特别的日子发布了。

最核心的一点便是Composition API ,在本文咱们先揭开它的面纱,简单的进行横向对比一下,最后我们将一同构建两个版本:一个使用Composition API,另一个使用基于Options API

Composition API

什么是Composition API

新的api 并不会破坏当前2.x 的代码,甚至可以继续使用,新的方式是为了解决vue2.x 一些限制

简言之,vue 3 并没有新增什么新的内容,或者说vue 把一些内部的功能暴露出来,提供给开发者,让我们可以屁颠屁颠的直接在组件中使用。

为什么大费周折改变

一程不变是好事,但在开发中,对于一个问题的解决方式一定要精益求精,不断的寻求更优解,这也是开发者的精神吧,我想

在2.x的版本中,我们使用data watch methods 以及各种生命周期,就像这样

20200430172328

正式因为如此,我们很难通过一个庞大而复杂的文件中读取分组,我们经常会来回的滚动,另一个缺点是,由于在组件中无法直观的拆分,因此逻辑重用变得十分的困难

初始vue3

<template>
  <button @click="increment">
    当前的状态是: {{ state.count }}, 当前的状态乘以2计算得{{ state.double }}
  </button>
</template>

<script>
import { reactive, computed } from "vue";

export default {
  setup() {
    const state = reactive({
      count: 0,
      double: computed(() => state.count * 2),
    });

    function increment() {
      state.count++;
    }

    return {
      state,
      increment,
    };
  },
};
</script>

通过一个简单的案例,可以得知一个新的apisetup() , 包括状态也好,点击的事件函数也好都是书写在此函数内。这显得与vue 2.x 有点差异,之前的写法我们会把一些方法写在 methods 中,那么这样就会有一个问题,随着项目越来越大,组件变得越来越长,后期维护的时候,

typescript支持

vue 3 可以更好的支持typescript ,我们知道ts 有着较好的类型推断

那么当前有什么问题呢,

vue-class-component

当前很多开发者正在或即将使用类组件 ,那么在vue 3 实现细节上仍然有很多的不确定性,这变成了一个较为危险的行为

目前的最新api 大多是使用普通的变量和函数,类型较为友好,使得开发者可以尽情的享受类型推断带来的快感

那么,这种class-component 的这种方式我们还可以继续使用吗,目前为止,仍然继续可以使用,但是不推荐

横向对比

当然了我们在对比的时候,不得不拿出,这两张图

让我们构建一个简单的组件,该组件允许用户按下按钮即可添加两个数字。首先,我们将快速回顾如何使用基于options的API来完成此操作。然后,我们将使用Composition API重建相同的组件,以说明差异。

使用Options API构建

 data() {
    return {
      num1: 0,
      num2: 0,
      sum: 0,
    };
  },
  methods: {
    addNumbers() {
      this.sum = parseInt(this.num1) + parseInt(this.num2);
    },
  },

使用基于Vue 2选项的API,我们在data()函数中返回了反应数据对象。然后,该AddNumbers()功能将在methods属性中注册。要从中访问变量data(),必须使用this

现在,this它嵌套在方法内部,因此它应该引用方法的对象而不是整个实例,但不是。Vue正在这里进行幕后工作,以便为我们解决这个问题。通常,这非常简单直观,但是在更复杂的情况下,这种幕后处理可能会导致的意外行为this

这也正是我们上文提到的关于typescript 的支持

使用Composition API构建

在使用vue3 之前,官方已经给我们准备好了vue-cli-plugin-vue-next , 熟悉vue 脚手架的人对于此并不陌生,我们可以通过

vue add vue-next

来在项目里使用vue3 ,这样能够很轻松的把vue 2.x 的项目转换为 vue 3项目

main.js

import { createApp } from 'vue';
import App from './App.vue'

createApp(App).mount('#app')

我们可以看到在挂载的时候是不一样的, 这里的不一样大概指得是用法不一样,

在之前的版本

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

核心API

vue 2.x 我们都知道一些常用的api ,那么在最新版本的vue中(基本大的框架与语法已经成型)会多哪些新的api呢,

疑问:到底vue3 是不是多了新的api

ref

import {ref} from 'vue'
// ……
let num3 = ref(0);
let num4 = ref(0);
let sum1 = ref(0);

所有内容现在都在setup()函数内。模板中需要使用的所有函数或属性都应加入,setup()因为这是将它们返回模板的方式。

还有一个函数,单独的挂出,并不是写在methods中,现在,我们可以轻松地在组件实例之间重用我们的功能,这将显着提高大型代码库的可读性。还请注意,this不再需要引用变量!

  function addNumbersVue3() {
            sum1.value = parseInt(num3.value) + parseInt(num4.value);
        }

最后,我们将函数和属性返回到模板。

 return {
            num3,
            num4,
            sum1,
            addNumbersVue3
        }

这里的一件事是ref在变量中使用let num1 = ref(0)。这就是我们使变量具有反应性的方式!有两个函数可用于处理状态和反应性:refreactive

特点

computed

有时候我们需要依赖其他状态,在vue 中是通过计算属性来处理。我们起初的时候,是直接通过一个方法来计算两者之和,这是为了更好的来演示用。接下来我们使用computed()

import { computed } from 'vue'
let sum1 = computed(() => parseInt(num3.value) + parseInt(num4.value));

sum1是一个我们称为“ ref”的对象,因为它用作对其持有的内部值的反应性引用。

reactive

反应性 反应状态 副作用 的意思

import { reactive } from 'vue'

// reactive state
const state = reactive({
  count: 0
})

其中state 便是反应性对象,类似,

data(){
    return {
        count:0
    }
}

watchEffect

根据反应状态重新应用副作用

参考