新手從零搭建的Vue3 + TypeScript項目
一、前置準(zhǔn)備
確保電腦已安裝:
Node.js(推薦 16.x 及以上,可通過 node -v 查看版本)
npm/yarn/pnpm(npm 隨 Node.js 自帶,推薦用 pnpm 速度更快)
二、創(chuàng)建 Vue3 + TS 項目
Vue 官方提供了腳手架 create-vue,是搭建 Vue3 + TS 項目的最佳方式(替代舊的 @vue/cli)。
1. 執(zhí)行創(chuàng)建命令
打開終端(CMD/PowerShell/ 終端),運行:
# 使用 npm npm create vue@latest # 或使用 pnpm(推薦) pnpm create vue@latest # 或使用 yarn yarn create vue@latest
注意:
node版本過低會有引擎不兼容警告,這個警告不影響項目創(chuàng)建,只是提示版本不滿足官方推薦要求,實際大部分功能仍可正常使用。
- 直接按提示輸入 y 繼續(xù)創(chuàng)建項目即可。
- 若后續(xù)運行出現(xiàn)兼容性問題,再升級 Node.js。
2. 交互式配置項目(關(guān)鍵步驟)
執(zhí)行命令后,終端會彈出一系列選項,按下面的配置選(練手項目足夠用):
# 1. 輸入項目名稱(比如:vue3-ts-todo) √ Project name: vue3-ts-todo # 2. 是否使用 TypeScript?選 Yes(核心) √ Add TypeScript? Yes # 3. 是否使用 JSX?選 No(練手先不涉及) √ Add JSX Support? No # 4. 是否添加 Vue Router?選 Yes(路由是基礎(chǔ)) √ Add Vue Router for Single Page Application development? Yes # 5. 是否添加 Pinia?選 Yes(狀態(tài)管理,替代 Vuex) √ Add Pinia for state management? Yes # 6. 是否添加 Vitest?選 No(測試先不涉及) √ Add Vitest for Unit Testing? No # 7. 是否添加 Cypress?選 No √ Add Cypress for both Unit and End-to-End testing? No # 8. 是否添加 ESLint?選 Yes(代碼規(guī)范) √ Add ESLint for code quality? Yes # 9. 是否添加 Prettier?選 No(練手簡化) √ Add Prettier for code formatting? No # 10. 是否跳過示例代碼選項?選 No(練手簡化) 選 No:會保留官方示例代碼,方便你參考結(jié)構(gòu),同時可以逐步替換成自己的 TodoList 功能,降低上手難度。 選 Yes:會生成完全空白的項目,需要自己從零搭建所有文件,更適合有一定經(jīng)驗的開發(fā)者。
3. 進(jìn)入項目并安裝依賴
# 進(jìn)入項目目錄 cd vue3-ts-todo # 安裝依賴(用 npm/pnpm/yarn 都可以) npm install # 或 pnpm install # 或 yarn install
4. 啟動項目
npm run dev # 或 pnpm dev # 或 yarn dev
啟動成功后,終端會顯示本地訪問地址(如 http://localhost:5173/),打開瀏覽器訪問即可看到 Vue3 初始頁面。
三、熟悉項目目錄結(jié)構(gòu)(核心關(guān)注)
創(chuàng)建完成后,項目核心目錄如下(重點看標(biāo)星的文件):
vue3-ts-todo/ ├── src/ │ ├── components/ # 組件目錄(重點寫 TS 組件) │ ├── router/ # 路由配置(TS 版) │ │ └── index.ts # * 路由入口(TS 語法) │ ├── stores/ # Pinia 狀態(tài)管理(TS 版) │ │ └── counter.ts # * 示例倉庫(可替換為 Todo 倉庫) │ ├── views/ # 頁面組件(TS 版) │ │ ├── AboutView.vue │ │ └── HomeView.vue │ ├── App.vue # * 根組件(TS 語法) │ ├── main.ts # * 入口文件(TS 語法) │ └── types/ # (手動新建)全局類型定義目錄 ├── package.json ├── tsconfig.json # * TS 配置文件(核心) └── vite.config.ts # Vite 配置(TS 版)
# app.vue
<template>
<!-- 模板區(qū)域 -->
<div id="app">
<router-view />
</div>
</template>
<script setup lang="ts">
// 腳本區(qū)域
</script>
<style scoped>
/* 樣式區(qū)域 */
}
</style>
四、實現(xiàn) TodoList 練手功能(核心實戰(zhàn))
基于 TS 實現(xiàn)「添加待辦、刪除待辦、標(biāo)記完成」的核心功能,覆蓋 Vue3 + TS 的核心用法:
- 組件 Props 類型約束
- 響應(yīng)式數(shù)據(jù)類型注解
- Pinia 狀態(tài)管理 + TS
- 路由跳轉(zhuǎn) + TS
1. 新建全局類型(src/types/todo.ts)
先定義 Todo 數(shù)據(jù)的類型(TS 核心:先定義類型,再寫邏輯):
// src/types/todo.ts
// 定義單個待辦項的類型
export interface Todo {
id: number; // 唯一標(biāo)識
content: string; // 待辦內(nèi)容
isCompleted: boolean; // 是否完成
}
// 定義 Pinia 倉庫的狀態(tài)類型
export interface TodoState {
todoList: Todo[]; // 待辦列表
}
2. 創(chuàng)建 Pinia 倉庫(src/stores/todo.ts)
用 TS 約束 Pinia 的狀態(tài)和方法:
// src/stores/todo.ts
import { defineStore } from 'pinia'
import type { Todo, TodoState } from '@/types/todo'
// 定義 Todo 倉庫(TS 版)
export const useTodoStore = defineStore('todo', {
// 狀態(tài):指定類型為 TodoState
state: (): TodoState => ({
todoList: [
// 初始示例數(shù)據(jù)
{ id: 1, content: '學(xué)習(xí) Vue3 + TS', isCompleted: false },
{ id: 2, content: '實現(xiàn) TodoList', isCompleted: true }
]
}),
// 方法:操作待辦數(shù)據(jù)(TS 約束參數(shù)/返回值)
actions: {
// 添加待辦
addTodo(content: string): void {
if (!content.trim()) return
const newTodo: Todo = {
id: Date.now(), // 用時間戳做唯一 ID
content,
isCompleted: false
}
this.todoList.push(newTodo)
},
// 刪除待辦
deleteTodo(id: number): void {
this.todoList = this.todoList.filter(todo => todo.id !== id)
},
// 切換待辦完成狀態(tài)
toggleTodo(id: number): void {
const todo = this.todoList.find(todo => todo.id === id)
if (todo) {
todo.isCompleted = !todo.isCompleted
}
}
}
})
3. 編寫 TodoList 組件(src/components/TodoList.vue)
這是核心組件,覆蓋 Vue3 + TS 的核心語法(
<template>
<div class="todo-container">
<h2>Vue3 + TS 待辦事項</h2>
<!-- 添加待辦 -->
<div class="todo-add">
<input
v-model="inputValue"
placeholder="請輸入待辦內(nèi)容"
@keyup.enter="handleAddTodo"
class="todo-input"
/>
<button @click="handleAddTodo" class="add-btn">添加</button>
</div>
<!-- 待辦列表 -->
<ul class="todo-list">
<li
v-for="todo in todoStore.todoList"
:key="todo.id"
:class="{ completed: todo.isCompleted }"
>
<input
type="checkbox"
:checked="todo.isCompleted"
@change="todoStore.toggleTodo(todo.id)"
/>
<span>{{ todo.content }}</span>
<button @click="todoStore.deleteTodo(todo.id)" class="del-btn">刪除</button>
</li>
</ul>
<!-- 空列表提示 -->
<div v-if="todoStore.todoList.length === 0" class="empty-tip">
暫無待辦事項,添加一個吧~
</div>
</div>
</template>
<script setup lang="ts">
// 1. 導(dǎo)入 Pinia 倉庫
import { useTodoStore } from '@/stores/todo'
// 2. 導(dǎo)入 Vue 響應(yīng)式 API(TS 自動推導(dǎo)類型)
import { ref } from 'vue'
// 3. 初始化倉庫
const todoStore = useTodoStore()
// 4. 響應(yīng)式數(shù)據(jù)(TS 注解:字符串類型)
const inputValue = ref<string>('')
// 5. 方法(TS 約束:無參數(shù)、無返回值)
const handleAddTodo = (): void => {
todoStore.addTodo(inputValue.value)
// 清空輸入框
inputValue.value = ''
}
</script>
<style scoped>
.todo-container {
width: 500px;
margin: 50px auto;
padding: 20px;
border: 1px solid #eee;
border-radius: 8px;
}
.todo-add {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.todo-input {
flex: 1;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
}
.add-btn {
padding: 8px 16px;
background: #42b983;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.todo-list {
list-style: none;
padding: 0;
margin: 0;
}
.todo-list li {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
border-bottom: 1px solid #eee;
}
.todo-list li.completed span {
text-decoration: line-through;
color: #999;
}
.del-btn {
margin-left: auto;
padding: 4px 8px;
background: #ff4444;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
}
.empty-tip {
text-align: center;
color: #999;
padding: 20px;
}
</style>
4. 修改首頁組件(src/views/HomeView.vue)
把 TodoList 組件引入首頁,替換默認(rèn)內(nèi)容:
<template>
<main>
<TodoList />
</main>
</template>
<script setup lang="ts">
import TodoList from '@/components/TodoList.vue'
</script>
<style scoped>
main {
padding: 1rem;
}
</style>
5. 簡化路由(可選)
打開 src/router/index.ts,確保路由配置正確(TS 版):
typescript
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
// TS 約束路由類型(Vue Router 內(nèi)置)
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// 懶加載組件(TS 自動識別類型)
component: () => import('../views/AboutView.vue')
}
]
})
export default router
五、運行項目,查看效果
重新啟動項目(如果之前沒關(guān)就不用):
npm run dev
訪問 http://localhost:5173/,你會看到:
帶輸入框的 TodoList 界面
可輸入內(nèi)容添加待辦
勾選復(fù)選框標(biāo)記完成 / 未完成
點擊刪除按鈕移除待辦
空列表時顯示提示文字

