隨著Vue3正式版的到來,帶來了一些新的特性:
- Composition API: 這是一個(gè)從react hooks上受啟發(fā)的組件
- Portals: 可以在vue當(dāng)前組件外渲染dom節(jié)點(diǎn)
- Fragments: 允許有多個(gè)root節(jié)點(diǎn)
- 更新的v-model-api: 支持多個(gè)models
- Suspense: 異步加載組件的loading界面
- TypeScript: Vue從現(xiàn)在起完全支持Typescript
本著學(xué)習(xí)的精神,我決定嘗試下從零開始自己搭建一個(gè)Vue3 + Typescript的項(xiàng)目
創(chuàng)建一個(gè)項(xiàng)目
第一件事就是初始化一個(gè)項(xiàng)目
yarn init
然后添加依賴,對Vue3實(shí)現(xiàn)最基本的支持
yarn add vue
yarn add -D webpack webpack-cli webpack-dev-server @vue/compiler-sfc
添加webpack配置
import { resolve } from './utils'
import { Configuration as WebpackConfiguration, HotModuleReplacementPlugin } from "webpack"
import { Configuration as WebpackDevServerConfiguration } from "webpack-dev-server"
import HtmlWebpackPlugin from "html-webpack-plugin"
import { VueLoaderPlugin } from 'vue-loader'
interface Configuration extends WebpackConfiguration {
devServer?: WebpackDevServerConfiguration;
}
const config: Configuration = {
entry: "./src/main.tsx",
resolve: {
extensions: [".tsx", ".ts", ".js", ".json"],
alias: {
vue$: 'vue/dist/vue.runtime.esm-bundler.js',
'@': resolve('src')
}
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.tsx?$/,
exclude: /node_modules/,
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
}
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
},
plugins: [
new VueLoaderPlugin()
],
devServer: {
historyApiFallback: true,
host: 'localhost',
port: 4000,
open: true,
hot: true,
allowedHosts: 'all',
compress: true, // 為所有服務(wù)啟用gzip 壓縮
}
}
export default config
增加Typescript支持
方案一:使用ts-loader
yarn add -D ts-loader
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
}
}
]
}
方案二:使用babel-loader + @babel/preset-typescript
yarn add -D @babel/core babel-loader @babel/preset-typescript
module: {
rules: [
{
test: /\.(jsx?|tsx?)$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
}
- babel.config.js
module.exports = {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: '3.0',
},
],
[
"@babel/preset-typescript",
{
allExtensions: true, // 支持所有文件擴(kuò)展名,否則在vue文件中使用ts會報(bào)錯(cuò)
},
]
]
}
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"useDefineForClassFields": true,
"sourceMap": true,
"baseUrl": "./",
"typeRoots": [
"types",
"node_modules/@types"
],
"paths": {
"@/*": ["src/*"]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"ts-node": {
"compilerOptions": {
"module": "CommonJS"
}
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}
配置package.json命令
當(dāng)webpack基本配置好后,添加scripts命令來運(yùn)行
{
"scripts": {
"dev": "webpack serve --development",
"build": "webpack --mode production"
}
}
.vue文件使用ts問題
為了避免.vue文件使用ts報(bào)錯(cuò),在src目錄下添加shim-vue.d.ts文件
declare module '*.vue' {
import { defineComponent } from 'vue'
const component: ReturnType<typeof defineComponent>
export default component
}
vue-router
vue3相對應(yīng)的vue-router版本是@4.0+的,語法上與過往版本略有區(qū)別
- 創(chuàng)建Vue-router配置,createWebHashHistory為hash模式,createWebHistory為history模式
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '@/Home.vue'
const routes = [
{
path: '/',
component: Home
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
pinia
pinia是完全使用Composition API編寫的,對于使用新的特性非常適合,可以拋棄vuex了。
import { defineStore } from 'pinia'
export const useStore = defineStore('main', {
// other options...
state: () => ({
counter: 0
}),
actions: {
increment() {
this.counter++
}
}
})
Vue入口文件main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
const app = createApp(App) // 創(chuàng)建Vue實(shí)例
const pinia = createPinia() // 創(chuàng)建pinia實(shí)例
app.use(router)
app.use(pinia)
app.mount('#app')
結(jié)語
以上就是分享的使用Vue + TypeScript的簡單案例,歡迎互相交流。