新项目基于vue技术路线的开发
运用到的工具、框架或库
- VueJS 2.x
- Vue-router
- axios
- Vuex
- Element UI 2.x(PC端组件库)
- VUX(移动端组件库)
- Babel
- Webpack 3
- Npm
开发流程
使用脚手架工具创建前端工程、后端工程,配置数据库,导入示例数据。
根据项目实际需求,配置路由和菜单,准备各路由所对应的vue文件,vue文件内容为空白,待分配给项目成员实现。
在mock目录下准备mock数据,设计好数据结构(控件需要的数据结构)和字段名(最好同数据库中表结构字段名)
实现vue文件的界面部分,使用mockjs来拦截ajax请求,返回mock数据。
后端实现RESTful接口,并维护接口文档(接口文档推荐使用markdown格式)
注意事项
JS风格使用ECMAScript 6编码风格,建议使用VSCode作为js/vue的编辑器,并安装以下插件EditorConfig for VSCode , Prettier-Standard - JavaScript formatter , JavaScript Standard Style , stylefmt , Vetur,注意不要再安装其他JS格式化工具以免冲突。
并且vscode的配置里要加下面的命令,防止格式化时自动加分号。
"prettier.singleQuote": true,
"prettier.semi": false,在开发界面时使用ElementUI提供的栅格系统(24列),对界面进行响应式布局,以便移动端访问。
不要使用ElementUI提供的图标组件,使用Font Awesome 图标。
后端接口符合RESTful规范
注意后端返回前端的数据,字段名同数据库中的字段名,并转为小写字母开头的驼峰式命名,构造mock数据时也要注意这一点。
工程编译时,source目录下的lib、assets目录下的文件会被直接复制到dist目录下。
不要提交node_modules和dist目录到svn工程里
写接口的同事可维护markdown格式接口文档,并利用gitlab wiki功能编写接口文档
为了便于维护,对话框、页签等如果里面的内容比较多(超过30行),要独立成vue组件,尽量不要让一个vue组件的代码太多(超过500行超过20K),尽量把vue文件里的js移到单独的文件,便于使用编辑器的js校验/js格式化功能。vue文件中css代码行数较多时(超过50行),亦可将css移到单独的css文件。模板部分要保持在vue文件里,以使用Vetur插件的模板语法校验功能。
从后台请求的数据有分页的情况下,Request参数的约定:pageIndex 第几页(从第1页开始);pageSize 每页返回多少行。Response中返回数据除了有列表外,还要有total供分页条显示总记录数。特定的api也可以支持 startIndex 从第几行记录开始,count 返回多少行记录。
新项目基于vue技术路线的实施
多环境打包部署配置-测试环境
一般使用vue-cli脚手架创建的vue工程中都会有一个打包的配置目录build,其中对开发环境编译运行和生产环境打包做了相关配置,如果需要自定义测试环境的打包,我们把build.js复制一份,改名为bulid.test.js作为测试环境打包的总入口,同时复制一份webpack.prod.conf.js---->webpack.test.conf.js,修改成测试环境的相应配置即可。最后在config/index.js中增加如下配置:
buildtest: {
index:path.resolve(__dirname, '../dist/index.html'),
assetsRoot:path.resolve(__dirname, '../dist'),
assetsSubDirectory:'static',
assetsPublicPath:'./',
productionSourceMap:true,
devtool:'#source-map',
productionGzip:false,
productionGzipExtensions: ['js', 'css'],
bundleAnalyzerReport:process.env.npm_config_report
},
这里对几个比较重要的配置做下说明:
assetsPublicPath:打包后引用的静态资源位置,这里使用的是相对路径,生产环境部署的时候如果需要把静态资源部署到cdn上,这个配置改为所在cdn的绝对路径即可。
productionSourceMap:打包以后是否保留源码map,测试环境为了调试方便,这里选择true,生产环境为了安全需要,建议配置成false。最终打包结果的区别在于是否有下图中的map文件
测试环境配置完成以后,在package.json的scripts对象中增加
"buildtest": "nodebuild/build.test.js"
然后就可以使用npmrun buildtest命令来进行测试环境的打包了。
打包静态资源问题
如果在打包的过程中想压缩资源文件,可以开启gzip压缩功能(config/index.js文件)
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
/**
* Source Maps
*/
productionSourceMap: false,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: true,
productionGzipExtensions: ['js', 'css', 'jpg', 'png'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
productionGzip:true|false,是否开始压缩功能,开启压缩功能之后, 打包出来的成果物要小很多.
IE兼容性问题
Vue官方文档有对IE兼容性的说明,因为 Vue 使用了IE8 无法模拟的 ECMAScript 5 特性。所以Vue不支持 IE8 及以下版本,它支持所有兼容ECMAScript 5 的浏览器。
在项目开发完成后,却出现了IE11无法访问的情况,具体报错信息:
SCRIPT5022: [vuex] vuex requires a Promisepolyfill inthis browser.
造成这种现象的原因归根究底就是浏览器对ES6中的promise无法支持,因此需要通过引入babel-polyfill来使我们的浏览器正常使用es6的功能,解决方案:
- 首先通过npm来安装polyfill:
npm install babel-polyfill --save-dev
- 修改webpack.base.conf.js文件module.exports的配置:
entry: {
app: ['babel-polyfill','./src/main.js']
},
登录状态路由拦截
一般系统都会有对所有需要权限控制的路由进行拦截,确保登录状态下才能访问某些路由这类需求。利用vue-router提供的钩子函数beforeEach()可以很简单的实现。
- 第一步:定义路由是否需要拦截
首先在定义路由的时候就需要多添加一个自定义字段requireAuth,用于判断该路由的访问是否需要登录。
{
path:'/xxx,
meta: {
requireAuth:true, // 添加该字段,表示进入这个路由是需要登录的
},
component:xxx,
redirect:'/xxx/xxx,
children: [{
meta: {
requireAuth:true,
},
path:xxx/',
component:xxx
}
}
- 第二步:使用钩子函数beforeEach()拦截路由
// 全局导航钩子
router.beforeEach((to, from, next) => {
if (to.meta.requireAuth) {
getCurrentUser().then((curUser)=>{//getCurrentUser是封装的调用后台http接口的promise接口
if (curUser) {
next();
} else {
next({
path:'/login',
query: {
redirect:to.fullPath //登录页面获取该参数,在重新登录后重定向到该路由
}
})
}
}).catch((err)=>{
next({
path:'/login',
query: {
redirect:to.fullPath
}
})
});
} else {
next();
}
})
每个钩子方法接收三个参数:
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next(‘/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。