六、核心 TS 知識點回顧(練手重點)
這個項目中你用到的 Vue3 + TS 核心語法:<script setup lang="ts">:Vue3 組合式 API + TS 的核心寫法
類型注解:ref(‘’)、(): void 等,約束響應(yīng)式數(shù)據(jù) / 方法的類型
接口(interface):定義 Todo 數(shù)據(jù)結(jié)構(gòu),統(tǒng)一數(shù)據(jù)類型
Pinia + TS:約束倉庫的狀態(tài)和方法,避免傳參 / 返回值錯誤
路由 TS 類型:Vue Router 內(nèi)置類型,自動約束路由配置
七、拓展練習(xí)(進(jìn)階)
如果想進(jìn)一步練習(xí),可以給項目加功能:
給 Todo 加「編輯」功能(約束編輯輸入的類型)
按「完成 / 未完成」篩選 Todo(TS 約束篩選條件)
本地存儲 Todo 數(shù)據(jù)(用 localStorage,TS 約束存儲 / 讀取的數(shù)據(jù)類型)
總結(jié)
本次搭建的核心關(guān)鍵點:
項目搭建:用官方 create-vue 選擇 TypeScript 選項,快速生成規(guī)范的 Vue3 + TS 項目;
TS 核心:先定義接口(interface)約束數(shù)據(jù)結(jié)構(gòu),再寫邏輯,養(yǎng)成「先類型后邏輯」的習(xí)慣;
Vue3 結(jié)合:<script setup lang="ts"> 中用 ref/reactive 時添加類型注解,Pinia 倉庫用 TS 約束狀態(tài)和方法。
到此這篇關(guān)于新手從零搭建的Vue3 + TypeScript項目的文章就介紹到這了,更多相關(guān)Vue3 TypeScript搭建項目內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue axios調(diào)用接口方法報錯500 internal server err
前端使用axios 訪問后端接口時報錯,在瀏覽器中點擊紅色的報錯數(shù)據(jù),本文給大家分享vue axios調(diào)用接口方法報錯500 internal server error的兩種解決方法,感興趣的朋友一起看看吧2023-10-10
Vue3組件不發(fā)生變化如何監(jiān)聽pinia中數(shù)據(jù)變化
這篇文章主要給大家介紹了關(guān)于Vue3組件不發(fā)生變化如何監(jiān)聽pinia中數(shù)據(jù)變化的相關(guān)資料,pinia是Vue的存儲庫,它允許您跨組件/頁面共享狀態(tài),文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-11-11
一個vue組件庫發(fā)布到npm的完整實現(xiàn)過程
工作的時候總是使用別人的npm包,然而我有時心底會好奇自己如何發(fā)布一個npm包呢,什么時候自己的包能夠被很多人喜歡并使用呢,下面這篇文章主要給大家介紹了關(guān)于一個vue組件庫發(fā)布到npm的相關(guān)資料,需要的朋友可以參考下2022-03-03
Vue2.x如何解決Element組件el-tooltip滾動時錯位不消失的問題
這篇文章主要介紹了Vue2.x如何解決Element組件el-tooltip滾動時錯位不消失的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06
vue項目頁面嵌入代碼塊vue-prism-editor的實現(xiàn)
這篇文章主要介紹了vue項目頁面嵌入代碼塊vue-prism-editor的實現(xiàn),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10
詳解vue2.0的Element UI的表格table列時間戳格式化
本篇文章主要介紹了詳解vue2.0的Element UI的表格table列時間戳格式化,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-06-06

