-
目录结构
├── build // 构建相关 ├── config // 配置相关 ├── src // 源代码 │ ├── api // 所有请求 │ ├── assets // 主题 字体等静态资源 │ ├── components // 全局公用组件 │ ├── directive // 全局指令 │ ├── filtres // 全局 filter │ ├── icons // 项目所有 svg icons │ ├── lang // 国际化 language │ ├── mock // 项目mock 模拟数据 │ ├── router // 路由 │ ├── store // 全局 store管理 │ ├── styles // 全局样式 │ ├── utils // 全局公用方法 │ ├── vendor // 公用vendor │ ├── views // view │ ├── App.vue // 入口页面 │ ├── main.js // 入口 加载组件 初始化等 │ └── permission.js // 权限管理 ├── static // 第三方不打包资源 │ └── Tinymce // 富文本 ├── .babelrc // babel-loader 配置 ├── eslintrc.js // eslint 配置项 ├── .gitignore // git 忽略项 ├── favicon.ico // favicon图标 ├── index.html // html模板 └── package.json // package.json
api 和 views
根据业务模块划分view,view与api模块一一对应,全区公用的api模块单独放置;
components
components 放置全局公用组件,如上传组件,富文本等,一些页面级组件建议还是放在各自views下
store
不要为了用vuex而用vuex!有些数据还是需要用 vuex 来统一管理的,如登录token,用户信息,或者是一些全局个人偏好设置等,还是用vuex管理更加的方便,具体当然还是要结合自己的业务场景的
jquery
当 webpack 碰到 require 的第三方库中出现全局的$、jQeury和window.jQuery ;使用webpack 内置的 ProvidePlugin
插件,只需要
new webpack.ProvidePlugin({ $: 'jquery' , 'jQuery': 'jquery' })
alias
项目逐渐变大后,项目与项目之间的引用会变复杂,需要使用alias 了
有的人喜欢alias 指向src目录下,再使用相对路径找文件
resolve: { alias: { '~': resolve(__dirname, 'src') } } //使用 import stickTop from '~/components/stickTop'
或者也可以
alias: { 'src': path.resolve(__dirname, '../src'), 'components': path.resolve(__dirname, '../src/components'), 'api': path.resolve(__dirname, '../src/api'), 'utils': path.resolve(__dirname, '../src/utils'), 'store': path.resolve(__dirname, '../src/store'), 'router': path.resolve(__dirname, '../src/router') } //使用 import stickTop from 'components/stickTop' import getArticle from 'api/article'
ESLint
推荐 eslint+vscode 来写 vue
封装 axios
通过简单的配置就可以在本地调试线上环境
import axios from 'axios' import { Message } from 'element-ui' import store from '@/store' import { getToken } from '@/utils/auth' // 创建axios实例 const service = axios.create({ baseURL: process.env.BASE_API, // api的base_url timeout: 5000 // 请求超时时间 }) // request拦截器 service.interceptors.request.use(config => { // Do something before request is sent if (store.getters.token) { config.headers['X-Token'] = getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改 } return config }, error => { // Do something with request error console.log(error) // for debug Promise.reject(error) }) // respone拦截器 service.interceptors.response.use( response => response, /** * 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页 * 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中 */ // const res = response.data; // if (res.code !== 20000) { // Message({ // message: res.message, // type: 'error', // duration: 5 * 1000 // }); // // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; // if (res.code === 50008 || res.code === 50012 || res.code === 50014) { // MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', { // confirmButtonText: '重新登录', // cancelButtonText: '取消', // type: 'warning' // }).then(() => { // store.dispatch('FedLogOut').then(() => { // location.reload();// 为了重新实例化vue-router对象 避免bug // }); // }) // } // return Promise.reject('error'); // } else { // return response.data; // } error => { console.log('err' + error)// for debug Message({ message: error.message, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) }) export default service
import request from '@/utils/request' //使用 export function getInfo(params) { return request({ url: '/user/info', method: 'get', params }); }
比如后台项目,每一个请求都是要带 token 来验证权限的,这样封装以下的话我们就不用每个请求都手动来塞 token,或者来做一些统一的异常处理,一劳永逸。 而且因为我们的 api 是根据
env
环境变量动态切换的,如果以后线上出现了bug,我们只需配置一下 @/config/dev.env.js
再重启一下服务,就能在本地模拟线上的环境了。module.exports = { NODE_ENV: '"development"', BASE_API: '"https://api-dev"', //修改为'"https://api-prod"'就行了 APP_ORIGIN: '"https://wallstreetcn.com"' //为公司打个广告 pc站为vue+ssr }
多环境
vue-cli 默认只提供了dev
和prod
两种环境。但其实正真的开发流程可能还会多一个sit
或者stage
环境,就是所谓的测试环境和预发布环境。所以我们就要简单的修改一下代码。其实很简单就是设置不同的环境变量
"build:prod": "NODE_ENV=production node build/build.js", "build:sit": "NODE_ENV=sit node build/build.js",
之后在代码里自行判断,想干就干啥
var env = process.env.NODE_ENV === 'production' ? config.build.prodEnv : config.build.sitEnv
新版的 vue-cli 也内置了 webpack-bundle-analyzer
一个模块分析的东西,相当的好用。使用方法也很简单,和之前一样封装一个 npm script 就可以。
//package.json "build:sit-preview": "cross-env NODE_ENV=production env_config=sit npm_config_preview=true npm_config_report=true node build/build.js" //之后通过process.env.npm_config_report来判断是否来启用webpack-bundle-analyzer var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin())
前后端交互
跨域问题
1.cors
2.dev环境也可以通过 webpack-dev-server
的proxy
来解决,
3.开发环境用nginx
反代理
前端自行mock
iconfont
详细具体的使用可以见文章 手摸手,带你优雅的使用 icon
router-view
创建和编辑的页面使用的是同一个component,默认情况下当这两个页面切换时并不会触发vue的created或者mounted钩子,官方说你可以通过watch $route的变化来做处理,但其实说真的还是蛮麻烦的。后来发现其实可以简单的在 router-view上加上一个唯一的key,来保证路由切换时都会重新渲染触发钩子了。这样简单的多了。
<router-view :key="key"></router-view> computed: { key() { return this.$route.name !== undefined? this.$route.name + +new Date(): this.$route + +new Date() } }