本文完整版:《Vue3 TypeScript 使用教程 - 實戰 Vue3 element-plus 開發「待辦清單」》
Vue3 的原始碼使用 TypeScript 全部重構,而 TypeScript 是 JS 的一個超集,主要提供對 ES6 的支援以及更棒的程式碼可讀性和高維護性。可以說 Vue3 Typescript 已經成為開發標配。本文帶領大家從搭建環境開始,手把手帶領大家用 Vue3 Typescript + element-plus 開發一個極簡「待辦清單」app,在實戰中學習 Vue3 TypeScript。
如果你正在搭建後臺管理工具,又不想處理前端問題,推薦使用卡拉雲 ,卡拉雲是新一代低程式碼開發工具,可一鍵接入常見資料庫及 API ,無需懂前端,僅需拖拽即可快速搭建屬於你自己的後臺管理工具,一週工作量縮減至一天,詳見本文文末。
Vue3 Typescript 環境搭建
這裡我們透過 vue-cli
腳手架來初始化專案,如果沒有全域性安裝 vue-cli
也沒有關係,可以透過 node
自帶的 npx 命令來初始化專案:
vue create kalacloud-vue3-ts
// OR
npx vue create kalacloud-vue3-ts
執行上面的命令,會進入一個互動式的命令列介面:
會有3個選項,分別是 Vue2 的專案模版、Vue3 的專案模版以及手動安裝模式。這裡我們選擇手動安裝,因為我們需要新增 Typescript
的支援,然後按Enter鍵會進入到下一步:
這裡需要選擇我們需要安裝的其他支援,按空格鍵來選中 Typescript
,然後再按Enter鍵,進入下一步,會讓我們選擇 Vue 的版本:
這裡選擇 3.x
,然後按Enter鍵進入下一步,這個介面是詢問我們是否使用 vue-class-component
形式來開發程式碼:
我們輸入 n
,因為 Vue3 開始,官方推薦開發者使用 Composition API
的形式來組織程式碼,然後進入下一步:
這個選項的含義是說使用 babel
和 Typescript
做程式碼編譯(包括自動引入polyfill,編譯JSX等),這裡我們輸入 y
,然後進入下一步:
這裡我們選擇 ESLint + Standard config
來作為程式碼檢測工具,然後進入下一步:
選擇 Lint on save
即可,在程式碼儲存的時候,自動修正不符合 eslint
規則的程式碼,然後進入下一步:
這個選項的含義是說把 babel
eslint
這些工具單獨放在各自的配置檔案還是統一寫入 package.json
檔案中,這裡我們選擇 In dedicated config files
,然後按回車進入下一步:
這裡是詢問我們是否要儲存剛才的選項配置,我們輸入 n
即可,然後開始初始化專案程式碼,並安裝對應的依賴包:
出現這樣的介面,恭喜你,安裝成功!
擴充閱讀:《Vue3 Typescript + Axios 全棧開發教程:手把手教你寫 APP 實戰》
Vue3 TypeScript 目錄及重點檔案解讀
安裝成功之後,會有一個初始專案結構:
下面給大家介紹下主要的檔案:
|-- public //無需打包的靜態資原始檔
|-- src //專案原始碼目錄
|-- assets //需要打包的靜態資源
|-- components //公共元件
|-- main.ts //專案入口檔案
|-- shims-vue.d.ts //宣告檔案
|-- .browserslistrc //相容目標瀏覽器範圍的配置檔案
|-- .eslintrc.js //eslint配置檔案
|-- babel.config.js //babel配置檔案
|-- tsconfig.json //ts配置檔案
tsconfig.json
配置檔案需要重點了解下:
{
"compilerOptions": {
"target": "esnext", //指定 ECMAScript 的目標版本,這裡使用 “esnext” 是因為 vue-cli 內建的 webpack 會幫我們編譯程式碼
"module": "esnext", //指定使用的模組規範
"strict": true, //是否開啟嚴格模式
"jsx": "preserve", //指定 jsx 程式碼的生成
"importHelpers": true, //是否使用 ts 原生 lib 庫中支援的輔助工具
"moduleResolution": "node", //模組解析策略
"skipLibCheck": true, //是否跳過預設庫宣告檔案的型別檢查
"esModuleInterop": true, //開啟此選項可以修復 esm 和 cjs 在使用 import 的時候導致的相容性問題
"allowSyntheticDefaultImports": true, //此選項允許開發者從沒有設定預設匯出的模組中進行預設匯入
"sourceMap": true, //是否生成對應的 .map 檔案
"baseUrl": ".", //用於解析模組名稱的根目錄
"types": [ //指定需要包含的型別宣告的目錄
"webpack-env"
],
"paths": { //指定路徑對映規則,類似 webpack 中 alisa 的用法
"@/*": [
"src/*"
]
},
"lib": [ //指定要包含在編譯中的庫檔案
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [ //指定需要編譯的檔案型別或目錄
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [ //排除不需要編譯的檔案或目錄
"node_modules"
]
}
然後我們執行 npm run serve
,即可啟動開發伺服器,然後開啟瀏覽器,輸入 http://localhost:8081
就可以訪問專案首頁:
擴充套件閱讀:《Vue form 表單非同步驗證終極教程 async-validator 表單校驗》
Vue3 Typescript 快速上手
接下來我們談談相對於 Vue2
來說 Vue3
有哪些提升與變化,瞭解這些變化,讓我們更容易上手 Vue3
,我打算從效能差別及 Composition API 使用兩個大方面來談,幫助大家快速上手。
Vue3 Typescript 與 Vue2 效能最佳化對比
效能最佳化
- 原始碼體積的最佳化,
Vue3
引入tree-shaking
的技術,減少打包體積 - 底層響應式的最佳化,
Vue3
底層依賴Proxy API
實現資料響應式,對比Vue2
的Object.defineProperty
有更強的資料劫持能力,並且可以做到“惰性監聽” - 編譯時最佳化,提出
block tree
概念,每次diff
只會比較兩棵樹的動態節點,對比Vue2
的元件樹全量diff
,有明顯的效能優勢
- 原始碼體積的最佳化,
語法 API 最佳化:Composition API
- 最佳化程式碼邏輯組織,可以讓程式碼邏輯更聚焦
- 類似
hook
的使用方法,最佳化元件複用的能力
原始碼最佳化
- 使用
monorepo
更好的程式碼管理程式碼 - 使用
TypeScript
重構專案原始碼,利於程式碼的維護
- 使用
以上幾點都是 Vue3
的這次主要改進,接下來開始學習 Composition API 的使用。
擴充套件閱讀:《Element Plus 如何按需引入和自動匯入?》
Vue3 setup & ref 使用教程
在 src
目錄下新建資料夾 test-api
,並建立 Setup.vue
檔案:
<template>
<div>
<h2>ref & setup 基本使用方法</h2>
<h2>{{ counter }}</h2>
<button @click="add">+</button>
<button @click="minus">-</button>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
export default defineComponent({
name: 'Setup',
setup (props, context) {
console.log(props, context)
const counter = ref(0)
const add = () => {
counter.value = counter.value + 1
}
const minus = () => {
counter.value = counter.value - 1
}
return {
counter,
add,
minus
}
}
})
</script>
然後修改 App.vue
檔案如下:
<template>
<SetupVue />
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import SetupVue from './test-api/Setup.vue'
export default defineComponent({
name: 'App',
components: {
SetupVue
}
})
</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>
可以看到介面會發生變化,並且可以正常使用加減功能:
這是最簡單的 setup
和 ref
的使用,setup
就是 Composition API 的入口,可以認為是元件的邏輯入口。ref
用來建立響應式的資料物件,傳入的引數為基本型別,返回一個物件,該物件是響應式物件,並且只包含一個 value 屬性,用於讀取這個物件的值。
擴充套件閱讀:《5 款最棒的 Vue UI 移動端元件庫 - 特別針對國內使用場景推薦》
Vue3 reactive 使用教程
reactive
有點類似 ref
,只不過 reactive
接受的是引用型別,比如物件,陣列等,返回的也是一個響應式資料。 在 test-api
下新建 Reactive.vue
檔案:
<template>
<div>
<h2>reactive 基本使用方法</h2>
<h2>{{ info.name }} - {{ info.en }}</h2>
<h3>{{ info.desc }}</h3>
<button @click="updateDesc">update desc</button>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue'
export default defineComponent({
name: 'Setup',
setup () {
const info = reactive({ name: '卡拉雲', en: 'kalacloud', desc: '' })
const updateDesc = () => {
info.desc = '「卡拉雲 - 極速搭建企業內部工具,十倍提升開發效率」'
}
return {
info,
updateDesc
}
}
})
</script>
然後再 App.vue
中匯入,可以看到效果:
reactive
和 ref
不同的是,ref
建立出來的資料可以直接在模版中使用,不需要 .value
取值,vue 內部會幫我們自動處理。
不想處理 Vue 前端問題?
試試卡拉雲,拖拽元件連線 API 和資料庫直接生成後臺管理工具,數月的工期降低至1天
擴充套件閱讀:《如何在 Vue 中加入圖表 - Vue echarts 使用教程》
Vue3 watch 使用教程
這個 API 和 Vue2
中 watch 功能基本一致,接受三個引數:監聽的值、回撥、其他配置項,我們來使用一下,這裡基於 Setup.vue
稍作修改即可:
<template>
<div>
<h2>watch 基本使用方法</h2>
<h2>{{ counter }}</h2>
<button @click="add">+</button>
<button @click="minus">-</button>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, watch } from 'vue'
export default defineComponent({
name: 'Setup',
setup (props, context) {
console.log(props, context)
const counter = ref(0)
const add = () => {
counter.value = counter.value + 1
}
const minus = () => {
counter.value = counter.value - 1
}
watch(counter, (newValue, oldValue) => {
console.log('counter 發生了變化,最新的值是:', newValue)
})
return {
counter,
add,
minus
}
}
})
</script>
可以看到,每次 counter 發生改變,都可以輸出到控制檯最新的結果:
watch
第三個引數接受一個可選物件:
{
immediate: true, // 初始化的時候就會執行一次回撥函式
deep: false, // 深度監聽物件的變化
flush: 'pre' | 'post' | 'sync' // pre=回撥函式在渲染前呼叫;post=回撥函式在渲染後呼叫;sync=回撥將被同步呼叫,慎用!可能會阻塞頁面渲染
}
擴充套件閱讀:《最好用的 6 款 Vue 拖拽元件庫推薦》
Vue3 computed 使用教程
computed
是計算屬性,其值依賴響應式資料,如果響應式資料發生改變,vue 會幫我們自動計算改變後的值,像這樣使用,在 test-api
新建 Computed.vue
檔案:
<template>
<div>
<h2>computed 基本使用方法</h2>
<h3>「卡拉雲 - 極速搭建企業內部工具,十倍提升開發效率」</h3>
<h2>{{ info }}</h2>
<button @click="update">update</button>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, reactive, ref } from 'vue'
export default defineComponent({
name: 'Setup',
setup () {
const prefix = ref('')
const msg = reactive({ name: '卡拉雲' })
const info = computed(() => prefix.value + msg.name)
const update = () => {
prefix.value = 'kalacloud - '
}
return {
info,
update
}
}
})
</script>
我們會發現,prefix
發生了改變,info
也會隨之改變,這就是 computed
的用法
如果被依賴的響應式資料沒有發生改變,那麼也不會重新計算,所以 computed
還有快取的特性,一般用於快取計算量比較大的資料。
以上是 Vue3
Composition API 的一些使用方法,接下來,我會帶領大家實際開發一個簡單的應用,鞏固學習的這些 API。
擴充套件閱讀:《ToolJet 是什麼,怎麼樣? —— 低程式碼開發平臺測評》
使用 Vue3 TypeScript + element-plus 開發「待辦清單」例項
先為我們的應用安裝UI框架,這樣視覺上會好看些,在命令列執行下面的命令:
npm install element-plus --save
安裝好之後,在 main.ts
中z戶廁元件並匯入樣式檔案:
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
先建立一個 types
資料夾,用來存放專案中型別宣告檔案,比如我們這個 todo 應用,可以建立一個 todo.ts
:
export interface Todo {
id: number;
title: string;
done: boolean;
}
然後在 components
資料夾下新建 TodoList.vue
,這個元件用來實現處理每個待辦事項的操作邏輯
<template>
<div class="todo-item">
<el-checkbox v-model="todo!.done" />
<el-alert class="alert" :title="todo!.title" :type="todo!.done ? 'success' : 'warning'" :closable="false" />
<el-button type="danger" @click="remove">刪除</el-button>
</div>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue'
import { Todo } from '../types/todo'
export default defineComponent({
props: {
todo: {
type: Object as PropType<Todo>
}
},
emits: ['toggle', 'remove'],
setup (props, context) {
const toggle = () => {
context.emit('toggle', props.todo!.id)
}
const remove = () => {
context.emit('remove', props.todo!.id)
}
return {
toggle,
remove
}
}
})
</script>
<style scoped>
.todo-item {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.alert {
margin: 0 20px;
}
</style>
我們把 toggle
,remove
這兩個操作透過 emit
派發給父元件,在父元件去實現具體的業務邏輯,不過先不著急,我們先實現新增待辦事項的元件,同樣在 components
中建立 AddTodo.vue
:
<template>
<div class="add-todo">
<el-input type="text" v-model="state.inputValue" />
<el-button @click="onClick" class="add-button" type="primary">新增</el-button>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, watchEffect } from 'vue'
interface State {
inputValue: string;
}
export default defineComponent({
emits: ['add'],
setup (_, context) {
const state = reactive<State>({
inputValue: ''
})
const onClick = () => {
context.emit('add', state.inputValue)
state.inputValue = ''
}
return {
state,
onClick
}
}
})
</script>
<style scoped>
.add-todo {
display: flex;
}
.add-button {
margin-left: 20px;
}
</style>
同樣的,使用 context.emit('add', state.inputValue)
來派發事件給父元件,然後我們先實現 add
,remove
,toggle
這三個方法,並封裝成一個工具函式,在 src
目錄中建立 utils
資料夾,然後建立 todoAction.ts
,用來承載具體的業務邏輯:
import { Ref } from 'vue'
import { Todo } from '@/types/todo'
export default (todos: Ref<Todo[]>) => {
const addTodo = (title: string) => {
todos.value = [...todos.value, {
id: todos.value.length + 1,
title,
done: false
}]
}
const removeTodo = (id: number) => {
todos.value = todos.value.filter(todo => todo.id !== id)
}
const toggleTodo = (id: number) => {
const todo = todos.value.find(todo => todo.id === id)
if (!todo) return
todo.done = !todo.done
}
return {
addTodo,
removeTodo,
toggleTodo
}
}
addTodo
用來實現新增一個待辦事項,removeTodo
用來實現移除一個待辦事項,toggleTodo
用來更新待辦事項的狀態。最後我們來實現父元件,建立 Todo.vue
檔案:
<template>
<todo-list
v-for="todo in todos"
:todo="todo"
:key="todo.id"
@toggle="toggleTodo"
@remove="removeTodo"
/>
<add-todo
@add="addTodo"
/>
</template>
<script lang="ts">
import { defineComponent, watchEffect, ref } from 'vue'
import TodoList from './TodoList.vue'
import AddTodo from './AddTodo.vue'
import todoAction from '../utils/todoAction'
import { Todo } from '../types/todo'
const initialTodos: Todo[] = [
{
id: 1,
title: '使用卡拉雲建立表單',
done: false
},
{
id: 2,
title: '使用卡拉雲建立圖表',
done: false
},
{
id: 3,
title: '使用卡拉雲建立應用',
done: false
}
]
export default defineComponent({
components: {
TodoList,
AddTodo
},
setup () {
const todos = ref<Todo[]>(initialTodos)
const { addTodo, removeTodo, toggleTodo } = todoAction(todos)
return {
todos,
addTodo,
removeTodo,
toggleTodo
}
}
})
</script>
元件的程式碼實現基本完成了,在 App.vue
中進行使用,最後的效果如下:
這個應用雖然簡單,但是五臟俱全,透過這篇文章,大家可以學習到如何基於 Vue3
的組合API並結合 Typescript
進行開發。本文中的所有程式碼均可以在 kalacloud-vue3-ts 中找到。
擴充套件閱讀:《appsmith 是什麼?怎麼樣,評價如何》
Vue3 Typescript 上手教程總結
本文詳細講解新版 Vue3 Typescript 與舊版 Vue 有什麼區別及程式碼上的不同。其實如果你根本不想處理複雜的前端問題,完全可以使用卡拉雲來搭建前端工具,卡拉雲內建多種常用元件,無需懂任何前端,僅需拖拽即可快速生成,一鍵連線後端資料來源,極速開發後臺管理工具。
卡拉雲可幫你快速搭建企業內部工具,下圖為使用卡拉雲搭建的內部廣告投放監測系統,無需懂前端,僅需拖拽元件,10 分鐘搞定。你也可以快速搭建一套屬於你的後臺管理工具,瞭解更多。
卡拉雲是新一代低程式碼開發平臺,與前端框架 Vue、React等相比,卡拉雲的優勢在於不用首先搭建開發環境,直接註冊即可開始使用。開發者完全不用處理任何前端問題,只需簡單拖拽,即可快速生成所需元件,可一鍵接入常見資料庫及 API,根據引導簡單幾步打通前後端,數週的開發時間,縮短至 1 小時。立即免費試用卡拉雲。
擴充套件閱讀: