本文是在學習antd-pro-vue開箱即用的中臺前端/設計解決方案的源碼後,寫的筆記。javascript
這是他們的官方文檔ANTD PRO VUEcss
vue create ant-design-vue-pro
這裏須要用到vue-cli腳手架 必須先在全局安裝vue-cli Vue-cli的官網:Vue Clihtml
選擇第二個,自定義配置 前端
npm i ant-design-vue -D -S
vue
npm install babel-plugin-import --dev
修改babel.config.js
文件,配置babel-plugin-import
java
module.exports = {
presets: ["@vue/app"],
+ plugins: [
+ [
+ "import",
+ { libraryName: "ant-design-vue", libraryDirectory: "es", style: true }
+ ]
+ ]
};
複製代碼
詳細內容能夠看antd of vuenode
修改vue.config.js
文件,若是沒有該文件,則新建一個ios
module.exports = {
css: {
loaderOptions:{
less:{
javascriptEnabled:true,
}
}
}
}
複製代碼
在刪除大部分不須要的內容後,如今目錄以下:vue-router
core
core
文件夾下新建lazy_lib
文件夾lazy_lib
文件夾下新建components_use.js
//component_use.js
import Vue from 'vue'
import {
//引入你須要加載的組件
Button,
Icon,
Switch,
notification,
} from 'ant-design-vue'
Vue.use(Button)
Vue.use(Icon)
Vue.use(Switch)
Vue.use(notification)
Vue.prototype.$notification = notification // 在vue 單文件中能夠直接 this.$notification去調用
複製代碼
main.js
中導入該文件import "@/core/lazy_lib/components_use.js"
vuex
src
文件夾下新建layouts
文件夾layouts
文件夾下各類佈局文件,如BasicLayout.vue
關於頁面佈局,詳細信息能夠看layout
src
文件夾下新建config
文件夾,用來設置各類配置config
文件夾下新建router.config.js
// router.config.js
//導入各類基本頁面佈局
import {UserLayout,BasicLayout,RouteView,BlankLayout,PageView} from "@/layouts"
複製代碼
// 基本路由配置
export const constantRouterMap = [
{
path:'/user',
component:UserLayout,
redirect:'/user/login',重定向到登錄頁
children:[
{
path:'login',
name:'Login',
component:() => import('@views/user/login')
}
]
},
...
{
path:'/404',
component:()=>import('@views/exceptions/404')
}
]
// 詳情頁面的路由
export const asyncRouterMap = [
...
]
複製代碼
src
文件夾下新建一個router
文件夾,在改文件夾下新建index.js
//index.js
import Vue from 'vue'
import Router from 'vue-router'
const{ constantRouterMap,asyncRouterMap} from '@/config/router.config'
Vue.use(Router)
export default new Router({
mode:'history',
routes:constantRouterMap.concat(asyncRouterMap)
})
複製代碼
main.js
中導入...
import router from './router'
...
new Vue({
router,
render:h => h(App),
}).$mount('#app')
複製代碼
npm i axios
安裝axios
關於axios
的詳細信息,請看其官方文檔axios中文網
axios的響應格式以下:
{
// `data` 由服務器提供的響應
data: {},
// `status` 來自服務器響應的 HTTP 狀態碼
status: 200,
// `statusText` 來自服務器響應的 HTTP 狀態信息
statusText: 'OK',
// `headers` 服務器響應的頭
headers: {},
// `config` 是爲請求提供的配置信息
config: {},
// 'request'
// `request` is the request that generated this response
// It is the last ClientRequest instance in node.js (in redirects)
// and an XMLHttpRequest instance the browser
request: {}
}
複製代碼
由於axios將服務端響應的信息包裹了一層,因此咱們通常會去寫一個響應攔截器,提取服務端真正返回的信息
// 添加響應攔截器
axios.interceptors.response.use(function (response) {
// 對響應數據作點什麼
return response.data;//response.data是服務端真正返回的信息
}, function (error) {
// 對響應錯誤作點什麼
return Promise.reject(error);
});
複製代碼
給每次網絡請求的請求頭加上token
// 是否要添加請求頭
service.interceptors.request.use(config => {
const token = Vue.ls.get(ACCESS_TOKEN)
if(token){
config.headers['Access-Token'] = token //讓每一個請求自帶token
}
return config
},(err)=>{
//對請求錯誤作些什麼
})
複製代碼
在src
目錄下新建utils
文件夾,在utils
文件夾下新建request.js
import Vue from 'vue'
import axios from 'axios'
import store from '@/store'
import notification from 'ant-design-vue/es/notification'
import {ACCESS_TOKEN} from '@/store/mutation-types'
//建立axios實例
const service = axios.create({
baseURL:process.env.VUE_APP_API_BASE_URL,//能夠不寫
timeout:6000,//請求超時時間
})
// 建立一個函數用來處理網絡請求的錯誤
const err = (error) => {
if(error.response){
const data = error.response.data
const token = Vue.ls.get(ACCESS_TOKEN)
if(error.response.status === 403){
notification.error({
message:"權限限制",
description:data.message
})
}
if(error.response.status ==... ){
... 寫上大家所須要的業務邏輯
}
}
// 業務邏輯處理完後,依然返回所有的錯誤信息
return Promise.reject(error)
}
// 是否要添加請求頭
service.interceptors.request.use(config => {
const token = Vue.ls.get(ACCESS_TOKEN)
if(token){
config.headers['Access-Token'] = token //讓每一個請求自帶token
}
return config
},err)
// 由於axios會將服務段返回的信息嵌套一層,因此咱們能夠
// 將服務端真正返回的信息返回
service.interceptiors.response.use((response)=>{
return response.data,
},err)
export {
service as axios
}
複製代碼
關於axios
攔截器對知識,詳細內容能夠看官方文檔攔截器
在src
文件夾下新建一個api
文件夾,在該文件夾下新建三個js文件,以下:
--index.js
--login.js
--manage.js
複製代碼
index.js主要用於存放各類api
const prefix = "http://baidu.com"//根地址
const userPrefix = prefix + "/user"
const devicePrefix = prefix + "/deivce"
const apiUserLogin = userPrefix + '/login'
const apiDeviceAdd = devicePrefix + "/add"
//將全部api存放於一個對象內,導出該對象
const api = {
userPrefix,
devicePrefix,
apiUserLogin,
apiDeviceAdd
}
export default api
複製代碼
login.js存放用戶註冊、登錄、修改密碼、退出等網絡請求
import api from './index'
import {axios} from '@/utils/request'
// 用戶登錄
export function login (parameter) {
return axios({
url:api.apiUserLogin,
method:'post',
data:{
phone:parameter.phone,
password:parameter.password
}
})
}
...
複製代碼
manage.js 存放關於公司的主體業務的網絡請求
...
在src
文件夾下新建store
文件夾,在store
文件夾中 具體建立的文件以下:
.
├── getters.js
├── index.js
├── modules
│ └── user.js
└── mutation-types.js
複製代碼
mutation-types.js
裏寫滿了,要存儲信息的文件都名字
//mutation-types.js
export const AVATAR = 'avatar'
export const NAME = 'name'
export const USERINFO = 'userInfo'
export const ACCESS_TOKEN = 'token'
複製代碼
index.js
文件內導入了各個store模塊
import Vue from 'vue';
import Vuex from 'vuex';
import user from "./modules/user"
import getters from "./getters"
Vue.use(Vuex)
export default new Vuex.Store({
// 導入的模塊所有放在modules中
modules:{
user
},
state:{},
mutations:{},
actions:{},
getters,
})
複製代碼
modules
文件夾中存放了各個信息模塊的store
//user.js
import Vue from 'vue'
import {AVATAR,NAME,USERINFO,ACCESS_TOKEN} from '@/store/mutation-types'
import {login} from "@/api/login"
const user = {
// 存放用戶信息
state:{
token:'',
name:'',
avatar:'',
userInfo:''
},
// 操做state
mutations:{
SET_NAME:(state,name)=>{
state.name = name
},
SET_AVATAR:(state,avatar) =>{
state.avatar = avatar
},
SET_USERINFO:(state,userInfo) =>{
state.userInfo = userInfo
}
},
// 能夠異步操做,等網絡請求結果返回後,再經過操做mutations來改寫state 內容
actions:{
// 登錄:
Login({commit},userInfo){
return new Promise((resolve,reject)=>{
// 網絡請求
login(userInfo)
.then(res=>{
let statusCode = res.code;
if(statusCode==200){
const data = res.data;
Vue.ls.set(NAME,data.nickName,3*24*60*60*1000);
Vue.ls.set(AVATAR,data.headImg,3*24*60*60*1000);
Vue.ls.set(USERINFO,data,3*24*60*60*1000);
Vue.ls.set(ACCESS_TOKEN,data.token,3*24*60*60*1000);
commit('SET_NAME',data.nickName);
commit('SET_AVATAR',data.headimg);
commit('SET_USERINFO',data);
resolve();
}else{
reject({
description:res.message
})
}
})
}).catch(err=>{
reject({
description:"登錄失敗請重試"
})
})
}
}
}
複製代碼
由於用戶每次登錄,咱們都須要存儲服務端返回的該用戶的惟一標識token與用戶的各類我的信息,因此咱們能夠將 vuex與網絡請求結合起來,利用actions能夠異步操做這個特性,發送網絡請求,在確認請求成功後,便經過commit去調用mutations操做改寫state的各類信息
const getters = {
name:state.user.name,
avatar:state.user.avatar,
userInfo:state.user.userInfo,
token:state.user.token
}
export default getters
複製代碼
vuex能夠存放狀態,但只要瀏覽器一刷新,這些數據就會沒有了。因此咱們須要數據持久化,在這裏推薦使用
vue-ls
,這是它在npm 官網上的地址https://www.npmjs.com/package/vue-ls
npm i vue-ls
安裝vue-lssrc/config
目錄下,新建defaultSettings.js
,用於配置vue-lsexport default {
storageOptions:{
namespace:'pro_',//本地存儲,key的前綴
name:'ls',//Vue.[name] => 經過Vue.ls來調用
storage:'local'//本地存儲
}
}
複製代碼
main.js
中導入import Vue from 'vue'
import VueStorage from 'vue-ls'
import config from '@/config/defaultSettings'
Vue.use(VueStorage,config.storageOptions)
複製代碼
Vue.ls.set(name,value,time)
// name : 本地存儲的名字
// value : 本地存儲的值
// time : 本地存儲的時間
// Vue.ls.set('boo',123,3*24*60*60*1000)
Vue.ls.remove('foo')// 刪除本地緩存
複製代碼
雖然Vue.ls能夠本地緩存信息,可是vuex依然是每次瀏覽器一刷新,數據就全沒有了,因此咱們須要在瀏覽器刷新的時候,從本地緩存中將數據取出來,再將數據存放vuex中
core
文件夾下新建bootstrap.js
import Vue from 'vue'
import store from '@/store'
import {
ACCESS_TOKEN,
NAME,
AVATAR,
USERINFO
} from '@/store/mutation-types'
export default function Initializer() {
store.commit('SET_NAME',Vue.ls.get(NAME))
store.commit('SET_AVATAR',Vue.ls.get(AVATAR))
store.commit('SET_USERINFO',Vue.ls.get(USERINFO))
}
複製代碼
Initializer
函數import Vue from 'vue'
import bootstrap from './core/bootstrap'
new Vue({
// 每次刷新瀏覽器,vue 就會從新建立一次實例
// 於是能夠每次刷新,都從緩存中取數據存放到state中
created:bootstrap,
render:h => h(App)
}).$mount('#app')
複製代碼
此處只講用戶登錄先後的路由權限
src
目錄下,新建permission.js
//導入的文件
import Vue from 'vue'
import router from './router'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import {ACCESS_TOKEN} from '@/store/mutation-types'
複製代碼
NProgress 是瀏覽器工具欄處的進度條,詳細信息能夠訪問它在npm網上的地址https://www.npmjs.com/package/nprogress
const whiteList = ['login','register','forget'];// 即便用戶沒有登錄,也能夠訪問的路由
複製代碼
beforeEach
router.beforeEach((to,from,next) => {
NProgress.start();// 進度條開始
if(Vue.ls.get(ACCESS_TOKEN)){
//判斷用戶是否登錄
if(to.path==='user/login'){
// 若是已經登錄,而且訪問的地址是登錄地址,
// 則跳轉到登錄後到頁面
next({path:'/xx/xx'});
}else{
// 若是已經登錄,而且訪問的地址不是登錄地址,則讓其跳轉
next();
}
}else{
if(whiteList.includes(to.name)){
// 若是用戶沒有登錄,但訪問的路由在白名單內,則直接進入|
next()
}else{
// 既沒有登錄,訪問的路由地址又不在白名單內
// 則讓其跳轉到登錄地址
next({path:'/user/login'})
}
}
})
router.afterEach(()=>{
NProgress.done();// 路由跳轉結束後,讓進度條結束
})
複製代碼
小生實力水平有限,若是錯漏處,還請各位看官指正, 再聲明一次,該文是看ANTD PRO VUE
源碼後的筆記, 有興趣瞭解更多,請前往其官方文檔https://pro.loacg.com/
做者:胡志武
時間:2019/10/15
如要轉載,請註明出處,若是以爲不錯,請點個贊,再走吧!鞠躬!!!