一、Vue3
1 基礎配置
1.1 @
路徑別名
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'// 引入path,node提供的模塊,可以獲取文件或文件夾的路徑
import path from 'path'export default defineConfig({plugins: [vue()],resolve: {alias: {'@': path.resolve('./src')}}
})
tsconfig.json
{"compilerOptions": {// 配置路徑別名"baseUrl": "./","paths": {"@/*": ["src/*"]}}
}
1.2 SCSS
全局變量
vite.config.ts
export default defineConfig({// scss全局變量一個配置css: {preprocessorOptions: {scss: {javascriptEnabled: true,additionalData: '@import "./src/styles/variable.scss";',},},},
})
1.3 SVG
使用方式
vite.config.ts
// 配置svg:引入插件
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'export default defineConfig({plugins: [createSvgIconsPlugin({// 配置svg:指定svg資源目錄iconDirs: [path.resolve(process.cwd(), 'src/asstes/icons')],// 配置svg:指定svg資源namesymbolId: 'icon-[dir]-[name]'})]
}
main.ts
// svg插件需要配置代碼
import 'virtual:svg-icons-register'
使用
<svg style="width:30px; height:30px"><use xlink:href="#icon-xxx" fill="red"></use>
</svg>
1.4 SVG
全局組件
<svg-icon name="home" color="pihk"></svg-icon>
<!-- @/components/SvgIcon/index.vue --><template><svg :style="{width, height}"><use :xlink:href="prefix + name"></use></svg>
</template><script setup>
import { ref } from 'vue';
const prefix = ref('#icon-')
defineProps({// 名字name: String,// 顏色color:{type: String,defaule: ''},// 寬高width: {type: String,default: '20px'},height: {type: String,default: '20px'}
})
</script>
-
1、單獨引入注冊
main.ts
import SvgIcon from '@/components/SvgIcon/index.vue' app.components('SvgIcon', SvgIcon)
-
2、插件注冊,引入
components
下組件遍歷注冊@/components/index.ts
import SvgIcon from './SvgIcon/index.vue'const allGloablComponent = { SvgIcon } export default{install(app){Object.keys(allGloablComponent).forEach(key => {app.component(key, allGloablComponent[key])})} }
main.ts
//引入自定義插件對象:注冊整個項目全局組件 import gloalComponent from '@/components' //安裝自定義插件 app.use(gloalComponent)
1.5 EL
全局圖標
@/components/index.ts
// 引入全部elmentPlus的圖標
import * as ElementPlusIconsVue from '@element-plus/icons-vue'const allGloablComponent = { SvgIcon }
export default{install(app){// 將element-plus的圖標全部注冊for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)}}
}
main.ts
// 引入自定義插件對象:注冊整個項目全局組件
import gloalComponent from '@/components'
// 安裝自定義插件
app.use(gloalComponent)
使用方式
<el-icon> </Edit> </el-icon><el-icon> <component is="Edit"> </el-icon>
2 vue-router路由
2.1 路由跳轉
-
編程式導航
<script setup lang="ts">import { useRouter } from 'vue-router';const $router = useRouter()const toRoutes = (path) => {$router.push(path)} </script>
2.2 路由過度
<template><router-view v-slot="{ Component }"><transition name="fade"><component :is="Component" /></transition></router-view>
</template><script setup lang="ts"> </script><style lang="scss" scoped>
// 此為vue3寫法,與vue2類名略有不同,根據需求自定義過渡動畫
.fade-enter-from {opacity: 0;transform: scale(0);
}.fade-enter-active {transition: all .3s;
}.fade-enter-to {opacity: 1;transform: scale(1);
}
</style>
2.3 路由鑒權
項目當中的各個路由在什么條件下可以訪問,什么條件下不可以訪問
2.3 element-plus
組件
2.3.1 Menu
菜單折疊圖標
問題:在使用 el-menu
菜單的折疊功能時,因為自定義路由和Menu組件,導致圖標沒有正常顯示
解決:將圖標組件移出 template
外邊
<el-menu-item ><template #title><el-icon> <component :is="meta.icon"></component> </el-icon><span>{{item.children[0].meta.title}}</span></template>
</el-menu-item>
<el-menu-item ><el-icon> <component :is="item.meta.icon"></component> </el-icon><template #title><span>{{item.meta.title}}</span></template>
</el-menu-item>
2.3.2 Menu刷新默認菜單
問題:使用 el-menu
菜單在頁面刷新時,已展開的菜單會關閉,
解決:配置 el-menu
的 default-active
屬性,通過 router
將頁面路徑賦值給他
備注: route
獲取頁面路徑, router
頁面跳轉,現 $route
以改為宏函數,可以直接在 template
使用,無需引入,若想在 script
中使用,還是得引入
<el-menu :default-active="$route.path"></el-menu>import { useRoute } from 'vue-router'
$route = useRoute()
3 父子組件交互
3.1 defineEmits
vue3
內置 defineEmits
和 definProps
可無需引入直接使用
// son.vue
let $emit = defineEmits(['fn1', 'fn2', ...])const updata = () => {$emit('fn1', { name: '張三', age: '23' })
}// father.vue
<son @fn1="fn1"></son>const fn1 = (name='', age='') => { ... }
3.2 definProps
// father.vue
<son :name="name" :data="data"></son>// son.vue
let props = defineProps({name: {type: String,default: ''},data:{type:Object,default:() => ({ ... })}
})// 或defineProps({name:{type:String,default:''},data:{type:Object,default:() => ({ ... })}
})
3.3 ref
// father.vue
<son ref="son"/>let son = ref(null)
const fn = () => {son.value.fnSon
}// son.vue
const fnSon = () => {// ...
}
defineExpose({ fnSon })
二、TypeScript
1 類型定義
-
@/api/user/index.js
import request from '@/utils/request'import type {loginFormData,loginResponseData,userInfoReponseData, } from './type'enum API {// 登錄LOGIN_URL = '/admin/acl/index/login',// 用戶信息USERINFO_URL = '/admin/acl/index/info',// 退出登錄LOGOUT_URL = '/admin/acl/index/logout', }// 登錄接口 export const reqLogin = (data: loginFormData) => request.post<any, loginResponseData>(API.LOGIN_URL, data)// 獲取用戶信息 export const reqUserInfo = () =>request.get<any, userInfoReponseData>(API.USERINFO_URL)// 退出登錄 export const reqLogout = () => request.post<any, any>(API.LOGOUT_URL)
-
@/api/user/type.ts
// 請求攜帶參數類型 export interface loginFormData {username: string,password: string }// 基礎接口返回數據類型 export interface Response {code: number|string,message?: string,ok?: boolean }// 登錄接口 返回數據類型 export interface loginResponseData extends Response {data: string }// 用戶信息接口 返回數據類型 export interface userInfoReponseData extends Response {data: {routes: string[]buttons: string[]roles: string[]name: stringavatar: string} }
三、JavaScrpt
1 對象數組過濾對象
let objectsArray = [ { a: 1, b: 'one' }, { a: 2, b: 'two' }, { a: 3, b: 'three' }, { a: 2, b: 'anotherTwo' }
]; let valueToRemove = 2; // 這是你想從對象中過濾掉的屬性 a 的值 objectsArray = objectsArray.filter(obj => obj.a !== valueToRemove); console.log(objectsArray);
// 輸出: [ { a: 1, b: 'one' }, { a: 3, b: 'three' } ]
2 對象數組的對象的屬性名修改
imgList = res.data.map(item => {return{name: item.imgName,url: item.imgUrl}
})
3 Object.assign
Object.assign()
將所有可枚舉的屬性的值從一個或多個源對象復制到目標對象(第一個參數),具有相同屬性的話,會按順序進行覆蓋,并返回目標對象
let a = reactive({ x: 1, y: 2 })let b = { y: 3, z: 4 }let c = { z: 3 }let newA = Object.assign(a, b, c) console.log(a, a===newA) // { x: 1, y: 3, z: 3 } true// 在vue3中,如使用解構賦值的方法,會產生新的對象,會導致失去數據代理
a = {...a, ...b, ...c}
4 request.ts
@/utils/request.ts
import axios from 'axios'
import { ElMessage } from 'element-plus'
//引入用戶相關的倉庫
import useUserStore from '@/store/modules/user'const request = axios.create({//基礎路徑(在項目根目錄下設置)baseURL: import.meta.env.VITE_APP_BASE_API,//超時的時間的設置timeout: 5000,
})// 請求攔截器
request.interceptors.request.use((config) => {if(useUserStore().token){config.headers.token = useUserStore().token}return config
})// 響應攔截器
request.interceptors.response.use((response) => {// 成功回調,簡化數據return response.data},(error) => {// 失敗回調:處理http網絡錯誤let message = ''// http狀態碼const status = error.response.statusswitch (status) {case 401:message = 'TOKEN過期'breakcase 403:message = '無權訪問'breakcase 404:message = '請求地址錯誤'breakcase 500:message = '服務器出現問題'breakdefault:message = '網絡出現問題'break}//提示錯誤信息ElMessage({type: 'error',message,})return Promise.reject(error)},
)export default request
四、業務實現
-
左側菜單縮放通過倉庫變量(true/false)進行管理
-
刷新:通過
v-if
、nextTick
、倉庫
實現刷新(銷毀重建) -
全屏狀態:通過
document.fullscreenElement
設置全屏狀態 -
自動刷新:
window.location.reload()
,用戶修改自身賬號或密碼之后,調用方法自動刷新 -
展示角色權限:例,后端返回全部權限,其中該角色擁有的權限的
select:true
,修改時需要把新的權限對象給后端(父級的id和權限值 + 子級的id和權限值 + …),<el-tree>
提供獲取選中的節點的數組,修改完調用刷新方法一級 二級 三級 四級 1、全部數據 1.1、權限管理 1.1.1、用戶管理 1.1.1.1、添加用戶 1.1.1.2、刪除用戶 1.1.1.3、修改用戶 1.1.2、菜單管理 1.2、商品管理 {"id": 1,"name": "全部數據","level": 1,"children": [{"id": 7,"name": "權限管理","level": 2,"children": [{"id": 8,"name": "用戶管理","level": 3,"children": [{"id": 11,"name": "添加用戶","level": 4,"children": [],"select": false},{"id": 12,"name": "刪除用戶","level": 4,"children": [],"select": false}],"select": false},{"id": 10,"name": "菜單管理","level": 3,"children": [],"select": false}],"select": false}],"select": true }
const setPermisstion = async (id) => {let result = await reqAllMenuList(id);if (result.code == 200) {// 全部權限menuArr.value = result.data;// 擁有的權限selectArr.value = filterSelectArr(menuArr.value, []);} }const filterSelectArr = (allData, initArr) => {allData.forEach((item) => {// 如最后一級的權限的是第四級(遍歷完其最低級的權限,即可通過<el-tree>自動判斷)if (item.select && item.level == 4) {initArr.push(item.id);}if (item.children && item.children.length > 0) {filterSelectArr(item.children, initArr);}})return initArr; }
五、備注
-
在平時寫代碼的時候,為實現某個功能,感覺自己寫的代碼很冗余,可以試試將代碼交于
ai
,讓其優化一下,說不定JS官方
已經提供了便捷語法糖(如:ES6+新增的語法糖),或者AI
有更加便捷的實現思路 -
背景圖片
.contaiter{background: url('@/xxx/xxx.jpg') no-repeat;backgorund-size: cover; }