Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架,是当下很火的一个 JavaScript MVVM 库,是以 数据驱动和组件化 的思想构建的。
当创建了 ViewModel 后,双向绑定是如何达成的呢?
首先,我们将上图中的 DOM Listeners 和 Data Bindings 看作两个工具,它们是实现双向绑定的关键。
在这里我们需要稍微注意一下前端 库(Library) 和 框架(Framework) 的区别,它们的本质都是某人编写的,用于解决常见问题的 可复用代码 的集合。
比如,你有一个处理字符串的程序,你为了保持代码的 DRY (Don't Repeat Yourself),你编写了如下可复用的功能代码:
恭喜你,你创建了一个 JavaScript 库!
如果我们用 「构建房子」 来类比 「构建应用」 的话,那么 使用库 就像是 去宜家购物 一样,我已经有了一个家,现在我需要挑选自己喜欢的一些家具,以达到我自己满意的状态,这一切 都在我的控制范围之内;而 使用框架 就会像是已经有了一个 清装房,在已经规划好的蓝图和选择之中,我们的一些想法会显得十分地有限。
更加详细的解释如下:
说实话,我个人非常喜欢 Vue。在我大学刚尝试学习 HTML + CSS + JavaScript 和 Bootstrap 融合之后,我就接触了 Vue,它对我来说这样的「前端小白」来说,几乎没有什么开发的门槛,很平滑地就得以过渡到 Vue 的使用中去。
B 站翻译版本截图
Vue 从一开始的定位就是尽可能的降低前端开发的门槛,让更多的人能够更快地上手开发。———— 尤雨溪
可以看到几乎没有多余的部分,只是在创建 Vue 实例时,把 id 为 app 的对象 (此处为一个 div) 绑定到了 Vue 实例中而已。
由于 Vue 是国人编写的,所以在官网中有完整的中文文档可供开发者参考,并且借由尤大大出色的文笔,非常地清晰易懂,相信看过的朋友会和我有一样的感受:
将 message 绑定到文本框,当更改文本框的值的时候, <p>{{ message }}</p> 中的内容也会被更新:
反过来如果我们更改 message 的值的话,文本框的值也会被更新,我们可以在控制台中尝试一下:
说了这么多,无非是希望大家能停下来想想所谓的 ”A 技术比 B 技术牛逼“ 背后到底是在争些什么,我们使用这些技术的初衷又是什么。很多时候你说这方面,他说那方面,鸡同鸭讲,即使说到一起去,也往往缺乏对等的信息量或者基础共识,只是各自表达主观看法,最后变成两个阵营各自抱团取暖... 说到底,就算你证明了 A 比 B 牛逼,也不意味着你或者你的项目就牛逼了... 比起争这个,不如多想想怎么让自己变得更牛逼吧。—————— 尤雨溪
上面我们已经实际体验了一个 Vue 的指令 v-model 了,在 Vue 中,指令都带有 v- 前缀,以表示它们是 Vue 提供的特殊的 attribute,它们会在渲染 DOM 时进行特殊的响应式行为。
Vue 内置了一些常用的指令,接下来我们将依次来介绍:
v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。例如:(vue-tutorial/v-if-demo)
页面会正确的显示「现在你看到我了!」这几个字。
你也可以使用 v-else 来添加一个 "else 块" 来表达条件不满足时应该渲染的模块:
此时条件 seen 不满足,页面就会显示「Oh no!」的字样。
这是 2.1.0 版本新增的指令,充当 v-if 的 "else-if 块",可以用来连续判断条件:
类似于 v-else,v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。
另一个用于根据条件展示元素的选项是 v-show 指令。用法大致一样:
不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display (条件不满足则把元素 display 属性设置为 none),而 v-if 则在条件不满足时直接不渲染出对象。
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是 惰性 的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
结果:
我们可以传给 v-bind:class 一个对象,以动态地切换 class:(也可以用缩写 : 来替代 v-bind 指令)
上面的语法表示 active 这个 class 存在与否将取决于数据属性 isActive 的 truthiness。
你可以在对象中传入更多属性来动态切换多个 class。此外,v-bind:class 指令也可以与普通的 class 属性共存。当有如下模板:
和如下 data:
结果渲染为:
当 isActive 或者 hasError 变化时,class 列表将相应地更新。例如,如果 hasError 的值为 true,class 列表将变为 "static active text-danger"。
可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。(也可以用缩写 @ 来替代 v-on 指令)
示例:
结果:
image
上面我们了解了一些基本的指令了,接下来我们实际动动手,来搭建一个简单的 TodoList demo 小程序。
TodoList 想必大家都很熟悉,使用来记录我们接下来要做的一些事情的程序,最基本的功能有增加和删除:
很简单,可以看出我们只需要一个输入框 (用来记录将要保存的数据),一个按钮 (用来添加数据),和一个集合 (用来保存数据) 就差不多可以了,上手!
先来创建好我们需要的数据 data:
这里多定义了 id 属性是为了方便我们的删除操作。
没有任何布局,就直接定义好我们所需要的组件就好了:
没有任何的特别,只是里面包含了两个我们 未定义 的方法:addItem 和 removeItem 而已。
Vue 中的方法需要定义在 Vue 实例的 methods 关键字下面:
这里数组的更新需要用到 push,另外删除时我们使用了一个 lambda 表达式来完成,删除时传入了一个要删除元素的 id,然后从数组中挑选出所有 不等于 这个 id 的元素重新赋值给原数组,这样就相当于是删除了元素了。
本文涉及的所有代码都上传到了【More Than Java】项目中。(地址下方)