Vue全家桶实践项目总结(推荐)

从前端的角度看,Vue可以说是目前最理想的前端MVVM框架,一切为界面服务,上手难度低,本文就将记录使用Vue全家桶(Vue+Vue-router+Vuex)重构一个jQuery+template项目的过程,以及期间的收获。

入门

Vue的官方文档就是学习Vue的最佳教程,没有之一,可能因为框架作者是设计出身,没有后端背景,因此各种抽象概念在Vue里都得以用最容易理解的方式被恰到好处的阐述,这里只简单介绍Vue、Vue-router、Vuex的概念,要全面学习建议去官方文档。

Vue

Vue的核心功能是双向绑定,可以自动实现界面驱动数据变化和数据驱动界面变化,这能极大降低前端富交互应用的开发成本。同类框架不止Vue一个,但Vue的实现借助ES5原生特性,在性能方面有一定优势。

Vue-router

Vue-router是官方路由,用来组织url和组件间的映射关系,并自动将url的变化响应到组件中去,使开发者只需将关注点放在组件开发上,路由帮你解决相关的琐碎问题。

Vuex

Vuex提供一种集中式的数据管理模式,用以应对数据流向复杂的情况,比如多个组件共用数据却各自为营,可能导致该同步的数据没有同步,或者由于js中Object对象的钩子在内存里指向同一实例,导致一旦操作原数据就会污染到其他组件,这时就需要一套更有条理的数据操作模式,那就是Vuex。

技术选型

跟jQuery对比

在了解了Vue的基本概念之后,肯定会不自觉的拿他们跟jQuery技术栈做对比,想知道这些东西对我的业务是否真的有必要。

首先MVVM解决的问题能不能用jQuery解决?答案是肯定的,还记得最初做表单提交时用jQuery从一个一个的input里取值吗?这就是界面驱动数据;如果做过任何异步交互功能的话,应该都有过用jQuery将Ajax数据填充到界面中各个元素里的经验,这就是数据驱动界面。虽然能做,但有点繁琐,即便用上表单验证插件和前端模板引擎,也仍然需要在各个运行节点手动调用验证方法和渲染方法,做个网站页面还好,可当需求复杂到一定程度时,这将是很大的负担。

然后是路由,路由的本质是通过操作url实现界面切换和界面保持,单页面应用必备,这个其实跟技术栈没关系,只要产生了路由需求,即使是基于jQuery的项目也不过是再造了一个路由而已,只不过jQuery时代很少做单页面应用。

Vuex完全是基于双向绑定延伸出来的东西,相当于在数据和组件之间加了一个经纪人,组件不能直接操作数据,只能像经纪人提交操作需求,由经纪人去实施操作,以此解决人多手杂造成的各种不可预料的问题,并且数据被从应用中挪了出去,专门建立了一个Store,这样就杜绝了组件之间数据污染的问题。jQuery应该说不太会有这个需求,因为jQuery完全是手动操作数据,根本没有意料之外的情况。

适用场景

经过跟jQuery的对比之后,Vue的适用场景就很明显了,从开发角度讲交互越复杂的项目越适合,单页面最适合,内容类网站最不适合,如果网站中个别页面有需求也可以局部使用,例如购物车页面。

当然,这一切都要建立在不兼容IE8的前提下,对于这一点我有点疑惑,因为见到有些2C的站点都在使用Vue,这些前端er是怎么把老板忽悠瘸的?

项目分析

项目背景

这次重构的项目是为上一家公司开发的前端组件管理系统,选择重构这个项目是因为对需求比较熟悉,这是一个典型的单页面应用,而且复杂度适中,比较适合用作上手练习。

项目背景是外包类建站公司里,设计环节沉淀了大量可复用组件,设计师往往只需要微调组件就拼凑出页面,交付给前端,理论上这些组件在前端也可以复用,但实际上前端每次都要重新实现整个页面,浪费很多人力。

功能需求

