准备工作
需求由来: 当项目越来越大的时候提高项目运行编译速度、压缩代码体积、项目维护、bug修复......等等成为不得不考虑而且不得不做的问题。
又或者后面其他同事接手你的模块,或者改你的bug时避免人家看的眼痛以及心里千百句mamaipi...问候。
并且一个好的开发思路也能大大提高开发效率,以及检验自己。
进入正题:
在本地用 vue-cli
新建一个项目,这个步骤vue的官网上有,我就不再说了。
这里展示一下我的项目架构目录 这次主要讲红字具体实现部分
├── build // 项目build脚本├── config // 项目配置目录├── dist // 项目输出部署目录,执行 npm run build后生成├── src // 生产目录│ ├── assets // 静态资源,包含图片等│ ├── components // 项目公用组件,例如Header、Footer组件等│ ├── mock // 接口mock文件目录│ └── index.js // mock接口集合文件│ ├── pages // 页面目录│ │ ├── Demo // Demo模块,必须用大写开头│ │ │ ├── components // Demo模块专用组件 组件建议全部首字母大写│ │ │ ├── style // Demo模块专用css│ │ │ ├── services // Demo模块服务,可以包含相应方法类│ │ │ ├── interface.js // Demo模块接口结合文件│ │ │ └── index.vue // Demo模块页面入口│ │ └── Other // 其他页面目录│ ├── router // 路由配置文件,如果路由太多了,可以拆分│ ├── services // 项目公用配置服务│ │ │ ├── ajax.js // 所有接口请求公共配置 可以和 request.js 合并一起 不嫌代码太长的话│ │ │ ├── request.js // (需求有则添加) 为所有接口设置公共请求头│ │ │ ├── prompt.js // 全局的提示 例如:接口错误提示、保存成功提示、操作错误提示等等...│ │ │ ├── validate.js // 全局表单校验具体封装可参照element-ui form表单模块│ ├── App.vue // 组件入口│ ├── config.js // 项目配置文件 例如:权限校验,cookie设置、access_token获取等等...│ ├── interface.js // 项目公共接口文件│ └── main.js // Webpack 预编译主入口├── style // 项目公用style├── static // 静态文件目录,保留│ └── i18n // 国际化目录,每一个目录为一种语言│ ├── zh // 中文目录│ │ └── index.json // 配置文件│ └── en // 英文目录├── index.html // 项目入口文件,一般不用改动├── package.json // 项目配置├── README.md // 项目说明├── CHANGE_LOG.md // 项目更新历史文档└── test // 测试目录
services/aiax.js文件
/*** ajax 模块,可以将 axios 替换成 $.ajax 等*/ import axios from 'axios'; import globalConfig from '../config' import { Notification } from 'element-ui'// 注: 具体设置具体判断 根据公司项目需求 以及 接口需求 现在以我公司为例 const init = function () {// 添加 axios 请求拦截器为所有请求加上前缀 、 access_token (我公司所有接口都比要有 access_token才能访问)// 有对 axios 不是很了解的 可以看看 axios 官方文档 https://www.kancloud.cn/yunye/axios/234845axios.interceptors.request.use(function (config) {// 为所有接口加上前缀 例 https://www.kancloud.cn/yunye/axios/234845 前缀为 https://www.kancloud.cn// 因为相同环境下的所有接口前缀肯定是一样的 window.localStorage.gatewayDomain 为前缀域名 倘若后面更改域名之类的 只需改一个地方就行了 就不用说每个调接口的地方都去改 维护便捷// 若想了解分环境打包以及分环境设置 公共域名、前缀等 请看以往博文 https://www.cnblogs.com/ljx20180807/p/9456489.htmlconfig.url = window.localStorage.gatewayDomain + config.url// 登录时设置 cookiesvar cookies = globalConfig.getCookies()if (config.url.indexOf('?') < 0) {config.url += '?'}// 为所有接口加上 access_tokenconfig.url += ('access_token=' + cookies['access_token'])if (!config.data) config.data = {}return config;}, function (err) {// 错误处理return Promise.reject(err)})// 添加 axios 响应拦截器axios.interceptors.response.use(function (response) {// 这里是当接口请求服务器成功响应的情况 解构赋值出需要的数据const {status, data} = response;if (status === 200) {// 如果不出现错误,直接向回调函数内输出 data 状态200if (data.error === 'SUCCESS') {// 成功不用提示return data} else {// 若出现错误则弹窗错误提示if (data.message) {Notification({title: '错误',message: data.message,type: 'error',customClass: 'el-error-msg',duration: 2000})}return data}} else {return response;}}, function (error) {// 这里是当接口请求失败的情况 (例如服务器没响应、后台代码问题之类的) (具体的响应判断根据你后台返回状态码结构)const {response} = error;// 这里处理错误的 http codeif (!response || response.status === 404) {if (!response) { // access_token 失效的情况 弹窗提示 Notification({title: '错误',message: 'access_token已失效请重新登录',type: 'error',customClass: 'el-error-msg',duration: 1500,onClose() {window.location.href = window.localStorage.loginUrl // 自动跳转返回登录页重新获取access_token }})} else {// 这是请求url不对的情况console.log('404 error %o' + error);}}// Do something with response error 对响应错误做点什么return Promise.reject(error.message);}); };export default {init }
services/prompt.js文件
const init = function () {const _this = this;// 建议为了方便使用,这里可以包装window.Alert 具体怎么使用往下看window.Alert = function (msg, duration = 3000) {// 错误提示 _this.$notify({title: '错误',message: msg,type: 'error',customClass: 'el-error-msg',duration});}// 成功提示window.Tips = function (msg, duration = 3000) { _this.$notify({title: '成功',message: msg,type: 'success',duration});}// 警告提示window.Warning = function (msg, duration = 3000) {_this.$notify({title: '警告',message: msg,type: 'warning',duration});}// 全局延时器window.SetTimeout = function (path, queryObject) {setTimeout(_ => {_this.$router.push({path: path,query: queryObject});}, 500)} };export default {init }
page/Demo/interface.js文件 (pc端不建议用vuex 具体看需求吧 vuex管理版本 往下看)
import axios from 'axios';const ajax = {// 获取影像件上传列表GET_IMAGE_LIST: 'images?' }; // 提取公共部分 const API_PATH_PRE_FIX = 'apply/v1/'; // 增加接口模块前缀 let INTERFACE = {}; for (let key in ajax) {INTERFACE[key] = API_PATH_PRE_FIX + ajax[key]; }/*** 方式1: 多参数情况 获取列表* @param data 参数* @returns {*}*/ function getImageList(data) {return axios.get(INTERFACE.GET_IMAGE_LIST, {params: data}).catch(function (error) {window.Alert(error);}); }/*** 方式2: es6模板语法 获取基本信息* @param data 参数* @returns {*}*/ function getContrantInfo(API_PATH_PRE_FIX, agreementId) {return axios.get(`${API_PATH_PRE_FIX}/middle/agreement/basic?agreementId=${agreementId}&`).catch(function (error) { window.Alert(error);}); } export default {getImageList,getContrantInfo, };
page/Demo/index.vue文件
<script>
// 引入上面的接口文件 import INTERFACE from './interface' export default {data() {return {imageList: [],deleteList: []}},created() {// 获取列表 (调用封装好的请求)INTERFACE.getImageList().then(data => {if (data && data.data) this.imageList = data.data})},methods: {// 确认删除 handleDelete() {INTERFACE.deleteAgreement(this.deleteList).then(data => {// 操作成功提示 (上面定义好的全局提示)window.Tips('删除成功!')})}} } </script>
src/main.js文件
import Vue from 'vue' import ElementUI from 'element-ui' import App from './App' import ajax from '@/services/ajax'// axios 统一配置 ajax.init()// 全局变量 indow.localStorage.gatewayDomain = 'https://dev-api.cn/' window.localStorage.defaultLanguage = 'ZH_CN'
src/App.vue文件
<script> import prompt from '@/services/prompt' export default {name: 'app',mounted() {// 全局错误初始化prompt.init.call(this)} } </script>
以上就是pc端的项目配置化、请求统一管理内容了。有疑问的地方留言看到后会第一时间回复,或可改进的地方欢迎指导, 下面介绍vuex管理版本。
移动端结合Vuex 统一管理请求 stroe/actions.js文件
import Vue from 'vue'// 全局域名 const apiUrlBase = window.apiUrlBaseconst API_URL = {GET_APPLICENT: `${apiUrlBase}/app/v1/apply/dictionaries` }const actions = {/*** 获取投保人数据字典*/ actions.getApplicent = ({ state }) => {return new Promise((resolve, reject) => {Vue.http.get(`${API_URL.GET_APPLICENT}?access_token=${state.accessToken}`).then((ret) => {resolve(ret.body)}).catch((err) => {reject(err)})})} }export default actions
.vue文件里调用
this.$store.dispatch(`${storeName}/getApplicent`).then((data) => {console.log(data)})
这就可以啦。
本文为原创 转载请注明出处 。