这篇博客我将为你介绍vue的架构思想,固然这只是我根据遇到的项目总结的vue架构,这是我发现的一个小三轮,若是你有好的架构也欢迎指教哦。html
好了,咱们开始聊吧!前端
以我手撸的一个小项目 低配饿了么外卖平台 为例:线上演示地址vue
2019.4.14 最近一次重构git地址ios
├── src // 生产目录
│ ├── api // axios操做
│ ├── components // 组件
│ │ ├── common // 公共组件
│ │ ├── admin // 用户组件
│ │ └── seller // 商家组件
│ ├── router // 路由
│ ├── store // vuex状态管理器
│ ├── App.vue // 首页
│ └── main.js // Webpack 预编译入口
复制代码
很简单先访问App.vue,根据路由映射不一样组件渲染页面,每一个页面都有ajax请求git
ajax请求长这样github
getUserInfo: function() {
this.axios.get('user/infor')
.then(res => {
if (res.data.status) {
this.user = res.data.data;
}
})
.catch(error => {
console.log(error);
});
},
复制代码
2018.4.21 Github地址:elm1.0ajax
├── src // 生产目录
│ ├── api // axios操做
│ ├── components // 组件
│ ├── router // 路由
│ ├── store // vuex状态管理器
│ ├── App.vue // 首页
│ └── main.js // Webpack 预编译入口
复制代码
没错只是将ajax请求都集中到了api目录下 api目录下的index.js文件vuex
import axios from 'axios';
import store from '../store';
let httpURL = "http://www.xuguobin.club/api/elm/" //这是我服务器的api接口
let localURL = 'http://localhost/api/elm/'; //这是本地koa2的api接口
axios.defaults.baseURL = localURL;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
export default {
//获取用户信息
getUser() {
return axios.get('user/infor');
},
//获取订单
getOrders(orderType) {
return axios.get('user/order?type=' + orderType);
},
//提交订单
submitOrder(order) {
return axios.get('user/submit?order=' + order);
},
//确认收货
confirmOrder(orderId) {
return axios.get('user/confirm?orderId=' + orderId);
},
//提交评价
submitRating(rating) {
return axios.get('user/rating?rating=' + rating);
},
//用户登陆
userLogin(user) {
return axios.post('user/login',`username=${user.username}&password=${user.password}`);
},
};
复制代码
这样子作,很好的将axios请求与vue页面解耦和了! 如今ajax请求长这样axios
getUserInfo: function() {
this.api.getUser()
.then(res => {
if (res.data.status) {
this.user = res.data.data;
}
})
.catch(error => {
console.log(error);
});
},
复制代码
2018.7.8 Github地址:elm2.0api
讲道理此次重构的有点过度
├── src // 生产目录
│ └── axios // axios操做
| ├──base // axios模板
| | ├──base.js //axios基类
| | └──setting.js //状态码
| └── user
| ├──cache.js //请求函数
| └──config.js //配置信息
|
| ├── base //vue模板
│ ├── components // 组件
| | ├──common //公共组件
| | └──admin
| | ├── ui.vue // 输出组件
| | ├── component.html // template
| | ├── component.js // script
| | └── component.less // style
| |
│ ├── router // 路由
│ ├── store // vuex状态管理器
│ ├── App.vue // 首页
│ └── main.js // Webpack 预编译入口
复制代码
第一次的重构虽然已经将axios请求和页面分离开来了,可是每次请求后都要验证状态码,处理错误信息。
其实这彻底没有必要每一个页面都来一下,这些公共操做能够一块儿放在axios的基类
import axios from 'axios'
import setting from './setting'
let httpURL = "http://www.xuguobin.club/api/elm/" //这是我服务器的api接口
let localURL = 'http://localhost/api/elm/'; //这是本地koa2的api接口
axios.defaults.baseURL = httpURL;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
export default class AxiosCache {
constructor() {
this.__config = {}
this.__setting = setting;
this.init();
}
init() {
this.doFlushSetting(CACHE_KEY, )
}
doFlushSetting(key, conf) {
if (!key && typeof key !== 'string') {
return
}
this.__config[key] = conf
}
/*判断状态码*/
resultJudge(code) {
return code
}
/*发送请求数据*/
sendRequest(key, options) {
let send = this.__config[this.settingKey][key];
let self = this;
let baseURL = send.url;
send.method == 'get'
? options.data && (send.url += options.data)
: send.data = options.data
axios(send)
.then(function (response) {
send.url = baseURL;
if (self.resultJudge(response.data.status)) {
options.success(response.data.data)
} else {
options.fail
? options.fail(response.data.data)
: self.handleErrorCase(response.data.status)
}
}).catch(function (error) {
self.handleErrorCase(error)
})
}
/*处理错误信息*/
handleErrorCase(error) {
if (typeof error == 'Number') {
console.log(error)
} else {
alert(error)
}
}
}
复制代码
而发送请求的时候,只须要这样
getUSer: function() {
this.userCache.getUser({
success: res => this.user = res
})
},
复制代码
是否是很简洁。这样作,又进一步的解耦了axios操做,你能够对比我github上的elm1和elm2两个版本结构,必定会有所收获。
前端的架构追求就是尽可能 完美复用和解耦
2019.4.14 Github地址:elm3.0
可能并无优化多少,可是提供一个思路
elm2版本中的axios处理逻辑是:封装一个AxiosCache的基类,里面有一些共用的方法,其余axios对象则继承这个基类,在各自页面中进行实例化,若是这个页面须要请求用户相关接口则实例化一个UserCache,可若是另外一个页面也有用到则再实例化一个UserCache,重复的实例化让我以为性能上的浪费。因此我想到了另一种不使用类继承和实例化的axios的结构
elm3版本结构以下
├── axios // axios操做
| ├──index.js // axios配置表
| ├──base // axios公共部分
| | ├──index.js //axios公共方法
| | └──setting.js //状态码
| └── user
| ├──cache.js //请求函数
| └──config.js //配置信息
复制代码
elm3版本中的axios处理逻辑是这样的:在
axios
目录下的index.js
中引入各Cache的配置信息和状态码构成一个配置表
// 引入状态码表
import setting from './base/setting'
// 引入config配置表
import userConfig from './user/config';
import goodConfig from './good/config';
import sellerConfig from './seller/config';
export default {
__setting: setting,
__config: {
'user_cache_key': userConfig,
'good_cache_key': goodConfig,
'seller_cache_key': sellerConfig
}
}
复制代码
将这个配置表导入赋值给Vue(main.js):
import axios from '@/axios'
Vue.$axios = axios;
复制代码
而base
目录下的index.js
中只保留公共方法 (这里我使用了Promise)
import axios from 'axios'
import Vue from 'vue'
let httpURL = "http://www.xuguobin.club/api/elm/" //这是我服务器的api接口
let localURL = 'http://localhost/api/elm/'; //这是本地koa2的api接口
axios.defaults.baseURL = httpURL;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// 判断状态码
function resultJudge(code) {
return code
}
// 处理错误公共方法
function handleErrorCase(error) {
if (typeof error == 'Number') {
console.log(error)
} else {
alert(error)
}
}
// 发送请求
export default function sendRequest(settingKey, key, data) {
let send = Vue.$axios.__config[settingKey][key];
let baseURL = send.url;
send.method == 'get'
? data && (send.url += data)
: send.data = data;
return new Promise((resolve,reject) => {
axios(send)
.then((res)=>{
send.url = baseURL;
resultJudge(res.data.status) ? resolve(res.data.data) : reject(res.data.data);
}).catch((err)=>{
handleErrorCase(err)
});
});
}
复制代码
而在其余的Cache页面的请求函数
import sendRequest from '../base';
const CACHE_KEY = 'good_cache_key'
export default {
getGood(options) {
return sendRequest(CACHE_KEY, 'good-getGood',options);
},
getGoods(options) {
return sendRequest(CACHE_KEY, 'good-getGoods',options);
}
}
复制代码
这样作的好处是在页面第一次加载时就制定好了一张ajax请求的信息表并存储在
Vue.$axios
中,后期页面使用时不需求实例化,直接按表索引就行了
未完待续...... 你有好的架构也欢迎你fork个人master版本! ^_^