大家好距贷,我是蘇先生,一名熱愛鉆研吻谋、樂于分享的前端工程師忠蝗,跟大家分享一句我很喜歡的話:人活著,其實(shí)就是一種心態(tài)漓拾,你若覺得快樂什湘,幸福便無處不在
你可以學(xué)到什么长赞?
- 如何使用 vite 搭建項(xiàng)目
- 如何集成與使用 web-localstorage-plus
- 如何集成與使用 vue-router4
- 如何集成與使用 pinia
- 如何集成與使用 element-plus
- 如何封裝axios
- 如何借力 eslint 和 prettier 保證代碼質(zhì)量
- 如何借力 commitlint 規(guī)范git提交信息
源碼地址
1.創(chuàng)建項(xiàng)目
按提示選擇:
1.運(yùn)行vite
yarn create vite
2.輸入自定義的項(xiàng)目名稱
name: ? your-project-name
3.選擇你想要的技術(shù)框架
? Select a framework: ? - Use arrow-keys. Return to submit.
? Vanilla
Vue
React
Preact
Lit
Svelte
Others
4.選擇ts模板
? Select a variant: ? - Use arrow-keys. Return to submit.
? TypeScript
JavaScript
Customize with create-vue ↗
Nuxt ↗
5.按提示安裝并運(yùn)行項(xiàng)目
Done. Now run:
cd vite-project
yarn
yarn dev
一鍵初始化
除了上述問答形式創(chuàng)建外,vite官方也提供了快捷語法:通過命令行參數(shù)創(chuàng)建
# npm 6.x
npm create vite@latest my-vue-app --template vue
# npm 7+, extra double-dash is needed:
npm create vite@latest my-vue-app -- --template vue
# yarn
yarn create vite my-vue-app --template vue
# pnpm
pnpm create vite my-vue-app --template vue
2.優(yōu)化項(xiàng)目結(jié)構(gòu)
修剪vite默認(rèn)生成的項(xiàng)目結(jié)構(gòu)
1.保留public文件夾闽撤,刪除vite.svg文件得哆,同時刪除index.html
中對該文件的引入
2.刪除HelloWorld.vue
文件,同時從App.vue
中刪除引入
3.刪除App.vue
中的默認(rèn)代碼哟旗,只保留默認(rèn)的三個根元素
我個人習(xí)慣將template
放到最前邊
<template>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>
4.清空assets文件夾
定制化目錄
1.創(chuàng)建store文件夾
放置關(guān)于pinia的數(shù)據(jù)狀態(tài)
2.創(chuàng)建directive文件夾
放置我們的自定義指令贩据,如:v-auth
3.創(chuàng)建utils文件夾
項(xiàng)目中的公共方法或常量
4.創(chuàng)建styles文件夾
管理公共css樣式文件,如:reset.css
5.創(chuàng)建http文件夾
處理axios的封裝和調(diào)用
6.創(chuàng)建router文件夾
管理
vue-router
的路由模塊
7.創(chuàng)建pages文件夾
管理業(yè)務(wù)代碼
3.配置vite.config.ts
配置別名
項(xiàng)目中闸餐,不同模塊之間往往需要互相引入饱亮,使用別名能夠幫助我們省去一級一級查找的繁瑣
...
import { resolve } from 'node:path'
export default defineConfig({
plugins: [vue()],
resolve:{
alias:{
'@':resolve(__dirname,'src')
}
}
})
此時,node:path
和__dirname
會報(bào)錯舍沙,我們還需要安裝下對應(yīng)的ts類型包
yarn add @types/node --D
設(shè)置代理
我們本地開發(fā)完跟后端聯(lián)調(diào)階段近上,經(jīng)常會遇到跨域的問題,需要我們暫時的在前端進(jìn)行下處理
export default defineConfig({
...
server: {
proxy: {
"/api": {
target: "http url",
changeOrigin: true,
rewrite: (path: string) => path.replace(/^\/api/, ""),
},
},
},
});
其中"/api"
是我們要代理的接口標(biāo)識拂铡,target是我們實(shí)際要訪問的接口地址
設(shè)置自動導(dǎo)入
每次都手動導(dǎo)入依賴項(xiàng)是一件很麻煩的事情壹无,幸運(yùn)的是,我們可以借助第三方庫來幫我們實(shí)現(xiàn)感帅,它內(nèi)置了常見的庫斗锭,比如vue
1.安裝
yarn add unplugin-auto-import -D
2.在vite.config.ts中導(dǎo)入并作為plugin使用
...
import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig({
plugins: [...,AutoImport()],
...
});
4.集成web-storage-plus
對于需要使用到持久緩存的地方,localstorage
是優(yōu)選的方案失球,不過原生接口比較難用岖是,而該npm包對其進(jìn)行了二次封裝,使其支持了命名空間实苞、過期時間豺撑、監(jiān)聽變化、批量操作等特性黔牵,且其為我們提供了發(fā)布訂閱模式來彌補(bǔ)vue3中對bus的缺失前硫,文檔看這里:傳送門
1.安裝
yarn add web-localstorage-plus
2.在main.ts中引入并初始化根存儲
...
import createStorage from 'web-localstorage-plus'
createStorage({
rootName:'spp-storage'
})
...
3.在.vue文件中引入并使用
<script lang="ts" setup>
import { useStorage } from 'web-localstorage-plus'
const storage = useStorage()
storage.setItem('user',{
name:'spp',
age:28
})
</script>
5.集成pinia
對于非持久化數(shù)據(jù),我們選擇使用pinia來進(jìn)行管理荧止,它幫我們托管了全局狀態(tài)并且提供了響應(yīng)式能力,文檔看這里:傳送門
1.安裝pinia
yarn add pinia
2.在store文件夾下新建index.ts文件作為pinia的根倉庫文件
import { createPinia } from "pinia";
const pinia = createPinia()
export default pinia
3.在main.ts中導(dǎo)入并將 pinia 作為 plugin 注冊給 vue
import { createApp } from 'vue'
...
import pinia from '@/store'
...
const app = createApp(App)
app.use(pinia)
...
4.在store文件夾下新建xxx.ts文件作為子存儲模塊
import { defineStore } from 'pinia'
export default defineStore('spp', {
state() {
return {
spp:''
}
},
actions:{
updateSpp(spp:string){
this.spp = spp
}
}
})
5.在.vue文件中使用或修改pinia的狀態(tài)
<script lang="ts" setup>
...
import useLoginStore from '@/store/login.ts'
// 獲取狀態(tài)
const store = useLoginStore()
// 修改狀態(tài)
store.updateSpp('spp')
...
</script>
6.集成vue-router4
作為spa項(xiàng)目阶剑,路由是我們進(jìn)行頁面切換的必備工具跃巡,文檔看這里:傳送門
1.使用yarn安裝
yarn add vue-router@4
2.在router文件夾下新建index.ts文件作為根路由
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
const routes: Array<RouteRecordRaw> = [
{
path: "/login",
name: "Login",
component: () => import("@/pages/login/index.vue")
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
3.在main.ts中導(dǎo)入并作為plugin注冊給vue
import { createApp } from 'vue'
import router from '@/router';
...
const app = createApp(App)
app.use(router)
...
4.將根App.vue作為路由出口
<template>
<RouterView/>
</template>
7.集成less
1.安裝
yarn add less -D
2.使用
<style lang="less" scoped>
.root-app {
.spp {
// 自定義樣式
}
}
</style>
8.集成element-plus
element-plus是vue側(cè)比較流行的pc端ui框架之一,文檔看這里:傳送門
1.安裝
yarn add element-plus
2.按需自動導(dǎo)入
- 安裝依賴包
yarn add unplugin-vue-components unplugin-auto-import -D
- 修改vite.config.ts
import { defineConfig } from "vite";
...
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
export default defineConfig({
plugins: [
...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
...
});
3.在.vue文件夾下直接使用即可
9.集成axios(僅提供封裝思路牧愁,可選)
axios是目前最流行的前端發(fā)起ajax請求的庫素邪,其基于promise實(shí)現(xiàn),同時支持在瀏覽器和nodejs中使用猪半,文檔看這里:傳送門
1.安裝
yarn add axios
2.在http文件夾下新建index.ts文件
該文件對我們業(yè)務(wù)中的請求進(jìn)行基類封裝
import request from "./request";
import getPrefix from "./urlPrefix";
import { TgroupType } from '@/utils/types'
import { warn } from '@/utils/function'
class Http{
protected prefix:string=getPrefix(undefined);
protected config:any={}
constructor(group?:TgroupType){
this.prefix = getPrefix(group)
}
private combineUrl(url:string){
return this.prefix + url
}
setExtraConfig(config:any){
this.config = config
}
get<T>(url: string, arg?: T,message?:string){
return new Promise((resolve, reject) => {
request
.get(this.combineUrl(url), {
params: arg,
...this.config
})
.then((res:any)=>{
// 根據(jù)與后端的約定format數(shù)據(jù)兔朦,并做resolve或reject
...
})
.catch(reject)
.finally(()=>{
this.config={}
})
});
}
post<T>(url: string, message?: string | T, arg?: T) {
const isFull = arguments.length === 3
if (!isFull) {
arg = message as T;
}
const errMessage = '你的自定義錯誤'
return new Promise((resolve, reject) => {
request
.post(this.combineUrl(url), arg,{
...this.config,
})
.then((res: any) => {
// 根據(jù)與后端的約定format數(shù)據(jù)偷线,并做resolve或reject
...
})
.catch(()=>{
warn(errMessage)
reject(errMessage);
})
.finally(()=>{
this.config={}
})
});
}
}
export const http = new Http()
export const httpRequest = Http
export const usePrefix = getPrefix
3.在http文件夾下新建request.ts文件
該文件用于配置axios,并通過攔截器對接口狀態(tài)進(jìn)行檢測和錯誤的統(tǒng)一處理
import axios from "axios";
axios.defaults.timeout = 10000000;
axios.defaults.withCredentials = true;
axios.interceptors.request.use(
(config) => {
config.headers = Object.assign(config.headers,{
// 配置header
})
return config;
},
(error) => {
// 處理錯誤
return Promise.reject(error);
}
);
axios.interceptors.response.use(
(response) => {
// 統(tǒng)一攔截驗(yàn)證
return response;
},
(error) => {
// 處理錯誤
return Promise.reject(error);
}
);
export default axios;
4.在http文件夾下新建urlPrefix.ts文件
該文件用于統(tǒng)一管理不同域名對應(yīng)的不同環(huán)境下的url
import { IurlConfig,TgroupType} from '@/utils/types'
const mode = import.meta.env.MODE;
const urlConfig:IurlConfig = {
// 前綴-{dev:'',pro:''}
}
const getPrefix = (key:TgroupType)=>{
if(key === undefined){
key = ''
urlConfig[key][mode]
}
return urlConfig[key][mode]
}
export default getPrefix;
5.在業(yè)務(wù)中引入并使用
import { http } from "@/http";
http
.post<傳遞與當(dāng)前接口參數(shù)匹配的類型>(url, "添加成功", params)
.then(() => {
// 請求成功的業(yè)務(wù)處理
});
10.常用工具推薦
- 時間處理:moment
- 萬能工具庫:lodash-es
11.代碼質(zhì)量與提交規(guī)范
eslint
因?yàn)閑slint無法識別.vue文件沽甥,因此我們還需要一個定制化插件:eslint-plugin-vue
声邦,文檔看這里:傳送門
1.安裝依賴
yarn add eslint eslint-plugin-vue -D
2.創(chuàng)建.eslintignore忽略文件
node_modules
dist
yarn.lock
index.html
3.添加ts支持
eslint-plugin-vue
只針對.vue文件或者.js文件中的vue寫法,我們還需要對ts進(jìn)行兼容
文檔傳送門:@typescript-eslint/parser摆舟、@typescript-eslint/eslint-plugin
yarn add @typescript-eslint/parser @typescript-eslint/eslint-plugin -D
4.在根目錄下創(chuàng)建.eslintrc.cjs配置文件
module.exports = {
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2020,
sourceType: 'module',
ecmaFeatures: {
jsx: true
}
},
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
],
rules: {
"no-console": "error",
}
};
5.按環(huán)境區(qū)分
實(shí)際項(xiàng)目中亥曹,我們一般會根據(jù)不同的開發(fā)環(huán)境來區(qū)分規(guī)則,比如console應(yīng)在開發(fā)階段可用恨诱,生產(chǎn)時禁用
1-安裝依賴
文檔看這里:cross-env媳瞪、@rollup/plugin-eslint
yarn add cross-env @rollup/plugin-eslint -D
2-修改命令行
在打包階段配置環(huán)境變量,我這里以production為例子
"scripts": {
...
"build": "cross-env NODE_ENV=production && vue-tsc --noEmit && vite build"
},
3-將rollup插件加入vite的plugin
...
import eslint from '@rollup/plugin-eslint';
export default defineConfig({
plugins: [
...
eslint({
include:['src/**']
})
],
...
});
4-修改.eslintrc.cjs
cross-env
會將定義的環(huán)境變量暴露在env上照宝,我們獲取并做三元判斷即可
const mode = process.env.NODE_ENV
module.exports = {
...
rules: {
"no-console": mode === 'production' ? "error" : "off",
...
}
};
prettier
相關(guān)文檔看這里:prettier蛇受、eslint-config-prettier、eslint-plugin-prettier
1.安裝依賴
yarn add prettier eslint-config-prettier eslint-plugin-prettier -D
2.創(chuàng)建配置文件:.prettierrc.js
以我司的某個項(xiàng)目為例
module.exports = {
// 一行最多 150 個字符
printWidth: 150,
// 使用 4 個空格縮進(jìn)
tabWidth: 4,
// 不使用 tab 縮進(jìn)厕鹃,而使用空格
useTabs: false,
// 行尾需要有分號
semi: true,
// 使用單引號代替雙引號
singleQuote: true,
// 末尾使用逗號
trailingComma: 'es5',
// 箭頭函數(shù)兢仰,只有一個參數(shù)的時候,也需要括號
arrowParens: 'always',
}
3.修改 .eslintrc.js
配置
強(qiáng)制當(dāng)和eslint沖突時熊响,以prettier為準(zhǔn)
module.exports = {
...
extends: [
...
'prettier',
'plugin:prettier/recommended'
],
...
};
提交規(guī)范
我們需要在提交代碼前對代碼質(zhì)量旨别、代碼格式和commit信息進(jìn)行約束,為此汗茄,我們需要先注冊commit提交前鉤子
1-安裝husky
文檔看這里:傳送門
yarn add husky -D
2-初始化husky
在package.json文件夾下新增prepare
腳本秸弛,并立即運(yùn)行一次
"scripts": {
...
"prepare": "husky install"
},
3-注冊hook
我們使用pre-commit
鉤子來攔截提交行為,
npx husky add .husky/pre-commit "npm run check"
git add .husky/pre-commit
此時洪碳,當(dāng)git commit
發(fā)生時递览,將會調(diào)用check
腳本,但這默認(rèn)事針對全部文件的瞳腌,因此我們需要借助另一個npm包幫我們把當(dāng)前更改的文件提取出來單獨(dú)校驗(yàn)
1-安裝lint-staged
文檔看這里:傳送門
yarn add lint-staged -D
2-修改package.json配置
"lint-staged": {
"*.{js,ts,vue}": [
"npm run eslint",
"prettier --parser=typescript --write"
]
}
3-與husky關(guān)聯(lián)
將lint-staged作為check的指向腳本
"scripts": {
...
"check": "lint-staged"
},
最后我們來對commit提交格式進(jìn)行約束绞铃,這可以通過commitlint來幫我們完成,文檔看這里:傳送門
1-安裝
yarn add @commitlint/config-conventional @commitlint/cli -D
2-將其校驗(yàn)位置放在check
腳本執(zhí)行前
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'
3-創(chuàng)建配置文件commitlint.config.cjs
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'feature', // 迭代功能
'conf', // 修改構(gòu)建配置
'fixbug', // 修復(fù)bug
'refactor', // 代碼重構(gòu)
'optimize', // 代碼優(yōu)化
'style', // 僅修改樣式文件
'docs', // 文檔補(bǔ)充說明
],
],
'header-max-length': [0, 'always', 72], //限制最長72
},
};
4-測試使用
如果本文對您有用嫂侍,希望能得到您的點(diǎn)贊和收藏