一、项目架构树
.\
├─ src\
│ ├─ App.vue —— 项目根组件\
│ ├─ main.js —— 项目入口文件\
│ ├─ apis\ —— 接口请求\
│ │ └─ demo.js
│ ├─ assets\ —— 项目静态资源\
│ │ ├─ images\
│ │ │ └─ logo.png
│ │ └─ styles\ —— 全局引用样式资源\
│ │ ├─ reset.less —— 重置样式\
│ │ ├─ common.less —— 全局公共样式\
│ │ └─ variables.less —— 全局公共样式变量\
│ ├─ components\
│ │ ├─ common —— 全局公共组件\
│ │ │ └─ HelloWorld.vue\
│ │ └─ index.js —— 公共组件的全局注册\
│ ├─ request\
│ │ ├─ index.js —— axios请求封装,并添加公共的请求成功与请求失败回调函数(包含全局loading状态调整)\
│ │ └─ interceptors.js —— 请求拦截器,对请求和响应统一处理\
│ ├─ router\
│ │ ├─ auth-guard.js —— 路由守卫\
│ │ ├─ index.js —— 自动引入所有modules模块中的路由,以及标准的单页路由配置\
│ │ └─ modules\
│ │ └─ userModule.js —— 标准模块路由示例\
│ ├─ store\
│ │ └─ index.js —— store 仓库\
│ ├─ utils\ —— 工具类仓库\
│ │ ├─ permission.js —— 权限处理\
│ │ └─ util.js —— 工具类方法\
│ └─ views\ —— 页面\
│ ├─ 404.vue —— 错误页面\
│ ├─ Home.vue
│ └─ userModule\
│ ├─ home.vue
│ └─ tradeManagement
├─ .env.development —— 开发环境变量\
├─ .env.production —— 生产环境变量\
├─ .env.test —— 测试环境变量\
├─ vue.config.js\ —— 项目基础配置\
└─
二、apis 配置
设计思路:将 interceptor(请求拦截)、axios(请求)、api(接口)分成独立的文件进行封装以及管理。
1.1 interceptor.js 请求拦截器
interceptor 请求拦截器中实现对请求的定制化处理。
/* interceptor.js */
import axios from 'axios'
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 10000
})
service.interceptors.request.use(
config => {
// 添加请求头部信息
// config.headers.token = 'token'
return config
},
error => {
return Promise.reject(error)
}
)
service.interceptors.response.use(
res => {
return res.data
},
error => {
return Promise.reject(error)
}
)
1.2 axios 请求封装
/* request.js */
import { Toast } from 'vant'
import instance from './interceptor'
// 配置多个 Toast
Toast.allowMultiple()
/**
* @description 封装 axios 请求
* @param {String} method 请求方法
* @param {String} url 请求地址
* @param {Object} params 请求参数
* @param {Object} options 配置项:showError-是否显示错误提示
*/
function request(method, url, params = {}, options = {}) {
const {
header = {},
timeout = 10000,
loading = false,
loadingMessage = '加载中',
showError = true
} = options
// 配置请求头
const headers = {
'Content-Type': 'application/json',
...header
}
// POST/PUT/PATCH 请求配置
let requestConfit = {
headers,
timeout
}
// 请求时 loading
if (loading) {
Toast.loading({
message: loadingMessage,
duration: 0,
forbidClick: true
})
}
return new Promise((resolve, reject) => {
let data = params
// GET/DELETE 请求配置
if (method === 'get' || method === 'delete') {
data = {
params,
headers,
timeout
}
requestConfit = null
}
instance[method](url, data, requestConfit)
.then(res => {
if (res.code === 200) {
resolve(res.data)
} else {
if (res.code === 401) {
// 登录状态失效
Toast('登录状态已过期,请重新登录')
} else {
// 其它错误状态处理
// ...
if (showError) {
Toast('网络可能存在延迟,请稍后重试')
}
}
reject(res)
}
})
.catch(error => {
reject(error)
})
.finally(() => {
Toast.clear()
})
})
}
function HttpGet(url, params, options) {
return request('get', url, params, options)
}
function HttpPost(url, params, options) {
return request('post', url, params, options)
}
function HttpPut(url, params, options) {
return request('put', url, params, options)
}
function HttpDelete(url, params, options) {
return request('delete', url, params, options)
}
export {
HttpGet,
HttpPost,
HttpPut,
HttpDelete
}
1.3 api 接口文件
/* demo.js */
import { HttpGet } from './request'
// 接口请求
export const getData = (params) => {
return HttpGet('/api/demo', params)
}
// 其它接口
// ...
三、components 配置
公共组件全局注册
/* components/index.js */
import Vue from 'vue'
import BaseLayout from './common/BaseLayout.vue'
Vue.component('BaseLayout', BaseLayout)
四、main.js
在入口文件中加载项目配置、全局样式和项目初始化等等
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// 加载插件
import '@/utils/vant' // vant
import 'amfe-flexible' // 手机端适配
// 注册全局组件
import '@/components'
// 加载样式
import './assets/styles/reset.less'
// 加载 Js 文件
import '@/utils/permission'
Vue.config.productionTip = false
new Vue({
router,
store,
render: (h) => h(App),
}).$mount('#app')
五、vue.config.js 配置
vue.config.js 标准配置罗列
const path = require('path');
function resolve(dir) {
return path.resolve(__dirname, dir);
}
module.exports = {
publicPath: '/answer-app',
devServer: {
// 开发服务代理
proxy: {
'/dev-api': {
target: 'http://api.hdblog.online',
changeOrigin: true,
pathRewrite: {
'^/dev-api': ''
}
}
}
},
chainWebpack: config => {
// 配置别名
config.resolve.alias
.set('@', resolve('src'))
},
css: {
// 配置移动端适配
loaderOptions: {
postcss: {
plugins: [
require('postcss-pxtorem')({
rootValue: 37.5,
propList: ['*']
})
]
}
},
// less 共享全局变量配置
less: {
globalVars: {
hack: `true; @import "~@/assets/styles/variables.less";`
}
}
},
}
源码地址:Demo演示
参考资料: