Vue+webpack项目配置便于维护的目录结构教程详解

新建项目的时候创建合理的目录结构便于后期的维护是很重要

环境:vue、webpack

目录结构:

项目子目录结构

Vue+webpack项目配置便于维护的目录结构教程详解

子目录结构都差不多,主要目录是在src下面操作

src目录结构

Vue+webpack项目配置便于维护的目录结构教程详解

src/common 目录

主要用来存放公共的文件

Vue+webpack项目配置便于维护的目录结构教程详解

src/components

主要用来存放公共的组件

src/config

用来存放配置文件,文件目录如下

Vue+webpack项目配置便于维护的目录结构教程详解

src/config/index.js 配置目录入口文件

import api from './website' // 当前平台 export const HOST_PLATFORM = 'WEB' // 当前环境 export const NODE_ENV = process.env.NODE_ENV || 'prod' // 是否开启监控 export const MONITOR_ENABLE = true // 路由默认配置 export const ROUTER_DEFAULT_CONFIG = { // mode: 'history', waitForData: true, transitionOnLoad: true } // axios 默认配置 export const AXIOS_DEFAULT_CONFIG = { timeout: 20000, maxContentLength: 2000, headers: {} } // vuex 默认配置 export const VUEX_DEFAULT_CONFIG = { strict: process.env.NODE_ENV !== 'production' } // API 默认配置 export const API_DEFAULT_CONFIG = { baseURL: api, // 图标地址 imgUrl: `${api}/api/system/icon.do?name=`, // 菜单图标地址 menuImgUrl: `${api}/`, dicomUrl: `${api}/testDICOM/`, // 请求参数格式 json/form-data isJSON: true, // 请求加载效果, 支持element-ui所有参数配置 loading: { text: '加载中' }, // 是否开启mock mock: false, // 是否开启debug debug: false, // 定义全局变量 ippid: 'test' } export const CONSOLE_REQUEST_ENABLE = true // 开启请求参数打印 export const CONSOLE_RESPONSE_ENABLE = false // 开启响应参数打印 export const CONSOLE_ROUTER_ENABLE = false // 打印路由信息 export const CONSOLE_MONITOR_ENABLE = true // 监控记录打印

src/config/website.js 动态配置ip文件

/** * 动态匹配api接口地址 */ const website = [ { web: 'localhost:9000', api: '//192.168.0.170:8080/xhhms', env: 'dev' }, { web: '127.0.0.1:8000', api: '//192.168.0.149:8080/xhhms', env: 'dev' } ] let matchApi = website.filter(item => new RegExp(item.web).test(location.href)) if (matchApi.length > 1) { console.error(`${location.href}: 该站点映射了多个api地址${matchApi.map(item => item.api).join(',')},默认选取第一个匹配项`) } export default matchApi[0].api

src/config/interceptors目录

拦截器配置

src/config/interceptors/axios.js

