前言
本教程带你用vue-cli3.0开发一个开箱即用的移动端h5开发框架,本章讲的是正式开发前的准备工作。
目录结构
|-public //模板文件
|-index.html //html模板文件
|-favicon.ico //网站图标
|-src //源代码
|-assets //静态资源文件
|-img //图片文件
|-css //样式资源
|-js //脚本文件
|-data //数据文件
|-others //其他文件
|-components //公用组件
|-router //路由文件
|-index.ts //路由入口文件
|-main.js //路由文件
|-server //服务请求配置
|-api //接口配置文件
|-config //请求配置文件
|-axios //axios配置文件
|-http //全局请求封装
|-store //全局store管理
|-views //view
|-utils //全局公用方法
|-vue.congig.js //配置文件
|-package.json //描述文件
|-env //打包配置文件
接下来进行目录的大致讲解
server服务
server服务目录中主要包括了4个文件,分别进行讲解
api
用来存储所有的对接接口请求,进行全局注册,方便调用。
// api 接口列表
const api = {
//主页模块
app: {
nodeRoute:'user',//用户信息
nodeAdd:'user/add'//添加用户
}
}
export default api
config
用来配置打包地址,请求头协议,请求方式等信息。
// REQUEST配置文件
const DOMAIN_NAME = {
// 本地端口
URL_DEVELOPMENT_MICRO: 'http://192.168.1.57:7001/',
// 测试端口
URL_TEST_MICRO: 'http://192.168.1.57:7002/',
// 准生产(灰度)端口
URL_PREVIEW_MICRO: 'http://192.168.1.57:7003/',
// 生产端口
URL_PRODUCTION_MICRO: 'http://192.168.1.57:7004/',
// HEADER
REQUEST_HEADER: {
application: 'application/x-www-form-urlencoded', // 请求体中的数据会以普通表单形式(键值对)发送到后端,“引入qs进行处理”
form: 'multipart/form-data', // 它会将请求体的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。
text: 'application/json'// 请求体中的数据会以json字符串的形式发送到后端
},
// 请求方式
REQUEST_WAY: {
Post: 'POST', // 向指定路径资源提交数据进行请求处理,数据包含在请求体中
Get: 'GET', // 向指定路径资源发出请求,数据暴露在url中
Options: 'OPTIONS', // 返回服务器针对特定资源所支持的HTTP请求方法,允许客户端查看,测试服务器性能
Head: 'HEAD', // 向服务器与GET请求相一致的响应,响应体不会返回,可以不传输整个响应内容
Put: 'PUT', // 从客户端向服务器传送的数据取代指定的文档的内容
Delete: 'DELETE', // 请求服务器删除指定的页面
Trace: 'TRACE'// 回显服务器收到的请求,主要用于测试或诊断
},
//TOKEN
TOKEN:''
//TOKEN:sessionStorage.getItem('token')
}
export default DOMAIN_NAME
有些项目中,我们需要携带token或者openid等参数返回后台,这样进行封装后我们就不需要手动添加了。这里配置了四种开发环境,api 是根据 env 环境变量动态切换的,打包时可自动配置。
axios
用来配置axios相关,封装了拦截,响应等。
import axios from 'axios'
import DOMAIN_NAME from './config.js'
/*
* 请求拦截器
*/
axios.interceptors.request.use((config) => {
// 预处理请求信息
console.log('RequestMessage:',config)
return config
}, (error) => {
// 预处理请求异常时抛出error
return Promise.reject(error)
})
/*
* 响应拦截器
*/
axios.interceptors.response.use((res) => {
// 进行响应事件处理
const status = parseInt(res.status)
switch (status) {
case 200 :
return res
break;
case 400 :
return Promise.reject({ code: status, msg: '请求错误' })
break;
case 403 :
return Promise.reject({ code: status, msg: '服务器拒绝请求' })
break;
case 404 :
return Promise.reject({ code: status, msg: '页面丢失' })
break;
case 500 :
return Promise.reject({ code: status, msg: '服务器内部错误' })
break;
case 503 :
return Promise.reject({ code: status, msg: '服务不可用' })
break;
default:
break;
}
}, (error) => {
return Promise.reject(error)
})
/* 多环境打包配置 */
let requestUrl = ''
if (process.env.VUE_APP_ENV == 'test') {
requestUrl = DOMAIN_NAME.URL_TEST_MICRO
} else if (process.env.VUE_APP_ENV == 'preview') {
requestUrl = DOMAIN_NAME.URL_PREVIEW_MICRO
} else if(process.env.VUE_APP_ENV == 'production'){
requestUrl = DOMAIN_NAME.URL_PRODUCTION_MICRO
} else {
requestUrl = DOMAIN_NAME.URL_DEVELOPMENT_MICRO
}
/**
* 返回axios方法
* @param url(如果传绝对地址则baseURL不会追加到url之前)
* @param method
* @param timeout
* @param data
* @param headers
* @param dataType
* @returns {AxiosPromise}
*/
export default function (url, {
// 默认求情方式post
method = 'post',
// 超时
timeout = 6000,
// 请求主题
data = {},
// 请求头
headers = {
'Content-Type':DOMAIN_NAME.REQUEST_HEADER.application,
'token':DOMAIN_NAME.TOKEN
},
// 文件类型
dataType = 'json'
}) {
const config = {
method: method,
timeout: timeout,
url: url,
baseURL: requestUrl,
data: data,
headers: headers,
dataType: dataType,
async:true,
withCredentials:true, //表示跨域请求时是否需要使用凭证
}
return axios(config)
}
http
进行各种请求方式的封装,get,post,formdata等
import axios from './axios'
import qs from 'qs'
const requests = {
// post 请求
requestPost (data, path) {
return axios(path, {
// 请求方式
method: 'post',
// 数据体
data: qs.stringify(data)
}).then(res => {
return res
}, (error) => {
return Promise.reject(error)
})
},
// get 请求
requestGet (data, path) {
return axios(path, {
method: 'get',
data: qs.stringify(data)
}).then(res => {
return res
}, (error) => {
return Promise.reject(error)
})
},
// formdata 上传文件
requestFormData (data, path) {
return axios(path, {
headers: { 'Content-Type': 'multipart/form-data' },
method: 'post',
data: data,
onUploadProgress: function (progressEvent) {
if (progressEvent.lengthComputable) { callback1(progressEvent) }
},
cancelToken: cancelToken
}).then(res => {
return res
}, (error) => {
return Promise.reject(error)
})
}
}
export default requests
这里components存放的是一些全局公用组件,比如地址选择器,上传组件等。
store
用来进行一些数据的统一管理,比如登录token,消息通知数量,或者一些全局配置等,可结合自己的业务场景进行开发。
router
路由管理一为了避免后期路由数量过多,从开始就应该考虑到路由的模块化管理。路由结构这里拆分为了index路由入口文件和其他路由文件。
index 路由入口文件
import Vue from 'vue'
import VueRouter, { RouteConfig } from 'vue-router'
import Main from './main.js'
Vue.use(VueRouter)
// 定义路由
const router = new VueRouter({
mode : 'history',
base : process.env.BASE_URL,
routes : [
...Main
]
})
// 处理vue-router.esm.js?8c4f:2089 Uncaught (in promise) 的发生
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
export default router
*这里的文件配置为了避免异步导致的路由报错
const originalPush = VueRouter.prototype.pushVueRouter.prototype.push = function push(location) { return originalPush.call(this, location).catch(err => err)}
main 路由文件
export default [
//主页
{
path : '/',
name : 'Home',
meta: {title: '主页'},
component : () => import('../views/Home.vue')
},
]
前后端分离带来的首要问题便是前后端交互
跨域问题
*请求跨域
axios请求跨域,我们所使用的方式是后端配置cors来解决的。除了这个方式还可以进行proxy的代理配置。
*阿里云资源跨域
这里需要进行阿里云的配置,否则会出现资源跨域现象。
接口问题
前后端交互中最主要的问题便是接口对接了,相比之前的word文档写接口配置,难以整理,更新困难,无法测试。为对接带了很大的困难和不便,这里推荐一款超级好用的接口文档工具。
**eolinker,**这是一款针对接口信息管理的平台,它集成了以下功能 1、接口信息的录入与导出 2、在线测试 3、团队协作管理 4、开发环境管理 5、支持数据字典的录入 6、用户常用到的小工具 7、对状态码进行管理 8、在线社区讨论 其中我比较常用的功能有接口信息的录入与导出、在线测试以及团队协作管理,不得不说,这是款考虑得十分周全的一款平台。 首先,接口信息的录入(记录信息粒度小,布局合理,考虑周到) 写完接口,用Postman或DHC进行测试? 这样太麻烦了,直接点击测试,可提前新增测试环境。
swagger swagger是一个REST APIs文档生成工具,可以在许多不同的平台上从代码注释中自动生成,开源,支持大部分语言,社区好,使用很方便。前提是后端需要去配置,如果不愿意耗费时间的话就使用eolinker**。**
Duang总结
快捷开发vue移动H5开发框架