2021通过Vue2.x对比学习Vue3.x(持续更新)

简介: 2021通过Vue2.x对比学习Vue3.x(持续更新)

写在前面


小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

一、前言


Vue3.x从2020年9月18日发布第一个One Piece版本,到现在一直在更新优化;中文版的官方文档也已经放出;那么作为终端用户的我们来看下Vue3.x新增了哪些功能和特性。今天小编就带大家通过和Vue2.x的对比一起来学习入门。

注意: Vue3.x 是兼容 Vue2.x 版本的,也就是说我们再日常工作中 可以在 Vue3.x 中使用 Vue2.x 的相关语法 但是当你真正开始使用 Vue3 写项目时 你会发现他比 Vue2.x 方便很多

二、Vue3.x优点


  • Performance:性能优化
  • Tree-shaking support:支持摇树优化
  • Composition API:组合API
  • Fragment,Teleport,Suspense:新增的组件
  • Better TypeScript support:更好的TypeScript支持
  • Custom Renderer API:自定义渲染器

三、环境要求


  • Node.js 版本 >= 12.0.0

四、包管理器


包管理器它可以让你使用并分享 全世界开发者的(例如 JavaScript)代码常用的有以下几种:


4.1 [npm]


4.2 yarn


  • 稳定版: v1.22.4
  • Node 版本支持:  ^4.8.0 || ^5.7.0 || ^6.2.2 || >=8.0.0
  • 安装方式:在 Windows 系统中有三种安装 Yarn 的方式

4.3 [pnpm]


4.4 [yi]


五、脚手架


脚手架作为项目工程创建的入口,可快速创建标准的Vue项目,下面从脚手架的按照方面加以说明。


5.1 Vue2.x


  1. 全局安装Vue2.x脚手架
yarn global add vue/cli
# 或
npm install -g vue/cli

5.2 Vue3.x


  1. 全局安装Vue3.x脚手架
yarn global add @vue/cli
# OR 
yarn global add @vue/cli@next
# 或
npm install -g @vue/cli
  1. 然后在 Vue 项目中运行
vue upgrade --next
  1. 项目创建
vue create my-project
  1. 配置项选择
Vue CLI v5.0.0-beta.7
? Please pick a preset: (Use arrow keys)
> ts-admin ([Vue 2] less, babel, typescript, pwa, router, vuex, eslint, unit-jest)
  vue3-ts-admin ([Vue 2] typescript, pwa, router, vuex, eslint)
  Default ([Vue 2] babel, eslint)
  Default (Vue 3) ([Vue 3] babel, eslint)
  Manually select features
  1. 选择 Manually select features
Vue CLI v5.0.0-beta.7
? Please pick a preset: Manually select features
? Check the features needed for your project:
 (*) Choose Vue version
 (*) Babel
 (*) TypeScript
 (*) Progressive Web App (PWA) Support
 (*) Router
 (*) Vuex
 (*) CSS Pre-processors
 (*) Linter / Formatter
 (*) Unit Testing
 (*) E2E Testing
  1. Choose Vue version
Vue CLI v5.0.0-beta.7
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Lint
er, Unit, E2E
? Choose a version of Vue.js that you want to start the project with
  2.x
> 3.x
  1. Use class-style component syntax?
Vue CLI v5.0.0-beta.7
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Lint
er, Unit, E2E
? Choose a version of Vue.js that you want to start the project with 3.x
? Use class-style component syntax? (y/N)
  1. babel
Vue CLI v5.0.0-beta.7
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Lint
er, Unit, E2E
? Choose a version of Vue.js that you want to start the project with 3.x
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (Y/n)
  1. Use history mode for router?
Vue CLI v5.0.0-beta.7
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Lint
er, Unit, E2E
? Choose a version of Vue.js that you want to start the project with 3.x
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)
  1. Pick a CSS pre-processor
Vue CLI v5.0.0-beta.7
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Lint
er, Unit, E2E
? Choose a version of Vue.js that you want to start the project with 3.x
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys)
> Sass/SCSS (with dart-sass)
  Less
  Stylus
  1. Pick a linter / formatter config
Vue CLI v5.0.0-beta.7
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Lint
er, Unit, E2E
? Choose a version of Vue.js that you want to start the project with 3.x
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Less
? Pick a linter / formatter config:
  ESLint with error prevention only
  ESLint + Airbnb config
> ESLint + Standard config
  ESLint + Prettier
  1. Pick additional lint features
Vue CLI v5.0.0-beta.7
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Lint
er, Unit, E2E
? Choose a version of Vue.js that you want to start the project with 3.x
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Less
? Pick a linter / formatter config: Standard
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
>(*) Lint on save
 ( ) Lint and fix on commit
  1. Pick a unit testing solution
Vue CLI v5.0.0-beta.7
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Lint
er, Unit, E2E
? Choose a version of Vue.js that you want to start the project with 3.x
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Less
? Pick a linter / formatter config: Standard
? Pick additional lint features: Lint on save, Lint and fix on commit
? Pick a unit testing solution: (Use arrow keys)
> Jest
  Mocha + Chai
  1. Cypress
Vue CLI v5.0.0-beta.7
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Lint
er, Unit, E2E
? Choose a version of Vue.js that you want to start the project with 3.x
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Less
? Pick a linter / formatter config: Standard
? Pick additional lint features: Lint on save, Lint and fix on commit
? Pick a unit testing solution: Jest
? Pick an E2E testing solution: (Use arrow keys)
> Cypress (Test in Chrome, Firefox, MS Edge, and Electron)
  Nightwatch (WebDriver-based)
  WebdriverIO (WebDriver/DevTools based)
  1. Where do you prefer placing config for Babel, ESLint, etc.?
Vue CLI v5.0.0-beta.7
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Lint
er, Unit, E2E
? Choose a version of Vue.js that you want to start the project with 3.x
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Less
? Pick a linter / formatter config: Standard
? Pick additional lint features: Lint on save, Lint and fix on commit
? Pick a unit testing solution: Jest
? Pick an E2E testing solution: Cypress
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
> In dedicated config files
  In package.json
  1. Save preset as
Vue CLI v5.0.0-beta.7
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Lint
er, Unit, E2E
? Choose a version of Vue.js that you want to start the project with 3.x
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Less
? Pick a linter / formatter config: Standard
? Pick additional lint features: Lint on save, Lint and fix on commit
? Pick a unit testing solution: Jest
? Pick an E2E testing solution: Cypress
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? Yes
? Save preset as: my-project

说明

Vue3.x 可以创建Vue2.x项目

六、生命周期

在vue3.x中,新增了一个setup生命周期函数,setup执行的时机是在beforeCreate生命函数之前执行,因此在这个函数中是不能通过this来获取实例的;同时为了命名的统一,将beforeDestroy改名为beforeUnmountdestroyed改名为unmounted

6.1 Vue2.x

生命周期图示微信图片_20220520133132.png

生命周期

  • beforeCreate:
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed
  • errorCaptured

6.2 Vue3.x

生命周期图示微信图片_20220520133136.png

生命周期

  • setup
  • onBeforeMount
  • onMounted
  • onBeforeUpdate
  • onUpdated
  • onBeforeUnmount
  • onUnmounted
  • onErrorCaptured


6.3 对照表


| 2.0 周期名称 | 3.0 周期名称 | 说明 | | beforeCreate | setup | 组件创建之前 | | created | setup | 组件创建完成 | | beforeMount | onBeforeMount | 组件挂载之前 | | mounted | onMounted | 组件挂载完成 | | beforeUpdate | onBeforeUpdate | 数据更新,虚拟 DOM 打补丁之前 | | updated | onUpdated | 数据更新,虚拟 DOM 渲染完成 | | beforeDestroy | onBeforeUnmount| 组件销毁之前 | | destroyed | onUnmounted | 组件销毁后 |

