本文是在学习antd-pro-vue开箱即用的中台前端/设计解决方案的源码后,写的笔记。
这是他们的官方文档ANTD PRO VUE
一、搭建环境
vue create ant-design-vue-pro
这里需要用到vue-cli脚手架 必须先在全局安装vue-cli Vue-cli的官网:Vue Cli

选择第二个,自定义配置


- 之后我们需要借助Ant Design of Vue的UI组件
npm i ant-design-vue -D -S
- 按需加载所需要的组件
npm install babel-plugin-import --dev
修改babel.config.js 文件,配置babel-plugin-import
module.exports = {
presets: ["@vue/app"],
+ plugins: [
+ [
+ "import",
+ { libraryName: "ant-design-vue", libraryDirectory: "es", style: true }
+ ]
+ ]
};
详细内容可以看antd of vue
- 如果发现使用了less 控制台报错
修改vue.config.js 文件,如果没有该文件,则新建一个
module.exports = {
css: {
loaderOptions:{
less:{
javascriptEnabled:true,
}
}
}
}
二、按需加载UI组件
在删除大部分不需要的内容后,现在目录如下:

- 在根目录,新建一个文件夹
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"
三、页面基本布局配置
- 在
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.jsimport 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拦截器对知识,详细内容可以看官方文档拦截器
六、Restful API
-
在
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的各种信息
- getters.js用于取出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-ls- 在
src/config目录下,新建defaultSettings.js,用于配置vue-ls
export 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))
}
- 每次在Vue创建实例后,调用
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
如要转载,请注明出处,如果觉得不错,请点个赞,再走吧!鞠躬!!!