这个项目的思路是,将所有组件开发出来,统一录入到一个平台上管理,设计师可以到平台上挑选组件,并实时预览和调整组件,整个过程所见即所得,平台会将调整结果生成一串代码,只要将代码交给前端,就可以用这串代码在平台上重现设计师修改后的组件,并能一键复制组件的html/css/js代码,快速应用到项目中去,使组件部分的前端开发成本接近于零。平台需要实现以下几个功能:

  1. 管理组件,支持分类、搜索、排序
  2. 展示组件,支持组件在线预览/编辑
  3. 组件交接,支持生成组件代码和基于代码重现组件
  4. 使用统计,支持统计组件的使用情况,便于进一步优化组件

功能分析

第一版是用jQuery+template实现的,这个技术栈太灵活了,优点是什么需求都好做,缺点是怎么做都行,不利于理清思路,往往伴随着边做边改。

组件被统一放在一个widgets/文件夹里,被称作组件库,因为是纯前端项目没有文件操作能力,因此组件的读取依赖一个静态json文件,这个文件充当组件库的目录,其中包括组件分类、标签、名称、日期等所有信息,数据结构大概是这样:

[{
 "title": "导航类",
 "list": [{
 "widget": "bread-1",
 "title": "图标面包屑",
 "tag": "面包屑/图标",
 "author": "UI",
 "date": "2015-06-04"
 },
 ...]
},
...]

组件在组件库中以栏目/编号二级文件夹的形式存放,同时约定用存放目录作为组件代号,例如组件bread-1意味着该组件存放地址是widgets/bread/1/文件夹。

当然组件的内部文件结构也必须约定下来,如下:

