本文是在学习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
如要转载,请注明出处,若是以为不错,请点个赞,再走吧!鞠躬!!!