前言
尤大在 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 2 3 4 5 6
| npm init vite@latest vue3_demo01 --template vue
cd vue3_demo01 npm install npm run dev
|
注意:
1 2
| 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>
|