Vue + iView + vuex + vee-validate 完整项目总结
部门最近的一个新项目启动,很幸运由我来主导整个前端部分的技术选型和整体架构,项目工作量很大,但是却没有足够的人手,只有三个连CSS都不太会的实习生跟着我一起做,压力山大。两个月以来,虽然遇见了很多问题,但是最终顺利的解决了,项目基本完成,果断写一篇总结,毕竟是第一个真正意义上全权自己负责的大项目 。
一、技术选型。
如果没有接触过新的知识,我可能会像之前的部门的所有项目一样,按部就班的使用Jquery + bootstrap + sea.js/require.js 进行开发,但是我说了NO。
首先,这次项目初步估计有近百个功能点和几十个页面,如果仍用jquery的方法,光是臃肿的dom操作代码就把人写的筋疲力尽了,而且我自己本人也是在是厌倦了重复而乏味DOM操作。所以我选择了Vue, 至于为什么不是react和anglar, 相对于他们Vue我觉得对于新手来说是很容易上手的,相对于react一些相关的技术栈,Vue对于实习生更容易掌握。使用Vue我只需要把项目共用的模块封装成共用组件,让他们去调用就可以了,这一点保证了他们很少去写CSS样式,也为项目快速的开发完成起到了一定的决定因素。
最终使用的技术如下:
基础JS框架: Vue, 基础样式和组件框架: iView ,国际化插件: vue-i18n,表单验证插件:vee-validate
项目打包工具:webpack + babel
代码规范性检查: eslint
二、项目过程中遇见的问题。
这部分其实是我写这篇博客的主要目的,好多问题,毕竟总结更多的是去记录过去遇见的问题和走过的弯路。
1、旧的JS代码的兼容。
由于项目中有一部分的代码是之前的项目组使用的seajs封装的模块,而且这部分代码内部的逻辑比较复杂,重写基本是不可能的,没时间何精力去研究,只有通过引入到我们的webpak工程中,如何把这部分代码挪过来并且很少改动就成了一个大问题。很幸运,webpack直接支持AMD或CMD的代码,我用的vue-cli初始化的项目,所以更改了一些webpack.base.config里的一些配置,但是忍让需要修改一些配置让原来js里的require能够找到原来的模块并执行。
新建了一个oldModuleConfig.js,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | const path = require( 'path' ) function resolve (dir) { return path.join(__dirname, '..' , dir) } const oldModuleConfig = { 'vue$' : 'vue/dist/vue.esm.js' , '@' : resolve( 'src' ), /* Switch EWeb */ 'oldModule1' : resolve( 'src/oldModule1' ), 'oldModule2' : resolve( 'src/oldModule2' ), 'oldModule3' : resolve( 'src/oldModule3' ), 'oldModule4' : resolve( 'src/oldModule4' ), } module.exports = oldModuleConfig |
然后修改了webpack.base.config.js
1 2 3 4 5 6 7 8 9 | resolve: { extensions: [ '.js' , '.vue' , '.json' , '.less' ], /** alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src') } **/ // 将原来的这部分改成这样 alias: oldModuleConfig } |
这样原来的module1里面如果写了require就可以直接使用了
var module2 = require('module2') //这行代码如果没有配置直接引入就找不到module2这个模块,而配置alias之后就可以运行了
这是本人自己想到的略low的方法,如果有高人指出可以在webpack里引入旧的seajs/requirejs代码其他方法,欢迎指出。
2、原有代码无法通过eslint语法检查
原来的代码虽然引进来了,但是却无法通过eslint的检查,这个问题我是直接选择忽视原有文件的检查,如果你是用了vue-cli构建的项目,可以修改.eslintignore
1 2 3 | build/*.js config/*.js src/oldCodeFolder //旧代码的文件夹 |
3、Vue-router 页面刷新
如果用过vue-router的应该知道,如果点击的链接就是现在的页面,那么当前页面组件是不会刷新的,实际过程中可能希望再次点击页面是刷新一下。解决办法是使用一个中转页面bus,所有的页面跳转到这个bus.vue,然后由这个页面再调回原来的页面,这样就达到了刷新的效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <!-- 这是一个中转的页面,本身不具有任何内容,为什么要设置这个中转页面呢? 因为vue-router点击当前页面的链接时并不会刷新组件,为了保持再次点击刷新, 通过设置这个bus中转页面即可实现 --> <template> <div> </div> </template> <script> export default { data () { return {} }, methods: { jumpToPage () { let path = this .$route.params.path if (path) { this .$router.replace(path) } } }, mounted: function () { this .jumpToPage() } } </script> |
然后router-view里传入下一个即将跳转的页面路径即可
1 | <router-link :to= "{ name: 'bus', params: { path: nextPath }}" :key= "link.en" > {{ link.en }} </router-link> |
4、iView封装带分页的表格组件
iView提供了Table和Page两个组件,但是很蛋疼,没有提供带分页的表格组件,所以需要自己进行组合实现。这里提供示例代码,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | <template> <div class = "clear" > <Table :columns= 'columns' :data= 'showData' :ref= "refLabel" :loading= "loading" stripe :no-data-text= "'<span class=\'no-data-text \' > <i class=\'icon-no-data\'></i> ' + $t('message.nodata')+ '</span>'" ></Table> <Page :total= 'dataCount' :page-size= 'pageSize' :show-total= 'isShowTotal' :current.sync= "current" class = 'paging' @on-change= 'changepage' ></Page> </div> </template> <style scoped> .paging{ float:right; margin-top:20px; } </style> <script> export default { data () { return { ajaxHistoryData: [], // 初始化信息总条数 dataCount: 0, // 每页显示多少条 showData: [], current: 1 } }, props: { pageSize: { type: Number, default : 10 }, columns: { type: Array }, isShowTotal: { type: Boolean, default : true }, tableData: { type: Array }, refLabel: { type: String }, loading: { type: Boolean, default : false } }, methods: { // 获取历史记录信息 handleShowData () { if ( this .tableData && this .tableData.length) { // 保存取到的所有数据 this .dataCount = this .tableData.length // 初始化显示,小于每页显示条数,全显,大于每页显示条数,取前每页条数显示 if ( this .tableData.length < this .pageSize) { this .showData = this .tableData } else { this .showData = this .tableData.slice(0, this .pageSize) } } else { this .showData = [] this .dataCount = 0 } this .current = 1 }, currentChange (value) { }, changepage (index) { var _start = (index - 1) * this .pageSize var _end = index * this .pageSize this .showData = this .tableData.slice(_start, _end) } }, created () { this .handleShowData() }, watch: { tableData (oldVal, newVal) { this .handleShowData()<br> // 表格刷新了,当前页标识需要回到第一页的位置 this .current = 1 } } } </script> |
这里没有写异步获取数据的方法,所以具体使用时需要解渴自己的业务逻辑进行修改。
5、webpack打包体积过大,减少打包体积
说出来你们可能不信,我们的代码最终放在的服务器智能放下60M左右的文件,我也是很无奈,所以减少webpack打包体积就成了一个必须的问题。解决方法如下:
a、首先最直观的,将生产环境的sourceMap设为false ,这里设置完之后,打包后的文件就没有了.map文件,这一步基本减少了一大半的代码体积。
b、使用webpack-bundle-analyzer 优化你的代码
如果vue-cli构建的项目,只需要在package.json的scripts里加入:
1 | "analyz" : "set NODE_ENV=production && set npm_config_report=true && npm run build" |
然后运行npm run analyz, 打包成功后浏览器会自动打开类似下面的页面,找出其中共用写入Vendors, 然后使用webpack.optimize.CommonsChunkPlugin 进行优化
c、如果你们有CDN的话,尽量把基础代码如: vue , vue-router 放在CDN上面
d、tree shaking 去除无用的代码
6、其他
其实还有许多大大小小的问题,比如Vue的路由拦截,webpack多页面,DDL优化打包速度,覆盖iVIew组件,nginx代理,组件scoped样式覆盖不了iView默认样式等等许多,每一个解决完了都有满满的成就感。
三、项目构建问题回顾
1、代码初期没有架构合理,导致后期存在一些维护上的问题。
比如,代码引入了SASS,开始没有设置一个主题的公共文件,导致后面设计变动整体主题跟着发生了一些改变,虽然iView支持更改主题,但是自己写的一些组件由于没有共用的主题文件,导致后期修改比较麻烦。
2、代码没有review
虽然代码整体风格使用了eslint去规范了,但是其实真正开发的时候发现三个兄弟的代码很不规范,毕竟工作经验不足,包括变量的大小写,css类命名,甚至在页面里使用了Jquery等问题,一开始没有review, 后期仔细阅读他们的代码的时候才发现这些问题,然后才进行修改。其实这些问题在项目开始我就应该说明的。
3、其他
后续补充。。。
四、项目收获
整个项目在代码架构上还是获得了其他同事的认可,至少推动了部门前端向前走了一步,我算是部门第一个吃螃蟹的人,敢于把新技术果断使用到新的项目里,第一次将webpack + vue的技术栈整体运用了一遍,虽然不能说精通,但是应该也是熟练掌握了,总觉得自己平日所学没有白费,实践应用了一遍满满的收获。
2018 继续前行。
喜欢的话可以点个推荐或者关注哦!
注:本文出自博客园 https://home.cnblogs.com/u/mdengcc/ ,转载请注明出处。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验