VUE3集成TS和vue-router

前言

尤大在 Vue 3.2 发布的时候已经在微博给出了最佳实践的解决方案:

<script setup> + TS + Volar = 真香

Volar 是个 VS Code 的插件,其最大的作用就是解决了 template 的 TS 提示问题。

注意

使用它时,要先移除 Vetur,以避免造成冲突。

<script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。相比于普通的 script 语法,它具有更多优势:

  • 更少的样板内容,更简洁的代码。
  • 能够使用纯 Typescript 声明 props 和发出事件。
  • 更好的运行时性能 (其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理)。
  • 更好的 IDE 类型推断性能 (减少语言服务器从代码中抽离类型的工作)。

详见官方文档 单文件组件

Vite

也可以使用新的创建方式简化操作步骤

https://www.psvmc.cn/article/2024-08-01-vue3-vite.html

创建项目

Vite 是一个 web 开发构建工具,由于其原生 ES 模块导入方式,可以实现闪电般的冷服务器启动。

通过在终端中运行以下命令,可以使用 Vite 快速构建 Vue 项目。

查看npm版本

1
npm -v

创建项目

1
2
3
4
5
6
# npm 6.x
npm init vite@latest vue3_demo01 --template vue

cd vue3_demo01
npm install
npm run dev

注意:

1
2
# npm 7+,需要加上额外的双短横线
npm init vite@latest vue3_demo01 -- --template vue

如果报错

Error: Cannot find module ‘worker_threads’

原因是:

Vite 需要 Node.js 版本 >= 12.0.0。

添加TS/vue-router等

安装 typescript、vue-router@next、axios、eslint-plugin-vue、less等相关插件

1
2
3
4
npm install axios
npm install vue-router@next
npm install typescript -D
npm install less -D

vite.config.ts

vite.config.js重命名为vite.config.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { UserConfig } from 'vite'
const path = require('path')
import vue from '@vitejs/plugin-vue'

const config: UserConfig = {
plugins: [vue()],
optimizeDeps: {
include: [ 'axios' ]
},
resolve: {
alias: {
'/@': path.resolve( __dirname, './src' )
},
},
}

export default config

router

在 src 下新建 router 文件夹,并在文件夹内创建 index.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { createRouter, createWebHashHistory } from 'vue-router'

const routes = [
{
path: '/',
name: 'Home',
component: () => import('/@/views/Home.vue')
}
]

export default createRouter({
history: createWebHashHistory(),
routes
})

views

src下添加views文件夹

添加Home.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script setup></script>

<template>
<div class="div1">
<div class="div2">码客说</div>
</div>
</template>

<style scoped lang="less">
.div1 {
.div2 {
font-size: 20px;
}
}
</style>

src下的App.vue中添加<router-view></router-view>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script setup>
import HelloWorld from "./components/HelloWorld.vue";
</script>

<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3 + Vite" />

<router-view></router-view>
</template>

<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>

ts 配置

项目根目录下新建 tsconfig.json 写入相关配置

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
30
31
{
"compilerOptions": {
"allowJs": true,
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": ["vite/client"],
"paths": {
"/@/*": ["src/*"]
},
"lib": ["esnext", "dom", "dom.iterable", "scripthost"]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx",
"vite.config.ts"
],
"exclude": ["node_modules"]
}

src 目录下新建 types 文件夹,里面需要配置 ts 的类型

shims-vue.d.ts

1
declare module '*.vue' {}

images.d.ts

1
2
3
4
5
6
7
declare module '*.svg'
declare module '*.png'
declare module '*.jpg'
declare module '*.jpeg'
declare module '*.gif'
declare module '*.bmp'
declare module '*.tiff'

main.ts

src下的main.js重命名为main.ts

1
2
3
4
5
6
7
8
import { createApp } from 'vue'
import router from '/@/router'

import App from '/@/App.vue'

const app = createApp(App)
app.use(router)
app.mount('#app')

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
<!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>

主要是

1
<script type="module" src="/src/main.js"></script>

修改为

1
<script type="module" src="/src/main.ts"></script>