文件结构化
api和views
api文件和views目录下的名称和api需求应该是对应的,这样会非常清晰
components
src
下的components
目录放置共用的组件,页面内的组件应该放在自己的目录下
Vuex
一个比较庞大的项目,几十个业务模块,几十种权限,但业务之间的耦合度是很低的,文章模块和评论模块几乎是俩个独立的东西,所以根本没有必要使用 vuex 来存储data,每个页面里存放自己的 data 就行。当然有些数据还是需要用 vuex 来统一管理的,如登录token,用户信息,或者是一些全局个人偏好设置等,还是用vuex管理更加的方便,具体当然还是要结合自己的业务场景的。 参考该的如何自动化项目
Module-Vuex
项目庞大起来,vuex也区分开了多个文件,就很容易搞混某个目录,声明的变量和方法等等,在文件export的时候加上namespaced: true
在使用时就可以使用目录的方式引入this.$store.dispatch('app/getToken')
前期是要做好vuex的配置
alias
路径别名,当项目逐渐变大之后,文件与文件之间的引用关系会很复杂,这时候就需要使用alias
了。有的人喜欢alias
指向src
目录下,再使用相对路径找文件
const path = require('path');//使用node的path
//__dirname为根目录,join()为拼接参数,返回地址
resolve: {
alias: {
'@': path.join(__dirname,'src')
}
}
//使用时
import stickTop from '@/comment/components/stickTop';
或者也可以
alias: {
'src': path.join(__dirname, 'src'),
'components': path.join(__dirname, 'src/components'),
'api': path.join(__dirname, 'src/api'),
'utils': path.join(__dirname, 'src/utils'),
'store': path.join(__dirname, 'src/store'),
'router': path.join(__dirname, 'src/router')
}
//使用时
import stickTop from 'components/stickTop'
import getArticle from 'api/article'
没有好与坏对与错,纯看个人喜好和团队规范。
ESLint
首先商店里安装eslint
代码规范检查,进入vsCode设置入口(文件>首选项>设置>用户设置>更多设置(右边的三个小点)>打开settings.json)然后在右边覆盖默认设置填写(配置一些基本的eslint的检测修复,深入自行查看配置)
"files.autoSave":"off",
"eslint.validate": [
"javascript",
"javascriptreact",
"html",
{
"language": "vue",
"autoFix": true
}
],
"eslint.options": {
"plugins": ["html"]
},
封装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,或者来做一些统一的异常处理,一劳永逸。 (拦截器用上回来补充)
前后端交互
环境变量
vue-cli3的环境变量查阅文档
根目录下包含了.env.development
和.nev.production
文件,代表了开发环境变量和线上环境变量,可在任何地方调用
process.env.*
*号代表你声明的环境变量名
//.env.development
VUE_APP_BASE_API = '/dev'
//use
const pri = process.env.VUE_APP_BASE_API;
//输出/dev
跨域问题
前端开发环境处理跨域问题主要用到域名代理:
即定义一个开发环境关键字段,请求时把字段代理到对应的域名上,实际看到的请求地址是本域的。
//vue.config.js
module.exports={
//...其他配置
devServer:{
//...
proxy: {
[process.env.VUE_APP_BASE_API]: {
target: `http://192.168.1.11:8443`,//将/dev代理到的域名
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''//代理后的地址把/dev改为空,进行请求
}
}
},
}
}
process.env.VUE_APP_BASE_API
是vueCli的环境配置变量
线上的跨域问题一般都是后台解决,搭建反向代理什么的,前端很难解决跨域问题。
自行mock
用mockjs默认后台数据
router-view
我创建和编辑的页面使用的是同一个component
,默认情况下当这两个页面切换时并不会触发vue的created
或者mounted
钩子,官方说你可以通过watch
$route
的变化来做处理,但其实说真的还是蛮麻烦的。后来发现其实可以简单的在 router-view
上加上一个唯一的key
,来保证路由切换时都会重新渲染触发钩子了。这样简单的多了。
router-view
和component
:is
的用法有相似的地方,区别在这
<router-view :key="key"></router-view>
computed: {
key() {
return this.$route.name !== undefined? this.$route.name + +new Date(): this.$route + +new Date()
}
}
优化
自动化项目
webpack
有一个自动化项目的配置,还是挺好用的叫require.context
可自行查询文档。
自动引入文件夹内的所有文件,不必每增加一个文件去
inport
一次
这个项目内在vuex中使用,每个模块有自己的vuex文件,在配置vuex里,引入:
const modulesFiles = require.context('./modules', true, /\.js$/)
const modules = {}
//modulesFiles.keys()拿到文件名数组
modulesFiles.keys().map(item => {
const moduleName = item.replace(/^\.\/(.*)\.\w+$/, '$1');//格式化文件名,用于做对象key
const value = modulesFiles(item);//根据目录名,取文件内容
modules[moduleName] = value.default;//赋值给对象
})
const store = new Vuex.Store({
modules,//引入,{a:a文件内容,b:b文件内容}
getters
})
export default store
多环境
vue-cli
默认只提供了dev
和prod
两种环境。但其实正真的开发流程可能还会多一个sit
或者stage
环境,就是所谓的测试环境和预发布环境。所以我们就要简单的修改一下代码。其实很简单就是设置不同的环境变量
"build:prod": "NODE_ENV=production node build/build.js",
"build:sit": "NODE_ENV=sit node build/build.js",
普通打包
npm install
npm run build:prod
优化以来打包,npm依赖打入基础淘宝镜像进行加速
npm install --registry=https://registry.npm.taobao.org
npm run build:prod
放上基础篇链接:手摸手,带你用vue撸后台 系列一(基础篇)