像咱们平日里作惯了 Java 或者 .NET 这种后端程序员,对于前端的认识还经常停留在 jQuery 时代,包括其插件在须要时就引用一下,不须要就删除。故观念使然,尽管 Nuget 和 Maven 用得顺溜,但对 NPM 仍不带感,兴许是周边无人带动的稀薄气氛,也或者是没参加过相似的大型活动,因而在自发性上差了许多。再者,我不用 MVVM 模式,领导也不会扣绩效。javascript
为了快速体验 MVVM 模式,我选择了非工程化方式来起步,并选择使用 Vue.js,以及基于它构建的 iView UI 框架。css
Vue.js 是美籍华人尤雨溪创做的,那会儿他还在 Google 工做,他自感 Angular.js 繁杂,进而自创了更为简洁易用的 Vue.js。html
iView UI 是由 90 后梁灏[hào]创做,网名 Aresn,在大数据公司 TalkingData 负责可视化基础架构,更了不得的是他还出了《Vue.js实战》一书,我是在“双十一”的前一天买的,行文措词简洁,表意直达困惑,入门很迅速,是我喜欢的风格。花了一周时间扫完了前十二章内容,用 WebStorm 练习了大部分实例,尽管书中用一整章内容介绍了 webpack 工程化构建方案,但因为我惯性使然,仍是选择对其跳过而使用了非工程化方式来体验 Vue.js,其实多少有失暴殄。无奈,毕竟才学了一周,后期时间充裕了再接着分享工程化构建的学习心得吧。前端
Vue.js 比较显著的特征是解耦了视图和数据,也就是说视图的变化再也不须要命令式编程去显式改变,只要修改完数据就能当即自动同步,这是比较大的一个思惟模式的转变,另外一个就是组件化思惟俯首皆是,这样开发一个应用就至关是在搭积木。vue
其实以上对 Vue.js 所阐述的优势也正是 MVVM 模式的写照,它原是由 MVC 所衍生,即当视图层发生变化时,会自动更新到视图模型上,反之亦然,这就是常说的双向绑定,上一张图吧:java
甭管这图是否好理解,通俗地来说,MVVM 这种模式拆分了视图和数据,这样咱们在开发时只要关心数据自己便可,而后视图 DOM 这方面会由 Vue.js 自动解决。webpack
为了能支撑起一个最基本的应用,须要引入如下几个必要文件:git
来到 Github 上的 Vue 项目,直接下载 Zip 源码:程序员
在 dist 目录中就能够找到 vue.js 文件:github
根据不一样的环境选择一个版本便可,至此第 1 步就搞定了。
在 iView 官网的“组件” / “安装” 页面的开头处发现了这个连接:https://unpkg.com/iview/ ,经过它能够查看到 dist 目录:
必要文件都在这里,这些文件没法打包下载,我采起的笨办法是逐个点开,而后复制其中的内容。
在获取 iView 相关的 js 和 css 方面还有一个办法,仔细观察官网给出的 CDN 地址分别为:
我尝试将它们放在浏览器里进行访问:
发现地址有变动,不过这并没有大碍。
至此,将各个文件放在指望的位置便可:
该图中各文件的摆放并非很严谨,你们按本身习惯来便可。
完成以上的准备工做后,就能够结合 iView UI 来正式开发了,接下来基于 table 表格组件演示一下购物车的基本操做。
通过起步工做的筹备,能够在新建页面中逐个地引入这些资源。
<head> <meta charset="UTF-8"> <title>购物车实例</title> <link rel="stylesheet" href="iViewContent/iview.2.7.0.css"> <script src="utility_js/vue.min.2.5.3.js"></script> <script src="utility_js/iview.min.2.7.0.js"></script> <script src="iViewContent/locale/zh-CN.js"></script> <script> iview.lang('zh-CN'); </script> </head>
按一向的方式引用,样式居前,随后紧跟着 vue.js 和 iView.js,以及 iView 中文语言包 zh-CN.js,而后当即调用 lang 方法使其生效。
首先把数据绑定起来,从而看一看总体效果,至于其余的行为操做先无论:
<body> <div id="app"> <i-table id="datatable1" size="small" :columns="columns" :data="cartList" stripe highlight-row> </i-table> </div> <script src="iViewUI_cart.js"></script> </body>
组件 i-table 最核心的两个属性分别是 columns 和 data,columns 是列定义,data 则为数据。
这两个属性都添加了冒号(:)语法糖,它指代的是 v-bind 指令,表示这个属性的值是动态绑定的,这样在运行过程当中发现数据有变动时,表格视图也会迅速的变动。
var cart = new Vue({ el: '#app', data: function () { return { cartList: [ {id: 1, name: 'iPhone X', price: 8300.05, count: 1}, {id: 2, name: 'MacBook Pro', price: 18800.75, count: 3}, {id: 3, name: 'Mate 10 Porsche', price: 16600.00, count: 8} ], columns: [ { title: '名称', key: 'name' }, { title: '单价', key: 'price' }, { title: '数量', key: 'count' } ] } }, methods: {} });
该文件是与页面对应的业务脚本,整个文件就负责 new 一个 Vue 实例,并将其赋值给了变量 cart,能够看到的 data 包含了两个属性,即表示数据源的 cartList 和 列定义的 columns,两者正好与上述 i-table 的核心属性相映射。
再次值得注意的是 data,它的值须要以匿名函数的形式进行书写,即:
function () { return {} }
如此,在其 columns 中出现的 Render 函数体内才能正常经过 this 访问到 methods 中定义的方法。固然本次演示是经过 cart 对象来访问,故不受此影响。
运行页面后,数据便可绑定成功。
数据呈现出来后,就能够补充必要的按钮了:
这一步简单,只须要修改一下 columns 属性,追加一项“操做”列,添加三个按钮:
{ title: '数量', key: 'count' }, { title: '操做', render: (h, params) => { return h('div', [ h('Button', { props: { type: 'primary', size: 'small' }, style: { marginRight: '5px' }, on: { click: () => { console.info('减小数量'); cart.reduceQuantity(params.row.id); } } }, '-'), h('Button', { props: { type: 'primary', size: 'small' }, style: { marginRight: '5px' }, on: { click: () => { console.info('增长数量'); cart.increaseQuantity(params.row.id); } } }, '+'), h('Button', { props: { type: 'error', size: 'small' }, style: { marginRight: '5px' }, on: { click: () => { console.info('删除当前项'); cart.deleteItem(params.row.id); } } }, '删除') ]); } }
在这里使用到了 Render 函数,该函数的内部机制略显复杂,做为初步演示只需依样画葫芦便可。
说到 Render 函数,还须要再强调一下在其内部对 methods 中所定义方法的调用,若是试图经过 this 来调用方法(好比 reduceQuantity),那么 Vue 实例中 data 的值须要使用匿名函数的方式来表达;反之,如果经过 Vue 实例 cart 来调用,则无此顾虑,即 data 的值使用一向的对象大括号({})来表达便可。
操做按钮已经添加成功了,那就须要有对应的方法去执行,在 Vue.js 中,方法都定义在 methods 属性中。
首先关注一下“减去数量”的定义:
methods: { reduceQuantity: function (id) { for (let i = 0; i < this.cartList.length; i++) { if (this.cartList[i].id === id) { this.cartList[i].count--; break; } } } }
经过遍历找到目标记录,并将其 count 属性减一,如同 MVVM 的定义,当数据变动的时候,视图也跟随着变化。
但凡是存在于购物车内的商品,其数量至少应该为 1,为防止减到 0,不妨再加一个判断使其逻辑更为完美:
methods: { reduceQuantity: function (id) { for (let i = 0; i < this.cartList.length; i++) { if (this.cartList[i].id === id) { if (this.cartList[i].count > 1) { this.cartList[i].count--; } break; } } } },
methods: { increaseQuantity: function (id) { for (let i = 0; i < this.cartList.length; i++) { if (this.cartList[i].id === id) { this.cartList[i].count++; break; } } } }
只须要针对 count 属性作 +1 操做便可。
deleteItem: function (id) { for (let i = 0; i < this.cartList.length; i++) { if (this.cartList[i].id === id) { // 询问是否删除 this.$Modal.confirm({ title: '提示', content: '肯定要删除吗?', onOk: () => { this.cartList.splice(i, 1); }, onCancel: () => { // 什么也不作 } }); } } }
在删除逻辑中,当遍历到目标记录时,会询问用户是否真的要删除当前记录,这里用到了 $Modal 对话框,若是用户点击肯定,那么就执行真正的删除,看一看效果:
很是漂亮考究的 iView Modal 对话框,使人赏心悦目,一见钟情。
至此,针对 Vue.js 和 iView 框架的体验就告一段落,后面抽时间再学习一下组件和 Render 函数,提高一下内功修养。