其实学习vue最好的办法就是看vue的官方文档,所以我写这个主要是想记录下学习的心路历程[手动滑稽],顺便加深下印象。

#数组或者对象的属性更新,但视图未发生变化

  • 这个是一个比较值得注意的点,官方文档是这样描述的
由于 JavaScript 的限制,Vue 不能检测以下变动的数组:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
  • 也就是说对于数组的操作直接对下标进行操作,vue自身'感知/监控'不到的(具体原因稍后解释),需要主动的去'通知',通过vue自身实现的一个Vue.$set()
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
  • 那么为什么set方法就是可行的?查找vue 的api文档vue_set这样的一段描述

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

注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。
  • 我们首先需要了解的是Vue 响应式原理的实现

    • 我的理解是vue将传进去的data对象进行遍历,并且利用Object.defineProperty方法将这些属性转化为getter/setter,即将数据描述符转化为存取描述符。
Object.defineProperty 是仅 ES5 支持,且无法 shim 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器的原因。

追踪变化原理

  • 简单的来说就是在页面渲染的过程中,页面的某一部分a使用到 或者是 计算属性中用到了data中的数据b,其实就是调用了getter函数,通知watcher会将b作为a的依赖,一但数据b发生改变其实就是调用了setter,而setter的变化会通知到watcher,进而重新渲染视图。

到此,这个问题基本上就有答案了。

  • 将数组的下标当作当作对象的属性进行类比,当我们添加属性并赋值时,Vue 并不能检测到对象中属性的添加或者删除,但是data中对应的属性确实是变化了,但是这个过程Vue是不可以监控的,需要主动的去通知Vue 将这个属性转化为 __boserver__类型的(vue可以动态响应的数据类型)

补充

Object.observe() 方法用于异步地监视一个对象的修改。当对象属性被修改时,方法的回调函数会提供一个有序的修改流。然而,这个接口已经被废弃并从各浏览器中移除。你可以使用更通用的 Proxy 对象替代。
Object.observe(obj, callback[, acceptList])

  • callback 当对象被修改时触发的回调函数,其参数为:
  • changes 一个数组,其中包含的每一个对象代表一个修改行为。每个修改行为>的对象包含:

    • name: 被修改的属性名称。
    • object: 修改后该对象的值。
    • type: 表示对该对象做了何种类型的修改,可能的值为"add", "update", or "delete"。
    • oldValue: 对象修改前的值。该值只在"update"与"delete"有效。
  • acceptList 在给定对象上给定回调中要监视的变化类型列表

wenhua
65 声望1 粉丝

web前端