生命周期 Vue2.x Vue3.x 说明
setup N Y beforeCreate、created由setup()代替
beforeCreate Y setup 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前执行,此时组件实例还未创建,通常用于插件开发中执行一些初始化任务
created Y setup 组件实例已经创建完成,并配置了数据观测 (data observer),property 和方法的运算,watch/event 事件回调。但是还没有挂载DOM,此阶段可用于异步数据获取
beforeMount Y onBeforeMount 在挂载开始之前被调用:相关的 render 函数首次被调用
mounted Y onMounted 组件实例被挂载后完成,DOM已创建,此阶段可用于访问数据和DOM元素,但不会保证所有子组件都一起被挂载。如果您希望整个视图都完成渲染可以在 mounted 内部使用 vm.$nextTick
beforeUpdate Y onBeforeUpdate 数据更新前调用,可用于获取更新前的状态。可在这里 手动移除已经添加的事件监听器
updated Y onUpdated 此函数执行的时候。DOM已经更新。updated 不会保证所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以在 updated 里使用 vm.$nextTick
beforeDestroy Y onBeforeUnmount 实例销毁之前调用。在这一步,实例仍然完全可用,此时可以取消定时器和订阅事件
destroyed Y onUnmounted 卸载组件实例后调用。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载
errorCaptured Y onErrorCaptured 错误时调用

注意

  1. vue3.x的生命周期执行发生在vue2.x生命周期的前面
  2. setup这个生命周期发生在beforeCreatecreated之前
  3. 两种形式的生命周期函数是可以共存,它们都会被执行

6.4 代码案例


<script lang="ts">
import { Options, Vue } from 'vue-class-component'
import { 
    onBeforeMount, 
    onMounted, 
    onBeforeUpdate, 
    onUpdated, 
    onBeforeUnmount, 
    onUnmounted, 
    reactive, 
    ref } from 'vue'
import HelloWorld from '@/components/HelloWorld.vue' // @ is an alias to /src
@Options({
  props: {
    msg: String
  },
  components: {
    HelloWorld
  }
})
export default class Home extends Vue {
  setup ():void {
     console.log("类似于created")
    //  挂载的生命周期
    onBeforeMount(() => {
      console.log('Vue3.0类似于beforeMount ')
    })
    onMounted(() => {
      console.log('Vue3.0类似于mounted ')
    })
    //   跟新阶段的生命周期
    onBeforeUpdate(() => {
      console.log('Vue3.0类似于beforeUpdate ')
    })
    onUpdated(() => {
      console.log('Vue3.0类似于 updated  ')
    })
    // 销毁阶段生命周期
    onBeforeUnmount(() => {
      console.log('Vue3.0类似beforeDestory ')
    })
    onUnmounted(() => {
      console.log('Vue3.0类似于destoryed')
    })
  }
  beforeCreate (): void {
    console.log('vue2.0 beforeCreate')
  }
  created ():void {
    console.log('vue2.0 created')
  }
  beforeMount ():void {
    console.log('vue2.0 beforeMount')
  }
  mounted ():void {
    console.log('vue2.0 mounted')
  }
  beforeUpdate ():void {
    console.log('vue2.0 beforeUpdate')
  }
  updated ():void {
    console.log('vue2.0 updated')
  }
  beforeUnmount ():void {
    console.log('vue2.0 beforeDestroy')
  }
  // destroyed==> unmounted
  unmounted ():void {
    console.log('vue2.0 destroyed')
  }
}
</script>

同时,vue3新增了生命周期钩子,我们可以通过在生命周期函数前加on来访问组件的生命周期,我们可以使用以下生命周期钩子:

  • onBeforeMount
  • onMounted
  • onBeforeUpdate
  • onUpdated
  • onBeforeUnmount
  • onUnmounted
  • onErrorCaptured
  • onRenderTracked
  • onRenderTriggered

我们在setup中挂载生命周期钩子,当执行到对应的生命周期时,就调用对应的钩子函数:

import { onBeforeMount, onMounted } from "vue";
export default {
  setup() {
    onBeforeMount(() => {
      // beforeMount代码执行
    });
    onMounted(() => {
      // mounted代码执行
    });
  },
}


七、 Vue3.x新增功能



7.1 响应式API


  • Vue3.x中新增reactive相当于Vue2.x中的Vue.observable
  • reactive函数只接收objectarray等复杂数据类型
  • ref创建基本数据类型,比如字符串和数值等

reactive主要负责复杂数据结构,而ref主要处理基本数据结构;但是ref本身也是能处理对象和数组的:

  1. 使用reactive来为JS对象创建响应式状态
import { reactive, toRefs } from "vue";
const user = reactive({
  name: 'kuaizhidao',
  age: 6,
});
user.name = '快智岛'
  1. 对于一些基本数据类型,比如字符串和数值等,我们想要让它变成响应式,也可以通过reactive函数创建对象的方式,但是Vue3.x提供了另一个函数ref
import { ref } from "vue";
const num = ref(0);
const str = ref("");
const bool = ref(true);
num.value++;
console.log(num.value);
str.value = "new val";
console.log(str.value);
bool.value = false;
console.log(male.value);

ref返回的响应式对象是只包含一个名为value参数的RefImpl对象,在js中获取和修改都是通过它的value属性;但是在模板中被渲染时,自动展开内部的值,因此不需要在模板中追加.value

<template>
  <div>
    <span>{{ count }}</span>
    <button @click="count ++">Increment count</button>
  </div>
</template>
<script>
  import { ref } from 'vue'
  export default {
    setup() {
      const count = ref(0)
      return {
        count
      }
    }
  }
</script>
  1. ref处理对象和数组
import { ref } from "vue";
// 处理对象
const obj = ref({
  name: "kuaizhidao",
  age: 6,
});
setTimeout(() => {
  obj.value.name = "快智岛";
}, 1000);
// 处理数组
const list = ref([1, 2, 3, 4, 6]);
setTimeout(() => {
  list.value.push(7);
}, 2000);


7.2 装饰器(decorators)


Vue Class Component是一个可以让你使用Class风格语法编写Vue组件的库.

1. Class 组件

@Component 装饰器可以让你能创建一个基于Class的Vue组件:

<template>
  <div>{{ message }}</div>
</template>
<script>
import Vue from 'vue'
import Component from 'vue-class-component'
// HelloWorld class will be a Vue component
@Component
export default class Kuaizhidao extends Vue {}
</script>

2. Data

使用Class属性来初始化 data

<template>
  <div>{{ message }}</div>
</template>
<script>
import Vue from 'vue'
import Component from 'vue-class-component'
@Component
export default class HelloWorld extends Vue {
  // 定义 component 的 data
  message = 'Hello World!'
}
</script>

The above component renders 上面的组件会在

中的组件data message中渲染Hello World!

注意如果初始化的值是 undefined, Class属性将不是响应式的, 意思就是当其发生修改后, 将不会被侦测到:

<template>
  <div>{{ message }}</div>
</template>
<script>
import Vue from 'vue'
import Component from 'vue-class-component'
@Component
export default class HelloWorld extends Vue {
  // `message` 将不是响应式数据
  message = undefined
}
<script>

为了防止这种情况, 你需要使用 null 来赋值, 或者使用 data 钩子来代替:

import Vue from 'vue'
import Component from 'vue-class-component'
@Component
export default class HelloWorld extends Vue {
  // `message` 将是响应式
  message = null
  data() {
    return {
      // `name` 将是响应式的, 因为在data钩子里
      name: undefined
    }
  }
}

3. Methods

组件 methods 将直接定义在Class方法属性中

<template>
  <button v-on:click="handleOK">Click</button>
</template>
<script>
import Vue from 'vue'
import Component from 'vue-class-component'
@Component
export default class HelloWorld extends Vue {
  // 定义一个组件方法
  handleOK() {
    console.log('Hello World!')
  }
}
</script>

4. Computed Properties

计算属性可以通过Class属性的 getter / setter 定义

<template>
  <input v-model="name">
