Vue2核心原理

数据双向绑定原理(数据劫持原理)

  • 深度遍历实例 data 中的所有属性,
  • 通过Object.defineProperty()方法将它们全部变成gettersetter以此进行数据劫持
  • 每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染

图片

注意:

  • Vue 会在初始化实例时实现 data=>setter 和 getter 的转化,因此只有 data 中的数据才会是响应式的
  • Object.defineProperty()方法是是 ES5 中一个无法shim的特性,这也就是 Vue不支持 IE8 以及更低版本浏览器的原因。

Object.defineProperty()

在一个对象上定义新属性,或者修改对象的现有属性并返回这个对象

参数

obj

要定义属性的对象。

prop

要定义或修改的属性的名称或Symbol

descriptor

要定义或修改的属性描述符。

返回值

被传递给函数的对象。

setget方法

1
2
3
4
5
6
7
8
9
10
11
12
13
const object1 = {};
Object.defineProperty(object1, "property1", {
get() {
return val;
},
set(newval) {
val = newval;
},
});
object1.property1 = 77;
// throws an error in strict mode
console.log(object1.property1);
//77

set 和 get 是其内置方法,可直接设置 writable 属性为 true,来允许改写对象属性

1
2
3
4
5
6
7
const object1 = {};
Object.defineProperty(object1, "property1", {
writable: true,
});
object1.property1 = 77;
// throws an error in strict mode
console.log(object1.property1);

数组更新检测

对于 data 中的数组中的属性不是响应式的,它们没有被监听,因此无法通过直接赋值触发重绘

1
vm.arr[0] = 'newName'; //不是响应性的

Vue.set() API

Vue.set( target, propertyName/index, value )

  • 参数:
    • {Object | Array} target
    • {string | number} propertyName/index
    • {any} value

用法:

向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如this.myObject.newProperty = 'hi')

  • 注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。

变更方法

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:

  • push()``向数组的末尾添加一个或多个元素,并返回新的长度
  • shift()``数组中删除第一个元素,并返回该元素的值
  • pop()``删除最后一个元素,并返回该元素的值
  • unshift()``将一个或多个元素添加到数组的开头,并返回该数组的新长度
  • splice()删除替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容
  • sort()
  • reverse()

你可以打开控制台,然后对前面例子的items数组尝试调用变更方法。比如example1.items.push({ message: 'Baz' })

替换数组

变更方法,顾名思义,会变更调用了这些方法的原始数组。相比之下,也有非变更方法,例如filter()concat()slice()。它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:

1
2
3
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})

你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。

JavaScript核心运行机制--单线程、同步和异步、执行栈和任务队列 ES7-新特性:async&await

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×