1. 简单的vue实例
每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例 开始的:
var app = new Vue({
// 选项
})
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统,我们新建一个.html 后缀的文件,输入以下代码,运行(右击文件 > open with > mini browser),你就会看到 {{msg}} 被渲染成 hello
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>syl-vue-test</title>
<!-- 通过cdn方式引入 vue.js -->
<script src="https://labfile.oss.aliyuncs.com/courses/1262/vue.min.js"></script>
</head>
<body>
<div id="app">{{msg}}</div>
<script>
var app = new Vue({
el:'#app',//dom挂载点
data:{ //数据项
msg:'hello syl'
}
})
</script>
</body>
</html>
el 为实例挂载点,上面表示挂载在 id 为 app 的 dom 元素中。data 选项为数据选项,存放绑定数据。除了这两个之外还有实例选项,methods(实例方法)、computed(计算属性) 等
M:Model 即数据逻辑处理
V:View 即视图(用户界面)
VM:ViewModel 即数据视图,用于监听更新,View 与 Model 数据的双向绑定
所以,Vue 一大特点就是数据双向绑定,另一大特点就是响应式,接下来,我们来看看他的魅力。
2. vue的响应式原理
Vue 最独特的特性之一,是其非侵入性的响应式系统。
什么是非侵入性?侵入式和非侵入式的区别
我的认识就是,侵入式就是我们的代码和框架的代码混到了一起,我们写的代码必须依赖框架中的某些东西才能使用;而非侵入式的话,就是我们写的代码,即使离开了这个框架也仍然能用,不必在重新写。
什么是响应式呢?简单的讲就是打开浏览器的 JavaScript 控制台 (就在这个页面打开),并修改你的vue中变量的值,更改数据也触发视图的相应更新。
2.1 那么什么是数据的双向绑定呢?
双向绑定就是视图上的变化能够反映到数据上,数据上的变化也能反映到视图上。
2.2 如何追踪数据的变化(那么怎么知道数据变没变?)
当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据属性记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
但是,需要注意的是,受现代 JavaScript 的限制 (而且 Object.observe 也已经被废弃),Vue 无法检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化,所以属性必须在 data 对象上存在才能让 Vue 将它转换为响应式的。
我们通过Object.defineProperty()来实现对数据改变的监听。要了解Object.defineProperty()的原理请点击 vue双向数据绑定的原理,Vue数据双向绑定的原理。
总之就是,当把数据设置为访问器属性之后,数据改变时就会触发存取描述符中的get和set方法,我们就可以通过这两个函数来实现对视图的更新,数据和视图的更新是通过Observer、Watcher、Compile共同完成的。
Observer的核心是通过Obeject.defineProperty()来监听数据的变动,这个函数内部可以定义setter和getter,每当数据发生变化,就会触发setter。这时候Observer就要通知订阅者,订阅者就是Watcher。
Watcher订阅者作为Observer和Compile之间通信的桥梁,主要做的事情是:
在自身实例化时往属性订阅器(dep)里面添加自己
自身必须有一个update()方法
待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调
Compile主要做的事情是解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。
3. 总结
vue.js就是使用模板语法来声明式地将数据渲染进 DOM 的系统,它是一种非侵入式的MVVM框架,它可以实现数据的双向绑定(通过Object.defineProperty)。
4. 参考文献
[1] 实验楼
[2] Vue底层实现原理概述
[3] vue双向数据绑定的原理
[4] Vue数据双向绑定的原理
[5] 侵入式和非侵入式的区别
[6] 深入响应式原理