import router from 'Plugins/router' import { CONSOLE_REQUEST_ENABLE, CONSOLE_RESPONSE_ENABLE } from '../index.js' import { Toast, Indicator } from 'mint-ui' import store from 'Store' import Qs from 'qs' /** * 请求拦截器(成功) * @param {object} request 请求对象 * @return {object} request 处理后的请求对象 */ export function requestSuccessFunc(request) { CONSOLE_REQUEST_ENABLE && console.info('requestInterceptorFunc', `url: ${request.url}`, request) // 自定义请求拦截逻辑,可以处理权限,请求发送监控等 // console.log(request.url) // if (localStorage.getItem('token') === null && request.url.indexOf('login') === -1) { // console.log('[*] 当前用户没有登录!!') // router.push('/login') // return false // } // 登录token携带 request.headers['X-AUTH-TOKEN'] = localStorage.getItem('token') // 兼容性写法,如果request里边没得site_code 就用全局site_code let publicParams = { orgCode: sessionStorage.getItem('orgCode'), menuId: sessionStorage.getItem('currentMenuId') } /** * @author wucheshi * @time 2018-08-13 * @description 需求变动,网站code从本地siteCodeList 这个字段来 */ let siteCodeList = sessionStorage.getItem('siteCodeList') // !request.data.site_code && (publicParams = Object.assign({ site_code: store.state.currentSite.code }, publicParams)) !request.data.site_code && !request.noSiteCode && (publicParams = Object.assign({ site_code: siteCodeList }, publicParams)) /** * @author wucheshi * @time 2018-08-13 * @description 单表操作接口不需要传递sitecode */ // 兼容单表操作传递site_code // if (request.data.condition && !request.noSiteCode) { // console.log(siteCodeList, 11111) // if (request.data.condition.findIndex(item => item.name === 'site_code') === -1) { // request.data.condition.push({ name: 'site_code', value: siteCodeList }) // } else { // request.data.condition.find(item => item.name === 'site_code').value = siteCodeList // } // } let newData // 判断是否是formdata类型 if (Object.prototype.toString.call(request.data) === '[object FormData]') { // 合并formdata格式公共参数 Object.keys(publicParams).forEach(key => { request.data.append(key, publicParams[key]) }) newData = request.data } else { // 合并公共参数 newData = Object.assign(request.data, publicParams) // 判断是否采用json格式提交参数 !request.isJSON && (newData = Qs.stringify(newData)) } // 不同提交参数方式给不同的字段赋值 if (request.method.toUpperCase() === 'POST') { request.data = newData } else if (request.method.toUpperCase() === 'GET') { request.params = newData } // 加载效果 request.loading && Indicator.open(request.loading) // 输出请求数据 CONSOLE_REQUEST_ENABLE && console.info(`%c 请求接口地址:${request.url} 请求接口名称:${request.desc} 请求参数JSON: ${JSON.stringify(request.data, '', 2)} `, 'color: #f60') return request } /** * 请求拦截器(失败) * @param {object} requestError 请求报错对象 * @return {object} 返回promise对象 */ export function requestFailFunc(requestError) { // 自定义发送请求失败逻辑,断网,请求发送监控等 return Promise.reject(requestError) } // 你就是个sx /** * 响应拦截器(成功) * @param {object} responseObj 响应对象 */ export function responseSuccessFunc(responseObj) { // 自定义响应成功逻辑,全局拦截接口,根据不同业务做不同处理,响应成功监控等 // console.log(typeof (responseObj.data)) // // 判断string是否包含 java字段 说明error // if (typeof (responseObj.data) === 'string' || responseObj.data.indexOf('java') !== -1) { // console.log('[*] token错误') // this.$router.push('/login') // } // 加载效果 Indicator.close() // 响应对象 let resData = typeof responseObj.data === 'object' ? responseObj.data : JSON.parse(responseObj.data) let { status, message } = resData // 输出响应体 CONSOLE_RESPONSE_ENABLE && console.info(responseObj) // 输出返回JSON数据 CONSOLE_RESPONSE_ENABLE && console.info(`%c 响应接口地址: ${responseObj.config.url} 响应接口描述: ${responseObj.config.desc} 响应数据JSON: ${JSON.stringify(resData, '', 2)} `, 'color: blue') // 自定义处理业务逻辑 if (responseObj.config.customErrorHandle) { return resData } // 统一逻辑处理 switch (+status) { case 0: // 常规错误 Toast(message) break case 1: // 如果业务成功,直接进成功回调 return resData case 401: // 登录失效 store.commit('DELETE_USER_INFO') router.push({ path: '/login', redirect: router.app._route.fullPath }) Toast(message) break default: // 业务中还会有一些特殊 code 逻辑,我们可以在这里做统一处理,也可以下方它们到业务层 // !responseObj.config.noShowDefaultError && GLOBAL.vbus.$emit('global.$dialog.show', resData.msg); return Promise.reject(resData) } } /** * 响应拦截器(失败) * @param {object} responseError 响应报错对象 * @return {object} 返回promise对象 */ export function responseFailFunc(responseError) { // 响应失败,可根据 responseError.message 和 responseError.response.status 来做监控处理 // ... // 加载效果 Indicator.close() // 错误码处理 // console.log(responseError.response) if (typeof (responseError.response) === 'undefined') { return false } switch (responseError.response.status) { case 401: console.error('401错误') store.commit('DELETE_USER_INFO') router.push({ path: '/login', redirect: router.app._route.fullPath }) store.state.user.username && Toast('登录超时') break case 403: console.error('403错误') router.push({ path: '/403' }) break case 500: console.error('500错误') router.push({ path: '/500' }) break } return Promise.reject(responseError) }

src/config/interceptors/index.js

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/0009160efe6dbb0330b948ef17ba5372.html