Vue3

Vue3快速上手

img

Vue3+TS快速上手

Vue3简介

Vue3带来了什么

1.性能的提升

  • 打包大小减少41%

  • 初次渲染快55%, 更新渲染快133%

  • 内存减少54%

    ……

2.源码的升级

  • 使用Proxy代替defineProperty实现响应式

  • 重写虚拟DOM的实现和Tree-Shaking

    ……

3.拥抱TypeScript

  • Vue3可以更好的支持TypeScript

4.新的特性

  • Composition (组合) API
  • setup
    • ref 和 reactive
    • computed 和 watch
    • 新的生命周期函数
    • provide与inject
  • 新组件
    • Fragment - 文档碎片
    • Teleport - 瞬移组件的位置
    • Suspense - 异步加载组件的loading界面
  • 其它API更新
    • 全局API的修改
    • 将原来的全局API转移到应用对象
    • 模板语法变化

一、创建Vue3.0工程

使用 vue-cli 创建

官方文档:https://cli.vuejs.org/zh/guide/creating-a-project.html#vue-create

1
2
3
4
5
6
7
8
9
10
## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue --version
## 安装或者升级你的@vue/cli
npm install -g @vue/cli
## 保证 vue cli 版本在 4.5.0 以上
## 创建
vue create vue_test
## 启动
cd vue_test
npm run serve

然后的步骤

  • Please pick a preset - 选择 Manually select features
  • Check the features needed for your project - 选择上 TypeScript ,特别注意点空格是选择,点回车是下一步
  • Choose a version of Vue.js that you want to start the project with - 选择 3.x (Preview)
  • Use class-style component syntax - 直接回车
  • Use Babel alongside TypeScript - 直接回车
  • Pick a linter / formatter config - 直接回车
  • Use history mode for router? - 直接回车
  • Pick a linter / formatter config - 直接回车
  • Pick additional lint features - 直接回车
  • Where do you prefer placing config for Babel, ESLint, etc.? - 直接回车
  • Save this as a preset for future projects? - 直接回车

image-20231003163618121

image-20231003163641258

如果忘记了选择typescript需要

1
2
npm install --save-dev typescript @types/node @types/vue
npx tsc --init #生成配置文件

2.使用 vite 创建

官方文档:https://v3.cn.vuejs.org/guide/installation.html#vite

vite官网:https://vitejs.cn

  • 什么是vite?—— 新一代前端构建工具。
  • 优势如下:
    • 开发环境中,无需打包操作,可快速的冷启动。
    • 轻量快速的热重载(HMR)。
    • 真正的按需编译,不再等待整个应用编译完成。
  • 传统构建 与 vite构建对比图

image-20220825150708980

image-20220825150734043

1
2
3
4
5
6
7
8
## 创建工程
npm init vite-app <project-name>
## 进入工程目录
cd <project-name>
## 安装依赖
npm install
## 运行
npm run dev
  • vite 是一个由原生 ESM 驱动的 Web 开发构建工具。在开发环境下基于浏览器原生 ES imports 开发,
  • 它做到了本地快速开发启动, 在生产环境下基于 Rollup 打包。
    • 快速的冷启动,不需要等待打包操作;
    • 即时的热模块更新,替换性能和模块数量的解耦让更新飞起;
    • 真正的按需编译,不再等待整个应用编译完成,这是一个巨大的改变。

image-20220825151253194

image-20220825151430330

image-20220825151412135

对比

main.js对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 引入的不再是Vue构造函数,引入的是一个名为createApp的工厂函数
import { createApp } from 'vue'
import App from './App.vue'

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

// vue2
// const vm = new Vue({
// render: h => h(App)
// })
// vm.$mount('#app')

// vue3
// 创建应用实例对象-app(类似于之前vue2中的vm,但app比vm更“轻”)
// const app = createApp(App)
// 挂载
// app.mount('#app')
// 卸载
// app.unmount('#app')

App.vue

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
<template>
<!--Vue3的组件木板结构可以没有根标签-->
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
name: 'App',
components: {
HelloWorld
}
}
</script>

<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

vue3可以没有根标签

安装vue3开发者工具

方式一:

chorme网上商店:https://chrome.google.com/webstore/category/extensions?hl=zh-CN

image-20220825153819697

方式二:离线安装

二、常用 Composition API

官方文档: https://v3.cn.vuejs.org/guide/composition-api-introduction.html

选项式API和组合式API

Vue 的组件可以按两种不同的风格书写:选项式 API组合式 API

选项式 API (Options API)

使用选项式 API,我们可以用包含多个选项的对象来描述组件的逻辑,例如 datamethodsmounted。选项所定义的属性都会暴露在函数内部的 this 上,它会指向当前的组件实例。

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
<script>
export default {
// data() 返回的属性将会成为响应式的状态
// 并且暴露在 `this` 上
data() {
return {
count: 0
}
},

// methods 是一些用来更改状态与触发更新的函数
// 它们可以在模板中作为事件处理器绑定
methods: {
increment() {
this.count++
}
},

// 生命周期钩子会在组件生命周期的各个不同阶段被调用
// 例如这个函数就会在组件挂载完成后被调用
mounted() {
console.log(`The initial count is ${this.count}.`)
}
}
</script>

<template>
<button @click="increment">Count is: {{ count }}</button>
</template>

组合式 API (Composition API)

通过组合式 API,我们可以使用导入的 API 函数来描述组件逻辑。在单文件组件中,组合式 API 通常会与 <script setup> 搭配使用。这个 setup attribute 是一个标识,告诉 Vue 需要在编译时进行一些处理,让我们可以更简洁地使用组合式 API。比如,<script setup> 中的导入和顶层变量/函数都能够在模板中直接使用。

下面是使用了组合式 API 与 <script setup> 改造后和上面的模板完全一样的组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script setup>
import { ref, onMounted } from 'vue'

// 响应式状态
const count = ref(0)

// 用来修改状态、触发更新的函数
function increment() {
count.value++
}

// 生命周期钩子
onMounted(() => {
console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
<button @click="increment">Count is: {{ count }}</button>
</template>

vue3 中 setup 函数、defineComponent 函数 和 script 标签上的 setup

vue3 中 setup 函数、defineComponent 函数 和 script 标签上的 setup

setup 函数的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div>{{ str }}</div>
<div v-for="(item, idx) in list" :key="idx"></div>
<div>{{ obj }}</div>
</template>
<script>
import { ref, reactive, toRefs } from 'vue'

export default {
setup() {
const str = ref('qwert')
const list = ref([])
const obj = reactive({})

return {
str,
list,
...toRefs(obj)
}
}
}
</script>

defineComponent 函数

defineComponent 函数是 setup 函数的语法糖之一

defineComponent 函数支持 TypeScript 的参数类型推断(专为 TS 准备的)。若使用的是 ts + vue3,强力推荐使用它。

defineComponent 函数的一般用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div>{{ str }}</div>
<div v-for="(item, idx) in list" :key="idx"></div>
<div>{{ obj }}</div>
</template>
<script>
import { ref, toRefs, reactive, defineComponent } from 'vue'

export default defineComponent({
setup() {
const str = ref('qwert')
const list = ref([])
const obj = reactive({})

return {
str,
list,
...toRefs(obj)
}
}
})
</script>

ts + vue3 中使用 defineComponent 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { defineComponent, PropType} from 'vue';
interface UserInfo = {
id: number,
name: string,
age: number
}
export default defineComponent({
//props需要使用PropType泛型来约束。
props: {
userInfo: {
type: Object as PropType<UserInfo>, // 泛型类型
required: true
}
},
})

==