初探 Vue.js:MVVM 与组件化开发

零、前端发展简史

  1. 1989 年,HTML 诞生。最早的 HTML 页面是完全静态的网页,它们是预先编写好的存放在 Web 服务器上的 html 文件。浏览器请求某个 URL 时,Web 服务器把对应的 html 文件扔给浏览器,就可以显示 html 文件的内容了。
  2. 服务器需要针对不同的用户,动态生成不同的 html 文件。一个最直接的想法就是利用 C、C++ 这些编程语言,直接向浏览器输出拼接后的字符串。这种技术被称为 CGI:Common Gateway Interface。
  3. 像新浪首页这样的复杂的 HTML 是不可能通过拼字符串得到的。于是,人们又发现,其实拼字符串的时候,大多数字符串都是 HTML 片段,是不变的,变化的只有少数和用户相关的数据,所以,又出现了新的创建动态 HTML 的方式:ASP、JSP 和 PHP ——分别由微软、SUN 和开源社区开发。但是,一旦浏览器显示了一个 HTML 页面,要更新页面内容,唯一的方法就是重新向服务器获取一份新的 HTML 内容。
  4. 1995 年年底,JavaScript 被引入到浏览器,可以在浏览器中修改页面。JavaScript 还可以通过修改 HTML 的 DOM 结构和 CSS 来实现一些动画效果。

用 JavaScript 在浏览器中操作 HTML,经历了若干发展阶段:

  1. 第一阶段,直接用 JavaScript 操作 DOM 节点,使用浏览器提供的原生 API:
  2. 第二阶段,由于原生 API 不好用,还要考虑浏览器兼容性,jQuery 横空出世,以简洁的 API 迅速俘获了前端开发者的芳心:
  3. 第三阶段,MVC 模式,需要服务器端配合,JavaScript 可以在前端修改服务器渲染后的数据。(2015年某博文说:“原来的 jquery 时代类似于传统的汇编或者是 C 时代的编程,这个阶段已经不 work 了。”)
  4. 现在,随着前端页面越来越复杂,用户对于交互性要求也越来越高,想要写出 Gmail 这样的页面,仅仅用 jQuery 是远远不够的。MVVM 模型应运而生。

一、MVVM 模型

MVVM 是 Model-View-ViewModel 的缩写,它从 MVC 发展而来。

在前端页面中,把 Model 用纯 JavaScript 对象表示,View 负责显示,两者做到了最大限度的分离。把 Model 和 View 关联起来的就是 ViewModel。ViewModel 负责把 Model 的数据同步到 View 显示出来,还负责把 View 的修改同步回 Model。

一个 MVVM 框架和 jQuery 操作 DOM 相比有什么区别?

先看对比 demo

从 demo 中可以看出,如果使用 MVVM 框架来实现同样的功能,我们并不关心DOM的结构,而是关心数据如何存储。要把显示的 name 从 Bart 改为 Homer,把显示的 age 从 12 改为 51,我们并不操作 DOM,而是直接修改 JavaScript 对象。

这就是 MVVM 的设计思想:关注 Model 的变化,让 MVVM 框架去自动更新 DOM 的状态,从而把开发者从操作 DOM 的繁琐步骤中解脱出来!

二、Vue.js

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

Vue 是一个 MVVM 框架。主要用途:数据绑定、组件化开发。以下会逐步讲到。

Vue 核心与数据绑定

Vue.js 的核心是一个允许采用模板语法来声明式地将数据渲染进 DOM 的系统:

// html
<div id="app">
  {{ message }}
</div>

// js
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

基本语法

  • 声明式渲染,见上例
  • 用 v-bind 绑定属性
  • 条件(v-if)与循环(v-for)
  • 事件监听(v-on)
  • 双向绑定(v-model)

到官方文档 https://cn.vuejs.org/v2/guide/index.html 看相关示例,并实际操作一盘。

一个综合例子:购物车demo

组件化应用构建

组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。仔细想想,几乎任意类型的应用界面都可以抽象为一个组件树

Component Tree

在 Vue 里,一个组件本质上是一个拥有预定义选项 Vue 实例。简单例子:

// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
  template: '<li>这是个待办项</li>'
})

现在可以用它构建另一个组件模板:

<ol>
  <!-- 创建一个 todo-item 组件的实例 -->
  <todo-item></todo-item>
</ol>

提供一个 demo 链接

我看到这里的时候,有个问题:父子组件之间,如何通信?文档中有答案:1. 父->子:绑定子组件标签的属性;2. 子->父:父组件监听子组件的自定义事件。

在一个大型应用中,有必要将整个应用程序划分为组件,以使开发更易管理。这里有一个 (假想的) 例子,以展示使用了组件的应用模板是什么样的:

<div id="app">
  <app-nav></app-nav>
  <app-view>
    <app-sidebar></app-sidebar>
    <app-content></app-content>
  </app-view>
</div>

三、更多内容

以上介绍的,是 Vue.js 的核心与基础,但千万不要觉得 Vue.js 的内容仅此而已。本文只是一个开始。

篇首提到:

当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

学习 Vue.js,除了框架本身,更重要的是学习和运用它的整个生态系统(工具链),这样才能较好地满足实战需要。

更多关键词:单文件组件(.vue文件)、Babel、Stylus、Webpack、NPM、ES6、JSX、CoffeeScript、TypeScript

对比其他框架

 

参考文章: