前段時間使用vue-element-admin做了一個簡單的讀書管理后臺做葵,現(xiàn)整理遇到的各類問題捞奕。
使用 vue-element-admin 初始化項目,而不是vue-admin-template
原因在于:vue-element-admin 實現(xiàn)了登錄模塊忘巧,包括 token 校驗玄捕、網(wǎng)絡請求等
-
下載
從github上clone項目時,防火墻禁止對git://的訪問不瓶,
可用https://來訪問repository禾嫉。
git config --global url."https://".insteadOf git://
-
項目結構
api:接口請求
assets:靜態(tài)資源
components:通用組件
directive:自定義指令
filters:自定義過濾器
icons:圖標組件
layout:布局組件
router:路由配置
store:狀態(tài)管理
styles:自定義樣式
utils:通用工具方法
auth.js:token 存取
permission.js:權限檢查
request.js:axios 請求封裝
index.js:工具方法
views:頁面
permission.js:登錄認證和路由跳轉
settings.js:全局配置
main.js:全局入口文件
App.vue:全局入口組件
-
調(diào)試
為方便進行源碼調(diào)試,可將 vue.config.js 中的 cheap-source-map 改為 source-map
這樣調(diào)試時可看見源碼湃番,而不是編譯后的代碼夭织。
souce-map缺點:每次改動文件吭露,會同步生成新的map文件吠撮,導致構建速度變慢。
故開發(fā)時,保持 eval 配置以增加構建速度泥兰,config.devtool('eval') 弄屡,
需要源碼調(diào)試排查問題時,改為 source-map
config
.when(process.env.NODE_ENV === 'development',
config => config.devtool('cheap-source-map')
)
-
一些代碼
1. 路由相關
vue-element-admin 將路由分成兩種:
constantRoutes 固定路由
asyncRoutes 根據(jù)用戶角色判定添加
export const asyncRoutes = [
{
path: '/book',
component: Layout,
redirect: '/book/create',
//redirect 重定向鞋诗,當訪問 /book 時膀捷, 會被重定向到 /book/create
children: [
{
path: '/book/create',
component: () => import('@/views/book/create'),
name: 'book',
meta: { title: '添加圖書', icon: 'edit', roles: ['admin'] }
//使用 admin 登錄,才可以看到"添加圖書"功能
}
]
},
// ...
]
重定向:
未獲取 Token時削彬,訪問 /login 以外且不在白名單的路由全庸,如:
訪問 /dashboard,實際訪問路徑為 /login?redirect=%2Fdashboard融痛,登錄后會直接重定向 /dashboard
重定向時壶笼,參數(shù)獲取:
const query = {
redirect: '/book/list',
name: 'yuki',
id: '1234'
}
const _query = Object.keys(query).reduce((acc, cur) => {
if (cur !== 'redirect') {
acc[cur] = query[cur]
}
return acc
}, {})
console.log(query, _query)
2. 登錄相關
user/login 方法調(diào)用了 login API雁刷,傳入 username 和 password 參數(shù)覆劈,請求成功后會從 response 中獲取 token,然后將 token 保存到 Cookie 中沛励,之后返回责语。
如果請求失敗,將調(diào)用 reject 方法目派,交由我們自定義的 request 模塊來處理異常
login({ commit }, userInfo) {
const { username, password } = userInfo
return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password }).then(response => {
const { data } = response
commit('SET_TOKEN', data.token)
setToken(data.token)
resolve()
}).catch(error => {
reject(error)
})
})
}
3. 圖書列表相關
<!--使用v-slot-->
<el-table-column
label="書名"
align="center"
width="150"
>
<template v-slot="{ row: { title } }">
<!--解構賦值坤候,拿出 row 里面的 title,一個row就是一條數(shù)據(jù)(數(shù)組的一項)-->
<span>{{ title }}</span>
</template>
</el-table-column>
<!--使用prop-->
<el-table-column
label="書名"
prop="title"
align="center"
width="150"
/>
關鍵字高亮:
wrapperKeyword(key, value) {
function highlight(value) {
return `<span style="color: #1890ff">${value}</span>`
}
if (!this.listQuery[key]) { // 判斷查詢參數(shù)是否存在 title author
return value
} else {
return value.replace(new RegExp(this.listQuery[key], 'ig'), value => highlight(value))
}
},
同一路由址貌,查詢參數(shù)不同:
beforeRouteUpdate(to, from, next) {
if (to.path === from.path) { // 跳轉到同一個路由
const newQuery = {...to.query}
const oldQuery = {...from.query}
if (JSON.stringify(newQuery) !== JSON.stringify(oldQuery)) { // 如果查詢參數(shù)不同
this.getList() // 重新發(fā)送請求獲取列表
}
}
next() // 調(diào)用next(),否則一直顯示加載中狀態(tài)
}
4.接口相關
vue-element-admin使用了mock接口铐拐,我改用自己開發(fā)的接口,關閉mock
修改 .env.development 和 .env.production 兩個配置文件:
VUE_APP_BASE_API = '/dev-api' 修改為實際接口地址