Vite2 + Vue3 + TypeScript + Pinia 搭建一套企業(yè)級的開發(fā)腳手架
前端學習路線一條龍【內(nèi)含入門到進階到高級精選資源】無套路獲取!!!
前端小菜雞之菜雞互啄,公眾號:前端開發(fā)愛好者xy哥怒肝,前端學習路線一條龍【內(nèi)含入門到進階到高級精選資源】無套路獲取!!!
哈嘍,大家好 我是
xy???????。從我最初接觸vue3版本到現(xiàn)在已經(jīng)有一年的時間。由于 vue3.2 版本的發(fā)布,<script setup>的實驗性標志已經(jīng)去掉,已經(jīng)陸陸續(xù)續(xù)有不少公司開始使用vue3.2開發(fā)項目了。這篇文章就來幫助大家如何快速使用vue3.x,typeScript,vite搭建一套企業(yè)級的開發(fā)腳手架 ??。廢話不多說,直接上手開搞 ??
搭建前準備
-
Vscode: 前端人必備寫碼神器 -
Chrome:對開發(fā)者非常友好的瀏覽器(反正我是很依賴它的) -
Nodejs&npm:配置本地開發(fā)環(huán)境,安裝 Node 后你會發(fā)現(xiàn) npm 也會一起安裝下來 -
Vue.js devtools:瀏覽器調(diào)試插件 -
Vue Language Features (Volar):Vscode 開發(fā) vue3 必備插件,提供語法高亮提示,非常好用 -
Vue 3 Snippets:vue3 快捷輸入
由于
Vue.js devtools需要到谷歌擴展商店才能下載,貼心 ?? 的xy已經(jīng)為大家準備好了crx文件了,公眾號回復(fù):【VueDevTools】可自動獲取哦 ??
Vue2 與 Vue3 的區(qū)別
Vue3由于完全由TS進行重寫,在應(yīng)用中對類型判斷的定義和使用有很強的表現(xiàn)。同一對象的多個鍵返回值必須通過定義對應(yīng)的接口(interface)來進行類型定義。要不然在 ESLint 時都會報錯。
vue2 的雙向數(shù)據(jù)綁定是利用 ES5 的一個 API Object.definePropert()對數(shù)據(jù)進行劫持 結(jié)合 發(fā)布訂閱模式的方式來實現(xiàn)的。Vue3 中使用了 es6 的 ProxyAPI 對數(shù)據(jù)代理。
Vue3支持碎片(Fragments)
Vue2 與 Vue3 最大的區(qū)別: Vue2 使用Options API而 Vue3 使用的Composition API
生命周期鉤子變化:
Vue2 ~~~~~~~~~~~ vue3
beforeCreate -> setup()
created -> setup()
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeDestroy -> onBeforeUnmount
destroyed -> onUnmounted
activated -> onActivated
deactivated -> onDeactivated
介紹 vite
Vite:下一代前端開發(fā)與構(gòu)建工具
-
?? 極速的開發(fā)服務(wù)器啟動 -
?? 輕量快速的熱模塊重載(HMR) -
??? 豐富的功能 -
?? 自帶優(yōu)化的構(gòu)建 -
?? 通用的插件接口 -
?? 完全類型化的 API
Vite (法語意為 “迅速”,發(fā)音 /vit/)是一種全新的前端構(gòu)建工具,它極大地改善了前端開發(fā)體驗。
它主要由兩部分組成:
-
一個開發(fā)服務(wù)器,它基于 原生
ES模塊 提供了 豐富的內(nèi)建功能,如速度快到驚人的 模塊熱更新(HMR)。 -
一套構(gòu)建指令,它使用
Rollup打包你的代碼,并且它是預(yù)配置的,可以輸出用于生產(chǎn)環(huán)境的優(yōu)化過的靜態(tài)資源。 -
Vite 意在提供開箱即用的配置,同時它的 插件 API 和 JavaScript API 帶來了高度的
可擴展性,并有完整的類型支持。
使用 vite 快速創(chuàng)建腳手架
兼容性注意:Vite 需要
Node.js版本>= 12.0.0。
-
第一步: 在需要創(chuàng)建項目文件目錄下打開 cmd運行以下命令
# npm 6.x
npm init @vitejs/app vite_vue3_ts --template
# npm 7+, 需要額外的雙橫線:
npm init @vitejs/app vite_vue3_ts -- --template
# yarn
yarn create @vitejs/app vite_vue3_ts --template
這里我采用 yarn 來安裝
-
第二步: 選擇 vue回車 =>vue-ts回車


-
第三步: cd到項目文件夾,安裝依賴,啟動項目
# 進入項目文件夾
cd vite_vue3_ts
# 安裝依賴
yarn
# 啟動
yarn dev
約束代碼風格
Eslint 支持
# eslint 安裝
yarn add eslint --dev
# eslint 插件安裝
yarn add eslint-plugin-vue --dev
yarn add @typescript-eslint/eslint-plugin --dev
yarn add eslint-plugin-prettier --dev
# typescript parser
yarn add @typescript-eslint/parser --dev
注意: 如果 eslint 安裝報錯:
可以嘗試運行以下命令:
yarn config set ignore-engines true
運行成功后再次執(zhí)行 eslint 安裝命令
項目下新建 .eslintrc.js
配置
eslint校驗規(guī)則:
module.exports = {
root: true,
env: {
browser: true,
node: true,
es2021: true,
},
parser: 'vue-eslint-parser',
extends: [
'eslint:recommended',
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
// eslint-config-prettier 的縮寫
'prettier',
],
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
// eslint-plugin-vue @typescript-eslint/eslint-plugin eslint-plugin-prettier的縮寫
plugins: ['vue', '@typescript-eslint', 'prettier'],
rules: {
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'no-var': 'error',
'prettier/prettier': 'error',
// 禁止出現(xiàn)console
'no-console': 'warn',
// 禁用debugger
'no-debugger': 'warn',
// 禁止出現(xiàn)重復(fù)的 case 標簽
'no-duplicate-case': 'warn',
// 禁止出現(xiàn)空語句塊
'no-empty': 'warn',
// 禁止不必要的括號
'no-extra-parens': 'off',
// 禁止對 function 聲明重新賦值
'no-func-assign': 'warn',
// 禁止在 return、throw、continue 和 break 語句之后出現(xiàn)不可達代碼
'no-unreachable': 'warn',
// 強制所有控制語句使用一致的括號風格
curly: 'warn',
// 要求 switch 語句中有 default 分支
'default-case': 'warn',
// 強制盡可能地使用點號
'dot-notation': 'warn',
// 要求使用 === 和 !==
eqeqeq: 'warn',
// 禁止 if 語句中 return 語句之后有 else 塊
'no-else-return': 'warn',
// 禁止出現(xiàn)空函數(shù)
'no-empty-function': 'warn',
// 禁用不必要的嵌套塊
'no-lone-blocks': 'warn',
// 禁止使用多個空格
'no-multi-spaces': 'warn',
// 禁止多次聲明同一變量
'no-redeclare': 'warn',
// 禁止在 return 語句中使用賦值語句
'no-return-assign': 'warn',
// 禁用不必要的 return await
'no-return-await': 'warn',
// 禁止自我賦值
'no-self-assign': 'warn',
// 禁止自身比較
'no-self-compare': 'warn',
// 禁止不必要的 catch 子句
'no-useless-catch': 'warn',
// 禁止多余的 return 語句
'no-useless-return': 'warn',
// 禁止變量聲明與外層作用域的變量同名
'no-shadow': 'off',
// 允許delete變量
'no-delete-var': 'off',
// 強制數(shù)組方括號中使用一致的空格
'array-bracket-spacing': 'warn',
// 強制在代碼塊中使用一致的大括號風格
'brace-style': 'warn',
// 強制使用駱駝拼寫法命名約定
camelcase: 'warn',
// 強制使用一致的縮進
indent: 'off',
// 強制在 JSX 屬性中一致地使用雙引號或單引號
// 'jsx-quotes': 'warn',
// 強制可嵌套的塊的最大深度4
'max-depth': 'warn',
// 強制最大行數(shù) 300
// "max-lines": ["warn", { "max": 1200 }],
// 強制函數(shù)最大代碼行數(shù) 50
// 'max-lines-per-function': ['warn', { max: 70 }],
// 強制函數(shù)塊最多允許的的語句數(shù)量20
'max-statements': ['warn', 100],
// 強制回調(diào)函數(shù)最大嵌套深度
'max-nested-callbacks': ['warn', 3],
// 強制函數(shù)定義中最多允許的參數(shù)數(shù)量
'max-params': ['warn', 3],
// 強制每一行中所允許的最大語句數(shù)量
'max-statements-per-line': ['warn', { max: 1 }],
// 要求方法鏈中每個調(diào)用都有一個換行符
'newline-per-chained-call': ['warn', { ignoreChainWithDepth: 3 }],
// 禁止 if 作為唯一的語句出現(xiàn)在 else 語句中
'no-lonely-if': 'warn',
// 禁止空格和 tab 的混合縮進
'no-mixed-spaces-and-tabs': 'warn',
// 禁止出現(xiàn)多行空行
'no-multiple-empty-lines': 'warn',
// 禁止出現(xiàn);
semi: ['warn', 'never'],
// 強制在塊之前使用一致的空格
'space-before-blocks': 'warn',
// 強制在 function的左括號之前使用一致的空格
// 'space-before-function-paren': ['warn', 'never'],
// 強制在圓括號內(nèi)使用一致的空格
'space-in-parens': 'warn',
// 要求操作符周圍有空格
'space-infix-ops': 'warn',
// 強制在一元操作符前后使用一致的空格
'space-unary-ops': 'warn',
// 強制在注釋中 // 或 /* 使用一致的空格
// "spaced-comment": "warn",
// 強制在 switch 的冒號左右有空格
'switch-colon-spacing': 'warn',
// 強制箭頭函數(shù)的箭頭前后使用一致的空格
'arrow-spacing': 'warn',
'no-var': 'warn',
'prefer-const': 'warn',
'prefer-rest-params': 'warn',
'no-useless-escape': 'warn',
'no-irregular-whitespace': 'warn',
'no-prototype-builtins': 'warn',
'no-fallthrough': 'warn',
'no-extra-boolean-cast': 'warn',
'no-case-declarations': 'warn',
'no-async-promise-executor': 'warn',
},
globals: {
defineProps: 'readonly',
defineEmits: 'readonly',
defineExpose: 'readonly',
withDefaults: 'readonly',
},
}
項目下新建 .eslintignore
# eslint 忽略檢查 (根據(jù)項目需要自行添加)
node_modules
dist
prettier 支持
# 安裝 prettier
yarn add prettier --dev
解決 eslint 和 prettier 沖突
解決
ESLint中的樣式規(guī)范和prettier中樣式規(guī)范的沖突,以prettier的樣式規(guī)范為準,使 ESLint 中的樣式規(guī)范自動失效
# 安裝插件 eslint-config-prettier
yarn add eslint-config-prettier --dev
項目下新建 .prettier.js
配置
prettier格式化規(guī)則:
module.exports = {
tabWidth: 2,
jsxSingleQuote: true,
jsxBracketSameLine: true,
printWidth: 100,
singleQuote: true,
semi: false,
overrides: [
{
files: '*.json',
options: {
printWidth: 200,
},
},
],
arrowParens: 'always',
}
項目下新建 .prettierignore
# 忽略格式化文件 (根據(jù)項目需要自行添加)
node_modules
dist
package.json 配置:
{
"script": {
"lint": "eslint src --fix --ext .ts,.tsx,.vue,.js,.jsx",
"prettier": "prettier --write ."
}
}
上面配置完成后,可以運行以下命令測試下代碼檢查個格式化效果:
# eslint 檢查
yarn lint
# prettier 自動格式化
yarn prettier
配置 husky + lint-staged
使用
husky+lint-staged助力團隊編碼規(guī)范, husky&lint-staged 安裝推薦使用mrm, 它將根據(jù)package.json依賴項中的代碼質(zhì)量工具來安裝和配置 husky 和 lint-staged,因此請確保在此之前安裝并配置所有代碼質(zhì)量工具,如Prettier 和 ESlint
首先安裝 mrm
npm i mrm -D --registry=https://registry.npm.taobao.org
husky 是一個為 git 客戶端增加 hook 的工具。安裝后,它會自動在倉庫中的 .git/ 目錄下增加相應(yīng)的鉤子;比如 pre-commit 鉤子就會在你執(zhí)行 git commit 的觸發(fā)。
那么我們可以在 pre-commit 中實現(xiàn)一些比如 lint 檢查、單元測試、代碼美化等操作。當然,pre-commit 階段執(zhí)行的命令當然要保證其速度不要太慢,每次 commit 都等很久也不是什么好的體驗。
lint-staged,一個僅僅過濾出 Git 代碼暫存區(qū)文件(被 git add 的文件)的工具;這個很實用,因為我們?nèi)绻麑φ麄€項目的代碼做一個檢查,可能耗時很長,如果是老項目,要對之前的代碼做一個代碼規(guī)范檢查并修改的話,這可能就麻煩了呀,可能導致項目改動很大。
所以這個 lint-staged,對團隊項目和開源項目來說,是一個很好的工具,它是對個人要提交的代碼的一個規(guī)范和約束
安裝 lint-staged
mrm安裝lint-staged會自動把husky一起安裝下來
npx mrm lint-staged
安裝成功后會發(fā)現(xiàn) package.json 中多了一下幾個配置:
因為我們要結(jié)合 prettier 代碼格式化,所有修改一下配置:
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,jsx,vue,ts,tsx}": [
"yarn lint",
"prettier --write",
"git add"
]
}
好了,到這里代碼格式化配置基本大功告成了!!!
可以修改部分代碼嘗試 git commit ,你會發(fā)現(xiàn)代碼將自動格式化:
提交前的代碼(發(fā)現(xiàn)編輯器爆紅了):
執(zhí)行 commit 操作,控制臺可以看到走了哪些流程:
commit 后的代碼,是不是已經(jīng)被格式化了
配置文件引用別名 alias
直接修改
vite.config.ts文件配置:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
})
修改
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"baseUrl": ".",
"paths": {
"@/*":["src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
配置 css 預(yù)處理器 scss
雖然
vite原生支持less/sass/scss/stylus,但是你必須手動安裝他們的預(yù)處理器依賴
安裝
yarn ass sass-loader --dev
yarn add dart-sass --dev
yarn add sass --dev
配置全局 scss 樣式文件
在 src/assets 下新增 style 文件夾,用于存放全局樣式文件
新建 main.scss, 設(shè)置一個用于測試的顏色變量 :
$test-color: red;
如何將這個全局樣式文件全局注入到項目中呢?配置 Vite 即可:
css:{
preprocessorOptions:{
scss:{
additionalData:'@import "@/assets/style/mian.scss";'
}
}
},
組件中使用
不需要任何引入可以直接使用全局
scss定義的變量
.test{
color: $test-color;
}
路由
# 安裝路由
yarn add vue-router@4
在 src 文件下新增 router 文件夾 => router.ts 文件,內(nèi)容如下:
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'Login',
component: () => import('@/pages/login/Login.vue'), // 注意這里要帶上 文件后綴.vue
},
]
const router = createRouter({
history: createWebHistory(),
routes,
})
export default router
修改入口文件 mian.ts :
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
const app = createApp(App)
app.use(router)
app.mount('#app')
到這里路由的基礎(chǔ)配置已經(jīng)完成了,更多配置信息可以查看 vue-router 官方文檔:
vue-router:
https://next.router.vuejs.org/zh/guide/
vue-router4.x 支持 typescript,配置路由的類型是 RouteRecordRaw,這里 meta 可以讓我們有更多的發(fā)揮空間,這里提供一些參考:
-
title:string; 頁面標題,通常必選。 -
icon?:string; 圖標,一般配合菜單使用。 -
auth?:boolean; 是否需要登錄權(quán)限。 -
ignoreAuth?:boolean; 是否忽略權(quán)限。 -
roles?:RoleEnum[]; 可以訪問的角色 -
keepAlive?:boolean; 是否開啟頁面緩存 -
hideMenu?:boolean; 有些路由我們并不想在菜單中顯示,比如某些編輯頁面。 -
order?:number; 菜單排序。 -
frameUrl?:string; 嵌套外鏈。
這里只提供一些思路,每個項目涉及到的業(yè)務(wù)都會存在些差異,這里就不作詳細講解了,根據(jù)自己業(yè)務(wù)需求做配置即可。
統(tǒng)一請求封裝
使用過 vue2.x 的同學應(yīng)該對 axios 很熟悉了,這里我們直接使用 axios 做封裝:
# 安裝 axios
yarn add axios
# 安裝 nprogress 用于請求 loading
# 也可以根據(jù)項目需求自定義其它 loading
yarn add nprogress
# 類型聲明,或者添加一個包含 `declare module 'nprogress'
yarn add @types/nprogress --dev
實際使用中可以根據(jù)項目修改,比如RESTful api中可以自行添加put和delete請求,ResType也可以根據(jù)后端的通用返回值動態(tài)的去修改
新增 service 文件夾,service 下新增 http.ts 文件以及 api 文件夾:
http.ts : 用于axios封裝
//http.ts
import axios, { AxiosRequestConfig } from 'axios'
import NProgress from 'nprogress'
// 設(shè)置請求頭和請求路徑
axios.defaults.baseURL = '/api'
axios.defaults.timeout = 10000
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
axios.interceptors.request.use(
(config): AxiosRequestConfig<any> => {
const token = window.sessionStorage.getItem('token')
if (token) {
//@ts-ignore
config.headers.token = token
}
return config
},
(error) => {
return error
}
)
// 響應(yīng)攔截
axios.interceptors.response.use((res) => {
if (res.data.code === 111) {
sessionStorage.setItem('token', '')
// token過期操作
}
return res
})
interface ResType<T> {
code: number
data?: T
msg: string
err?: string
}
interface Http {
get<T>(url: string, params?: unknown): Promise<ResType<T>>
post<T>(url: string, params?: unknown): Promise<ResType<T>>
upload<T>(url: string, params: unknown): Promise<ResType<T>>
download(url: string): void
}
const http: Http = {
get(url, params) {
return new Promise((resolve, reject) => {
NProgress.start()
axios
.get(url, { params })
.then((res) => {
NProgress.done()
resolve(res.data)
})
.catch((err) => {
NProgress.done()
reject(err.data)
})
})
},
post(url, params) {
return new Promise((resolve, reject) => {
NProgress.start()
axios
.post(url, JSON.stringify(params))
.then((res) => {
NProgress.done()
resolve(res.data)
})
.catch((err) => {
NProgress.done()
reject(err.data)
})
})
},
upload(url, file) {
return new Promise((resolve, reject) => {
NProgress.start()
axios
.post(url, file, {
headers: { 'Content-Type': 'multipart/form-data' },
})
.then((res) => {
NProgress.done()
resolve(res.data)
})
.catch((err) => {
NProgress.done()
reject(err.data)
})
})
},
download(url) {
const iframe = document.createElement('iframe')
iframe.style.display = 'none'
iframe.src = url
iframe.onload = function () {
document.body.removeChild(iframe)
}
document.body.appendChild(iframe)
},
}
export default http
api : 項目中接口做統(tǒng)一管理,按照模塊來劃分
在 api 文件下新增 login 文件夾,用于存放登錄模塊的請求接口,login 文件夾下分別新增 login.ts types.ts :
login.ts:
import http from '@/service/http'
import * as T from './types'
const loginApi: T.ILoginApi = {
login(params){
return http.post('/login', params)
}
}
export default loginApi
types.ts:
export interface ILoginParams {
userName: string
passWord: string | number
}
export interface ILoginApi {
login: (params: ILoginParams)=> Promise<any>
}
至此,一個簡單地請求封裝完成了!!!!
除了自己手動封裝 axios ,這里還推薦一個 vue3 的請求庫: VueRequest,非常好用,下面來看看 VueRequest有哪些比較好用的功能吧!!!
-
?? 所有數(shù)據(jù)都具有響應(yīng)式 -
?? 輪詢請求 -
?? 自動處理錯誤重試 -
?? 內(nèi)置請求緩存 -
?? 節(jié)流請求與防抖請求 -
?? 聚焦頁面時自動重新請求 -
?? 強大的分頁擴展以及加載更多擴展 -
?? 完全使用 Typescript 編寫,具有強大的類型提示 -
?? 兼容 Vite -
?? 輕量化 -
?? 開箱即用
是不是很強大 ??
官網(wǎng)鏈接: https://www.attojs.com/
狀態(tài)管理 pinia
由于 vuex 4 對 typescript 的支持讓人感到難過,所以狀態(tài)管理棄用了 vuex 而采取了 pinia. pinia 的作者是 Vue 核心團隊成員
尤大好像說 pinia 可能會代替 vuex,所以請放心使用。
安裝 pinia
Pinia 與 Vuex 的區(qū)別:
-
id是必要的,它將所使用 store 連接到 devtools。 -
創(chuàng)建方式: new Vuex.Store(...)(vuex3),createStore(...)(vuex4)。 -
對比于 vuex3 ,state 現(xiàn)在是一個 函數(shù)返回對象。 -
沒有 mutations,不用擔心,state 的變化依然記錄在 devtools 中。
# 安裝
yarn add pinia@next
main.ts 中增加
# 引入
import { createPinia } from "pinia"
# 創(chuàng)建根存儲庫并將其傳遞給應(yīng)用程序
app.use(createPinia())
在 src 文件夾下新增 store 文件夾,接在在 store 中新增 main.ts
創(chuàng)建 store, mian.ts :
import { defineStore } from 'pinia'
export const useMainStore = defineStore({
id: 'mian',
state: () =>({
name: '超級管理員'
})
})
組建中獲取 store :
<template>
<div>{{mainStore.name}}</div>
</template>
<script setup lang="ts">
import { useMainStore } from "@/store/mian"
const mainStore = useMainStore()
</script>
getters 用法介紹
Pinia 中的 getter 與 Vuex 中的 getter 、組件中的計算屬性具有相同的功能
store => mian.ts
import { defineStore } from 'pinia'
export const useMainStore = defineStore({
id: 'mian',
state: () => ({
name: '超級管理員',
}),
// getters
getters: {
nameLength: (state) => state.name.length,
}
})
組件中使用:
<template>
<div>用戶名:{{ mainStore.name }}<br />長度:{{ mainStore.nameLength }}</div>
<hr/>
<button @click="updateName">修改store中的name</button>
</template>
<script setup lang="ts">
import { useMainStore } from '@/store/mian'
const mainStore = useMainStore()
const updateName = ()=>{
// $patch 修改 store 中的數(shù)據(jù)
mainStore.$patch({
name: '名稱被修改了,nameLength也隨之改變了'
})
}
</script>
actions
這里與
Vuex有極大的不同,Pinia僅提供了一種方法來定義如何更改狀態(tài)的規(guī)則,放棄mutations只依靠Actions,這是一項重大的改變。
Pinia 讓 Actions 更加的靈活:
-
可以通過組件或其他 action調(diào)用 -
可以從其他 store的action中調(diào)用 -
直接在 store實例上調(diào)用 -
支持 同步或異步 -
有任意數(shù)量的參數(shù) -
可以包含有關(guān)如何更改狀態(tài)的邏輯(也就是 vuex 的 mutations 的作用) -
可以 $patch方法直接更改狀態(tài)屬性
import { defineStore } from 'pinia'
export const useMainStore = defineStore({
id: 'mian',
state: () => ({
name: '超級管理員',
}),
getters: {
nameLength: (state) => state.name.length,
},
actions: {
async insertPost(data:string){
// 可以做異步
// await doAjaxRequest(data);
this.name = data;
}
},
})
環(huán)境變量配置
vite提供了兩種模式:具有開發(fā)服務(wù)器的開發(fā)模式(development)和生產(chǎn)模式(production)
項目根目錄新建:.env.development :
NODE_ENV=development
VITE_APP_WEB_URL= 'YOUR WEB URL'
項目根目錄新建:.env.production :
NODE_ENV=production
VITE_APP_WEB_URL= 'YOUR WEB URL'
組件中使用:
console.log(import.meta.env.VITE_APP_WEB_URL)
配置 package.json:
打包區(qū)分開發(fā)環(huán)境和生產(chǎn)環(huán)境
"build:dev": "vue-tsc --noEmit && vite build --mode development",
"build:pro": "vue-tsc --noEmit && vite build --mode production",
使用組件庫 Naive UI
組件庫選擇,這里我們選擇
Naive UI至于為什么選擇它?我可以直接說尤大大推薦的嗎?
-
官方介紹: -
一個 Vue 3組件庫 -
比較完整, 主題可調(diào),使用TypeScript,不算太慢 -
有點意思
介紹還是比較謙虛的,既然尤大推薦,肯定有它的優(yōu)勢了!!!
安裝 Naive UI
# 安裝 組件庫
yarn add naive-ui
# 安裝 字體
yarn add vfonts
如何使用
import { NButton } from "naive-ui"
<n-button>naive-ui</n-button>
全局配置 Config Provider
全局化配置設(shè)置內(nèi)部組件的
主題、語言和組件卸載于其他位置的DOM的類名。
<n-config-provider :locale="zhCN" :theme="theme">
<!-- 容器 -->
</n-config-provider>
尤其是主題配置這個功能,我真的很喜歡 ??
組件庫選擇上不做任何強制,根據(jù)自己的項目需要選擇合適的組件庫即可
Vite 常用基礎(chǔ)配置
基礎(chǔ)配置
運行 代理 和 打包 配置
server: {
host: '0.0.0.0',
port: 3000,
open: true,
https: false,
proxy: {}
},
生產(chǎn)環(huán)境去除 console debugger
build:{
...
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
}
}
生產(chǎn)環(huán)境生成 .gz 文件
開啟
gzip可以極大的壓縮靜態(tài)資源,對頁面加載的速度起到了顯著的作用。
使用 vite-plugin-compression 可以 gzip 或 brotli 的方式來壓縮資源,這一步需要服務(wù)器端的配合,vite 只能幫你打包出 .gz 文件。此插件使用簡單,你甚至無需配置參數(shù),引入即可。
# 安裝
yarn add --dev vite-plugin-compression
plugins 中添加:
import viteCompression from 'vite-plugin-compression'
// gzip壓縮 生產(chǎn)環(huán)境生成 .gz 文件
viteCompression({
verbose: true,
disable: false,
threshold: 10240,
algorithm: 'gzip',
ext: '.gz',
}),
最終 vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
//@ts-ignore
import viteCompression from 'vite-plugin-compression'
// https://vitejs.dev/config/
export default defineConfig({
base: './', //打包路徑
plugins: [
vue(),
// gzip壓縮 生產(chǎn)環(huán)境生成 .gz 文件
viteCompression({
verbose: true,
disable: false,
threshold: 10240,
algorithm: 'gzip',
ext: '.gz',
}),
],
// 配置別名
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
css:{
preprocessorOptions:{
scss:{
additionalData:'@import "@/assets/style/mian.scss";'
}
}
},
//啟動服務(wù)配置
server: {
host: '0.0.0.0',
port: 8000,
open: true,
https: false,
proxy: {}
},
// 生產(chǎn)環(huán)境打包配置
//去除 console debugger
build: {
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
},
})
常用插件
可以查看官方文檔:https://vitejs.cn/plugins/
-
@vitejs/plugin-vue提供Vue 3單文件組件支持 -
@vitejs/plugin-vue-jsx提供 Vue 3JSX支持(通過 專用的 Babel 轉(zhuǎn)換插件) -
@vitejs/plugin-legacy為打包后的文件提供傳統(tǒng)瀏覽器兼容性支持 -
unplugin-vue-components組件的按需自動導入 -
vite-plugin-compression使用 gzip 或者 brotli 來壓縮資源 -
.....
非常推薦使用的 hooks 庫
因為
vue3.x和react hooks真的很像,所以就稱為hooks
VueUse:https://vueuse.org/
看到這個庫的第一眼,讓我立馬想到了 react 的 ahooks
VueUse 是一個基于 Composition API 的實用函數(shù)集合。通俗的來說,這就是一個工具函數(shù)包,它可以幫助你快速實現(xiàn)一些常見的功能,免得你自己去寫,解決重復(fù)的工作內(nèi)容。以及進行了基于 Composition API 的封裝。讓你在 vue3 中更加得心應(yīng)手。
??想要入手 vue3 的小伙伴,趕快學習起來吧!!!
??最后給大家奉上倉庫地址吧:https://github.com/xushanpei/vite_vue3_ts
寫在最后
公眾號:前端開發(fā)愛好者專注分享web前端相關(guān)技術(shù)文章、視頻教程資源、熱點資訊等,如果喜歡我的分享,給 ???? 點一個贊?? 或者 ?關(guān)注都是對我最大的支持。
請你喝杯?? 記得三連哦~
1.閱讀完記得給?? 醬點個贊哦,有?? 有動力
2.關(guān)注公眾號前端那些趣事,陪你聊聊前端的趣事
3.文章收錄在Github frontendThings 感謝Star?