</template>
<script>
import Vue from 'vue'
import Component from 'vue-class-component'
@Component
export default class HelloWorld extends Vue {
  firstName = 'Kuai'
  lastName = 'zhidao'
  // 定义计算属性的 getter
  get name() {
    return this.firstName + ' ' + this.lastName
  }
  // 定义计算属性的 setter
  set name(value) {
    const splitted = value.split(' ')
    this.firstName = splitted[0]
    this.lastName = splitted[1] || ''
  }
}
</script>

5. Hooks

data, render 以及所有Vue生命周期钩子可以直接在Class属性方法中直接定义, 但是你不能在实例本身上调用他们. 当定义自定义方法时, 你应该回避这些保留名

import Vue from 'vue'
import Component from 'vue-class-component'
@Component
export default class HelloWorld extends Vue {
  // 定义生命周七钩子函数
  mounted() {
    console.log('mounted')
  }
  // 定义渲染函数
  render() {
    return <div>Hello World!</div>
  }
}

八、Options API 和 Composition API区别


Options API约定了我们该在哪个位置做什么事,在一定程度上也强制我们进行了代码分割。现在用 Composition API,不再这么约定了,代码组织非常灵活,我们的控制代码写在setup 里面即可。

  • setup>beforeCreate(表示组件刚刚被创建出来,组件的datamethods还没有初始化好)>created(表示组件刚刚被创建出来,并且组件的datamethods已经初始化好)
  • setup函数是 Composition API(组合API)的入口
  • 由于在执行 setup函数的时候,还没有执行 created 生命周期方法,所以在setup函数中,无法使用 data methods 的变量和方法
  • setup中没有this,由于我们不能在 setup函数中使用 datamethods,所以 Vue 为了避免我们错误的使用,直接将 setup函数中的this修改成了 undefined
  • setup函数中定义的变量和方法最后都是需要 return 出去的 不然无法再模板中使用
  • setup函数只能是同步的不能是异步的
Options API Composition API 说明
props 里面设置接收参数 Composition API不再约定 控制代码写在 setup 里面即可
data 里面设置变量 Composition API不再约定
computed 里面设置计算属性 Composition API不再约定
watch 里面设置监听属性 Composition API不再约定
methods 里面设置事件方法 Composition API不再约定

九、 学习网址





目录
相关文章
|
1月前
|
监控
【Vue3】学习watch监视:深入了解Vue3响应式系统的核心功能(下)
【Vue3】学习watch监视:深入了解Vue3响应式系统的核心功能(下)
|
1月前
【Vue3】学习watch监视:深入了解Vue3响应式系统的核心功能(上)
【Vue3】学习watch监视:深入了解Vue3响应式系统的核心功能(上)
|
1月前
|
JavaScript
Vue.js学习详细课程系列--共32节(6 / 6)
Vue.js学习详细课程系列--共32节(6 / 6)
27 0
|
1月前
|
JavaScript
Vue.js学习详细课程系列--共32节(5 / 6)
Vue.js学习详细课程系列--共32节(5 / 6)
29 0
|
1月前
|
JavaScript
Vue.js学习详细课程系列--共32节(4 / 6)
Vue.js学习详细课程系列--共32节(4 / 6)
35 0
|
1月前
|
JavaScript
Vue.js学习详细课程系列--共32节(3 / 6)
Vue.js学习详细课程系列--共32节(3 / 6)
11 0
|
1月前
|
JavaScript
Vue.js学习详细课程系列--共32节(2 / 6)
Vue.js学习详细课程系列--共32节(2 / 6)
29 0
|
1月前
|
Web App开发 移动开发 JavaScript
Vue.js学习详细课程系列--共32节(1 / 6)
Vue.js学习详细课程系列--共32节(1 / 6)
42 0
|
1月前
【Vue3】回顾watch,学习watchEffect
【Vue3】回顾watch,学习watchEffect
|
1月前
|
缓存 JavaScript 开发者
【Vue3】学习computed计算属性
【Vue3】学习computed计算属性