前面我们已经用 vue2 和 react 做过开发了.
从 vue2 升级到 vue3 成本较大,特别是较大的项目。所以许多公司对旧项目继续使用vue2,新项目则使用 vue3.
有些UI框架,比如ant design vue1.x 使用的 vue2。但现在 ant design vue4.x 都是基于 vue3,示例默认是 TypeScript。比如 table 组件管理.
另外 vue3 官网介绍也使用了 TypeScript,例如:响应式 API:核心 。
本篇主要介绍:vite 创建vue3项目、组合式api、响应式数据、计算属性、监听、ref、ts、生命周期、自定义hooks.
Vue.js 3.0,代号海贼王,于2020年9月18日发布 —— v3.0.0 海贼王 。
主要有如下改进:
性能
改进:与 Vue 2 相比,Vue 3 在包大小(通过 Tree-Shaking 减少最多 41%)、初始渲染(快 55%)、更新(快 133%)和内存使用方面表现出了显着的性能改进(最多减少 54%)。TypeScript
:更好的支持 TS。有的公司在 vue2 中就用 TS 了Composition API
——一组新的 API,旨在解决大规模应用程序中 Vue 使用的痛点。Composition API 构建在反应性 API 之上,支持类似于 React hooks 的逻辑组合和重用、更灵活的代码组织模式以及比 2.x 基于对象的 API 更可靠的类型推断。前面我们用 vue-cli 创建过 vue2 的项目,用其构建 vue3 也类似,差别就是选择 vue3 版本。最后生成的项目结构如下:
Vue CLI 是官方提供的基于 Webpack 的 Vue 工具链,它现在处于维护模式。我们建议使用 Vite 开始新的项目,除非你依赖特定的 Webpack 的特性。在大多数情况下,Vite 将提供更优秀的开发体验 —— 官网 - 项目脚手架 。
另一种方式是使用 vite。有如下优势:
Tip
笔者首先使用 npm create vite@latest 创建项目,自己根据需要选择对应预设(比如要 TypeScript or javascript),创建完成后根据提示进入项目,安装依赖,本地启动:
npm install
npm run dev
结果报错:
> vite-vue3@0.0.0 dev \test-projects\vite-vue3
> vite
(node:40312) UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token '??='
at Loader.moduleStrategy (internal/modules/esm/translators.js:145:18)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:40312) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:40312) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
说是 node 版本可能低了.
Tip: Vite 需要 Node.js 版本 14.18+,16+。然而,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意升级你的 Node 版本 —— vite 官网-搭建第一个 Vite 项目 。
于是使用 nvm 安装 18.16.0。步骤如下:
// 目前版本 14.19
PS \test-projects\vite-vue3> node -v
v14.19.0
// nvm 已安装
PS \test-projects\vite-vue3> nvm -v
1.1.10
// nvm 安装 18.16.0
PS \test-projects\vite-vue3> nvm install 18.16.0
Downloading node.js version 18.16.0 (64-bit)...
Extracting node and npm...
Complete
npm v9.5.1 installed successfully.
Installation complete. If you want to use this version, type
nvm use 18.16.0
根据提示切换到 18.16.0 。
PS \test-projects> nvm use 18.16.0
Now using node v18.16.0 (64-bit)
PS \test-projects> node -v
v18.16.0
使用 npm create vue@latest 创建 vue3 项目 —— vue3 官网 创建一个 Vue 应用(这里提到 node 需要18+):
PS \test-projects> npm create vue@latest
Need to install the following packages:
create-vue@3.9.2
Ok to proceed? (y) y
Vue.js - The Progressive JavaScript Framework
√ 请输入项目名称: ... hello_vue3
√ 是否使用 TypeScript 语法? ... 否 / 是
√ 是否启用 JSX 支持? ... 否 / 是
√ 是否引入 Vue Router 进行单页面应用开发? ... 否 / 是
√ 是否引入 Pinia 用于状态管理? ... 否 / 是
√ 是否引入 Vitest 用于单元测试? ... 否 / 是
√ 是否要引入一款端到端(End to End)测试工具? » 不需要
√ 是否引入 ESLint 用于代码质量检测? ... 否 / 是
正在构建项目 \test-projects\hello_vue3...
项目构建完成,可执行以下命令:
cd hello_vue3
npm install
npm run dev
npm notice
npm notice New major version of npm available! 9.5.1 -> 10.4.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.4.0
npm notice Run npm install -g npm@10.4.0 to update!
npm notice
根据提示按照依赖,本地启动项目成功:
PS \test-projects> cd .\hello_vue3\
PS \test-projects\hello_vue3> npm install
added 63 packages, and audited 64 packages in 20s
7 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
PS \test-projects\hello_vue3> npm run dev
> hello_vue3@0.0.0 dev
> vite
VITE v5.1.3 ready in 3045 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
npm create vite@latest 和 npm create vue@latest 作用和用途不同,两者效果也不同,总的来说前者创建 Vite 项目,而 npm create vue@latest 是用来创建 Vue.js 项目.
PS \test-projects> npm create vite@latest
Need to install the following packages:
create-vite@5.2.0
Ok to proceed? (y) y
√ Project name: ... hello-vue3
√ Select a framework: » Vue
√ Select a variant: » TypeScript
Scaffolding project in \test-projects\hello-vue3...
Done. Now run:
cd hello-vue3
npm install
npm run dev
vite 本地启动非常快。真正按需编译,不在等待整个应用编译完成.
用 webpack 本地启动服务器,需要经历如下几步:entry->route->module->bundle->服务器启动(下图左);而用 vite 启动服务器,服务器启动却从末尾移到开头(下图右) 。
有点像懒加载,你需要访问哪个路由,就加载哪个,非常快速.
前面我们用 vite 创建了 hello_vue3 项目。目录结构如下:
我们先说其他文件,最后在分析src文件夹 。
内容如下:
// .vscode/extensions.json
{
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
}
推荐你安装这两个插件,当你用 vscode 启动项目,点击切换到其他文件上,vscode 右下角就会提示你是否安装这两个插件。就像这样:
这两个是vue官方给 vscode 提供的插件:
内容如下:
/// <reference types="vite/client" />
是一个在 Vue.js 项目中使用 Vite 构建工具时引入的指令,它的作用是让 TypeScript 编译器能够识别并利用 Vite 客户端类型声明文件提供的类型信息,以提供更好的智能编码功能和类型检查支持.
Tip:如果你删除 node_modules 文件夹,你在vscode 中会发现 vite/client 下有红色波浪线.
TypeScript 主要用于处理 JavaScript 代码,并且在处理模块时,它会关注 .ts、.tsx、.js 和 .jsx 这些与 JavaScript 相关的文件类型.
TypeScript 默认情况下并不会识别或处理像 .txt、.gif 这样的非 TypeScript 文件类型。这个文件的作用就是让 ts 认识 txt、jpg、gif等.
比如你在src 下新建 a.txt、b.ts,然后在 b.ts 中编写:
import a from 'a.txt'
console.log(a)
当你清空 env.d.ts,你会发现 import a from 'a.txt'中 a.txt 下有红色波浪线。再次还原 env.d.ts 则好了.
通过 ctrl + 鼠标点击进入 vite/client,你会发现 vue 给我们声明好了我们需要使用的其他类型文件。比如 txt
declare module '*.txt' {
const src: string
export default src
}
index.html 这就是我们的入口文件。内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
你可以尝试改成 。
<body>
a
</body>
无需重启服务,页面就显示 a.
tsconfig.app.json
tsconfig.json
tsconfig.node.json
vite.config.ts 项目配置文件。比如代理、安装插件 。
public/favicon.ico 页签图标 。
package.json、package-lock.json 。
src 就是我们编码的地方.
我们先将 src 中的文件都删除,我们自己重新创建.
创建 main.ts 和 App.vue 两个文件。内容如下:
// src/main.ts
import {createApp} from 'vue'
// 项目的根
import App from './App.vue'
// Vue.js 3.x 中用于创建和挂载应用
// 创建一个新的 Vue 应用,并将根组件指定为 App。.mount('#app') 将应用挂载到指定的 DOM 元素上
createApp(App).mount('#app')
// src/App.vue
<template>
<div>
你好 vue3
</div>
</template>
<!-- 可以指定语言是 ts,ts中也可以写js -->
<script lang="ts">
</script>
<style scoped>
</style>
浏览器访问,页面显示 你好 vue3.
前面我们说到 vite 启动后,服务器就已就绪。然后会根据用户请求哪里,就会给你加载哪里.
有些项目使用了 vue3,但写法还是 vue2 —— 不建议这么做.
为了证明 vue3 中能写 vue2,笔者在 vue3 项目中写一个 vue2 示例。请看代码:
// src/App.vue
<template>
<section>
<p>name: {{ name }}</p>
<p>date: {{ date }}</p>
<p><button @click="changeDate">change date</button></p>
</section>
</template>
<script lang="ts">
export default {
name: 'App',
data() {
return {
name: 'pengjiali',
date: -1,
}
},
methods: {
changeDate() {
this.date = new Date().getTime();
}
}
}
</script>
浏览器显示:
name: pengjiali
date: -1
// 按钮,点击后,date 后的数字就会变化
change date
Vue 2 使用的是选项式 API,而 Vue 3 引入了组合式 API 。
虽然 Vue 3 推荐使用组合式 API,但它仍然完全支持 Vue 2 的选项式 API,以保持向下兼容性。所以在 Vue 3 中,你可以自由选择使用选项式 API 或组合式 API 来编写你的组件逻辑.
选项式API有一个缺点:新增一个功能,需要分别在 data、methods、computed、watch等选项中修改代码,如果代码上千,修改或抽取封装这部分功能,有困难.
Tip:我们用 大帅老猿 的图说明以下这个问题 。