widgets
  |-bread
    |-1
      |-album.jpg   //缩略图
      |-config.json  //配置文件
      |-script.js   //脚本模板
      |-style.css   //样式模板
      `-temp.htm   //界面模板

有了这些约定,程序就可以通过目录文件得到所有组件的信息,组件的获取、展示、检索也就可以实现了。

组件里最关键的是config.json文件,这里面包含该组件的可配置项及其默认值,平台在展示组件时会读取这个配置文件,根据配置信息生成配置面板,这里面可以定义组件界面、样式、脚本中的所有变量,配置文件大概长这样:

{
 "cssConfig": {
 "fontSize": {
  "name": "字号",
  "value": "12px",
  "type": "text"
 },
 ...
 },
 "jsConfig": {
    ...
 },
 "showConfig": {
 "viewWidth": {
  "name": "栅格宽度",
  "value": 12,
  "type": "number"
 },
 ...
 }
}

配置文件里的cssConfig、showConfig、jsConfig三个分支,就是组件中所有可以修改的变量集合,想将这些变量应用到组件上,需要借助前端模板引擎,所以组件的三大件在开发的时候是用模板语法写的,经过模板引擎的解析,就能得到配置后的实际html/css/js内容,例如样式模板大概是这样的:

.widget-bread-1 {
  font-size: ${fontSize.value};
  color: ${textColor.value};
}
.widget-bread-1 a {
  color: ${textColor.value};
}
.widget-bread-1 a:hover{
  color:${hoverColor.value};
}
.widget-bread-1 .ion {
  font-size: ${iconSize.value};
  margin: 0 ${iconMargin.value};
}

在得到组件实际代码后,只要将结果插入页面中并适时更新就行了,其中HTML和css可以直接替换文本内容,js因为是模块化引入的,只替换模块内容不会重载模块,必须将整个模块重命名后进行整体替换,因此js模块的名称是随机的。

这里会有一个问题,有的组件需要在页面里多次使用,那么这个组件的js选择器就会发生冲突,这个问题的解决正好可以借助js模块的那个随机名称,我们约定在组件开发中id作为保留变量,由平台自动赋值一个随机字符串,这个字符串在组件实例内部相同,多次调用则不同,这样只要将${id}作为组件父节点的id或class,就解决了选择器冲突问题,同时也可以作为组件的css命名空间,使可能发生的css命名冲突也解决于无形。

以上是项目核心功能。

此外还用localStorage作为存储方式实现了单机版的数据统计,可以收集当前浏览器的组件使用记录,以及每个使用时的配置情况,这里主要是对本地存储的操作,但是项目自身的开发也用到了前端模板,加上组件的模板,都会在第一次加载后用localStorage缓存起来,这些内容的缓存策略不同,用户数据应该是永久存储,项目模板应该可以手动更新,组件模板需要视情况而定,存储的内容多了就需要清理,清理的时候一条一条的去删除就不现实了,全部删除可能误伤其他应用的存储,这里的做法是将localStorage操作封装,存储方法会在在key前加上一个特殊前缀,删除时只要遍历本地存储的key并且判断是否匹配前缀就知道是否是应用内的存储了,对应的取值方法也要逆向的先给key加上前缀再去取值。

另外localStorage是只支持字符串存取的,为了方便我们存取对象类型,封装方法还支持自动转换,但这个转换还不能是盲目的遇到对象就转字符,取值的时候匹配到可以转对象就自动转了对象,因为有时候用户可能真的就存了一个对象字符串进去,取出的时候也希望原样拿回来,要解决这个问题需要做一个小hack,当存储方法检测到值为对象时,会转成字符串然后在前面拼上一个标识字符串,取值方法只有在检测到这个标识后才会将后面的字符串还原成对象,这种方式虽然可以满足需求,但不是很保险,因为这个前缀是固定的,理论上总是有可能遇到中奖的,不知道这个问题还有没有其他的更优解。

项目的主要功能点就是这些。

重构

一次重构

第一次重构只用了Vue,重构过程中首先体会到的是各种便捷,本来要调用模板引擎做的事框架顺便就做了,本来要在js里绑定事件现在模板里直接可以绑定,还有其他各种语法糖。

当然,最重要的还是双向绑定,基于双向绑定可以让界面和数据自动的关联起来,让人感觉程序具有了一定的自主能动性,但为了让这种自主性正常运转,开发者必须事先规划好每一步路,这相对jQuery来说就会显得不那么自由。拿搬砖头举例,jQuery好比一个特别灵活的起重机,可以举重若轻,可以花式搬砖;Vue则像一个万能遥控器,你告诉他你要把砖头从某地搬到某地,期间发生什么情况要如何处理,按动按钮就可以自动搬砖了。

两种方式各有优劣,起重机开的好可以很灵活,路上遇到坑容易躲避,缺点是你要一趟一趟的开它;按钮可以一次编程自动运行,缺点是你必须事先把路上的坑实地考察好,把别的车全部调度好,所有的情况说清楚,否则就会翻车或撞车,从jQuery转到Vue一定会感觉到这种束缚感,逼的你必须”谋而后动”,不能先上车再说。

重构期间很大一部分工作就是建立Vue实例,将散布在js各个角落的数据收集到data中去,将操作数据的过程一点一点的集中到methods中去,将数据的筛选过程集中到computed中去,这整个过程可以清晰的回顾每一个实现细节,反思每一个实现方式是不是合理,其实也就是将原来开起重机的过程归纳成一个一个的遥控器按钮,当全部归纳完成后,Vue示例也就变成了最终我们的项目,能够自动运行。

经过重构,依托Vue的各种功能使逻辑部分的代码量减少了,除此之外对项目本身来说并没有什么改进,因为没有路由所以刷新页面状态丢失问题仍然存在;因为没有使用Vuex还遇到一个数据污染的坑,只能用深拷贝解决;并且基于组件的开发模式,让代码组织更零碎了,这些问题都需要二次重构。

二次重构

二次重构目标是完善路由、Vuex、代码组织、野狗云后端。

虽然有了第一次重构的经验,但二次重构一开始还是有点茫然,路由和Vuex应该先上哪一个?想了想,路由做的事是”拆”,Vuex做的事是”改”,感觉改完再拆的工作量会小一点,所以先上Vuex。

Vuex的概念凭空理解有点抽象,一旦用上却觉得的得心应手,而且这个东西不像路由,几乎不需要区分场景都可以用,引入Vuex后数据污染的问题自然就解决了,而且Vuex带来的 action => mutation => store 流程一旦接受了真的会让事情变简单,引入Vuex的过程基本就是将data转移到store,将数据操作分散到actions,getters,mutations中去,同时很多同步数据操作都不需要了,从而使代码量又减少了一些。

之后开始引入路由,一开始拿不准应该怎么划分视图,大的视图肯定是登录、注册、主界面,问题是主界面需不需要再细分,理论上可以分的很细,但结合应用实际使用场景发现,界面的切换相对频繁,组件频繁载入和卸载的开销会很大,而且将耦合紧密的组件拆到不同的视图,需要记录很多状态信息,有点得不偿失,最终作罢,没有将主视图继续分下去。考虑到三个视图的访问重叠性不高,自然就需要将组件做成异步加载,只在访问到的时候才加载组件,Vue自身支持异步组件,所以这件事变得非常简单,只要能返回一个Promise,你可以使用任意方式获取组件。

接下来要接入野狗云,实现真正的用户管理和数据统计,野狗云可以提供用户鉴权和数据存储等一系列功能,通过它只需要用js就可以开发一个完整的WEB应用。这样之前所有对localStorage的操作都要改成对野狗云的操作,数据到了云端也变得更可靠了。

至此二次重构就完成了,业务代码总体感觉减少了很多,但总代码量估计没少多少,毕竟还增加了三个框架文件,不过经过重重拆分,文件数量从当初的三两个js变成了十来个js,模块化方面用的seajs而不是webpack,因为个人对 webpack仍然持观望态度,目前还感觉不到用它的必要性,关键是基于webpack开发的代码会夹杂很多私货,让你的代码变得不原生,离了他就运行不起来,这个我不太能接受,而且在多页面场景seajs配合本地缓存比webpack更有优势,当然了,他们的的区别就跟jQuery和Vue的区别一样,本质不是一个东西,关键在于使用场景,适合的就是最好的。

后记

经过两次重构的实践和踩坑,对Vue框架有了更深刻的认识,Vue想要用的灵活自如,对开发者的项目架构能力有一个最低要求,如果要将Vue引入底层,对基础设施建设者的规划能力也有一个最低要求,这些都是jQuery技术栈所不存在的,使用Vue的过程也是接受这些约束的过程,他们能引导开发者建立自己的规则体系,这是好事也是大势所趋,毕竟真正的自由只存在于规则中。

本文的完整代码见Github

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈Vuex的状态管理(全家桶)

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试.状态快照导入导出等高级调试功能. 以上是vuex的官方文档对vuex的介绍,官方文档对vuex的用法进行了详细的说明.这里就不再细讲vuex的各个用法,写这篇博客的目的只是帮助部分同学更快地理解并上手vuex.

  • Vue全家桶实践项目总结(推荐)

    从前端的角度看,Vue可以说是目前最理想的前端MVVM框架,一切为界面服务,上手难度低,本文就将记录使用Vue全家桶(Vue+Vue-router+Vuex)重构一个jQuery+template项目的过程,以及期间的收获. 入门 Vue的官方文档就是学习Vue的最佳教程,没有之一,可能因为框架作者是设计出身,没有后端背景,因此各种抽象概念在Vue里都得以用最容易理解的方式被恰到好处的阐述,这里只简单介绍Vue.Vue-router.Vuex的概念,要全面学习建议去官方文档. Vue Vue的核

  • 全面介绍vue 全家桶和项目实例

    简介 "简单却不失优雅,小巧而不乏大匠". 2016年最火的前端框架当属Vue.js了,很多使用过vue的程序员这样评价它,"vue.js兼具angular.js和react.js的优点,并剔除了它们的缺点".授予了这么高的评价的vue.js,也是开源世界华人的骄傲,因为它的作者是位中国人–尤雨溪(Evan You). Vue.js 是一个JavaScriptMVVM库,是一套构建用户界面的渐进式框架.它是以数据驱动和组件化的思想构建的,采用自底向上增量开发的设计.

  • Vue 全家桶实现移动端酷狗音乐功能

    Vue 已经用了不少时间,最近抽空把以前的未完成的酷狗音乐做完了,过来分享下,也可以直接点这里预览,注意切换成手机模式. 技术栈: vue-router.eventBus.vuex.vue-awesome-swiper 整体功能 vs 酷狗官网: 总体模拟官网,原来的亮点保留,如: 图片懒加载 除此之外,增加了 加了全局的 Loading 组件,根据不同页面调整 Loading 尺寸 搜索页面做了优化,可以在刷新时保留之前的搜索结果 播放页面单独做了一个路由,可以在刷新时保留当前歌曲页面 播放器

  • Vue全家桶入门基础教程

    1. Vue概述 Vue(读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用. 渐进式: 声明式渲染→组件系统→客户端路由→集中式状态管理→项目构建 可以使用其中的一个或者多个 优点: 易用:熟悉HTML,CSS.JavaScript知识后,可快速上手Vue 灵活:在一个库和一套完整框架之间自如伸缩 高效:20kB运行大小,超快虚拟DOM 2. Vue的基本使用 2.1 传统开发模式对比 /

  • vue全家桶-vuex深入讲解

    目录 使用 index.js getters.js system.js 全局使用:main.js文件中 Vuex概述 Vuex中的核心特性 A.State this.$store.state.全局数据名称-组件访问State中的数据的第一种方式 组件访问State中的数据的第二种方式:按需导入 B.Mutation this.$store.commit是触发Mutation的第一种方式 触发Mutation的第二种方式,按需导入 C.Action this.$store.dispatch()是触

  • Vue组件通信实践记录(推荐)

    组件通信 几乎所有的mvvm框架中都要涉及组件通信的功能(吐槽一下knockout,毕竟是鼻祖就先不说它了).而且目前的前端形式来看,组件化是一个项目的基础.所以选好一个合适的框架后,随着组件的不断增加,业务的复杂度提升,组件之间的通信变得尤为重要. 实践方法 由于更换新的框架,我们的项目由Avalon更新成Vue.但是为了兼容以前的业务代码,不能直接使用vue的标准实践方式,我还是拿过来后封装了一个vue的class,具体业务里面不影响使用,封装的过程之后写出来再聊吧,下面来总结一下最近用到的

  • vue项目搭建以及全家桶的使用详细教程(小结)

    前言 vue是现阶段很流行的前端框架,很多人通过vue官方文档的学习,对vue的使用都有了一定的了解,但再在项目工程化处理的时候,却发现不知道改怎么更好的管理自己的项目,如何去引入一些框架以及vue全家桶其他框架的使用,以下将详细地介绍本人在处理工程文件构建的过程:对于刚开始解除vue的新手,建议使用官方脚手架vue-cli,当然,如果你对于webpack很熟悉,你也可以自己动手搭建自己的脚手架,当然如果你没把握的话,还是推荐使用vue-cli,能更好的帮助你搭建项目: 步骤一.安装vue-cl

  • 使用Vite+Vue3+Vant全家桶快速构建项目步骤详解

    目录 引言 一.vue3全家桶模板介绍 1.版本依赖 2.全家桶内置集成 二.安装 tive-cli 命令行工具 三.生成项目 四.项目体验 引言 随着Vue3 和 Vite 版本的不断更新完善,开发体验有了质的飞跃.因此,越来越多的大厂也逐步拥抱 Vue3. 利用Vite 脚手架工具可以很轻松生成以 Vue3 为模板的项目,但是作为Vue全家桶的 vue-router.vuex.axios等成员,需要自己一个一个去配置.于是便自行开发了本文讲到的 tive-cli 脚手架模板工具,只需短短几个

  • Vue 3.0 全家桶抢先体验

    序 Vue 3.0 全家桶发布内容包括: vue: Beta vue-router: Alpha vuex: Alpha vue-class-component: Alpha vue-cli: Experimental support via vue-cli-plugin-vue-next eslint-plugin-vue: Alpha vue-test-utils: Alpha vue-devtools: WIP jsx: WIP 可以看到 Vue 3.0 beta 版本是一个项目系列,包含

  • 如何免费获取 Jetbrain 全家桶使用兑换码的正确姿势(推荐)

    自今年1月份以Jetbrain公司严厉打击旗下开发工具产品(如:IntelliJ IDEA.WebStorm.PyCharm等)的盗版破解以来.求新破解方式.分享新破解方法的帖子或信息经常可以在各技术社区或微信社群中看到. 大批 IDEA 激活码到期之后的乱象...一文中介绍了如何通过正常途径继续使用这些开发工具的三种方法. **学生免费:**JetBrains的全线产品对在校学生全部免费开放.所以,你只要有专属于学校的邮箱,就可以注册账号并免费使用它们. **开源免费:**如果您跟我一样,热爱

随机推荐