让数组也变成响应式是Vue框架中非常重要的一块内容。下面我将详细讲解Vue2的基本响应式实现方式来实现这个功能。
Vue2基本响应式实现方式
Vue2使用了ES5 Object.defineProperty() 方法来实现数据的响应式。它会递归遍历对象所有的属性,并使用 Object.defineProperty() 方法把它们转换为 getter/setter,并在数据被访问/修改时触发通知,如下:
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get: function reactiveGetter() {
/* 在属性被访问时调用 */
console.log('getter执行了')
return val
},
set: function reactiveSetter(newVal) {
/* 当属性值被修改时调用 */
console.log('setter执行了')
if (newVal === val) return
val = newVal
}
})
}
以上代码,实现一个基本的响应式getter/setter。可是,它并不能对数组进行响应式更新,但是我们可以通过修改数组的原型来实现对象的响应式更新。
修改数组的原型
修改数组的原型,是一种让数组实现响应式的方法。我们可以在 Vue 实例化时修改数组的原型,使得数组能够响应式更新。这样的代码如下:
const arrProto = Array.prototype
const arrayMethods = Object.create(arrProto)
const methodsToPatch = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
]
methodsToPatch.forEach(function(method) {
const original = arrProto[method]
Object.defineProperty(arrayMethods, method, {
value: function mutator(...args) {
original.apply(this, args)
console.log(`array ${method}更新了`)
}
})
})
const arr = []
arr.__proto__ = arrayMethods
arr.push(1)
console.log(arr[0])
// 1
上述代码我们通过修改数组的原型,针对数组常用的几种方法,增加方法(value属性)来监听数组的变化,遇到数组改变(执行了原生方法)就会通知到我们添加的方法,并打印出结果"array ${method}更新了" 。这种方式的缺点是需要在我们的Vue实例化时对我们的数组做出修改,如果移植到其他的项目中,可能会有一些问题。
除此之外,我们还可以使用Vue的observable方法来做到这一点,这样会更加方便,也会更加推荐。
使用Vue的observable方法
Vue2提供了observable方法来供我们创建一个响应式对象,我们可以借助这个方法来让数组实现响应式更新。方法具体实现如下:
const { observable } = Vue;
const a = observable( [] );
a.push( 1 ); // a变化,触发getter和setter
console.log( a[0] ); // 1
我们仍然使用 Array.prototype.push() 方法向数组中添加元素,在执行 push() 方法时,observable() 方法会监听数据变化,在数据更新后执行相应操作,因此我们每次改变数组时, getter/setter 都会更新。
示例说明
以上就是使用原生方法让数组变成响应式的俩种方式,下面我再介绍几个示例说明。
- 对象和数组都响应式更新
const mydata = { a: 1,b: 2,c: [1,2,3]}
const obsData = Vue.observable(mydata)
obsData.c.push(4)
console.log(obsData.c) // [1,2,3,4]
在这个示例中,我们创建了一个对象 mydata 和一个称之为obsData 的响应式对象。当我们将 obsData.c 修改 var a = 1量时,数组会自动更新并触发响应。整个数据的更新过程都是响应式的
- 数组替换
const mydata = { list: [1, 2, 3] } // 定义了一个对象,包含数组 list
const obsData = Vue.observable(mydata) // 创建obsData响应式对象
obsData.list = [4, 5, 6] // 替换数组 list
console.log(obsData.list) // 返回值为 [4, 5, 6], 数据完成响应式更新
这个示例中,我们已经将obsData.list替换为另一个数组。整个数组的替换过程都是响应式的,也就是说当我们替换数组的时候,Vue会自动检测这个数组的变化并触发响应。
好了,以上就是使用Vue2的基本响应式实现方式之让数组也变成响应式的完整攻略。如有疑问,请提出。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue2基本响应式实现方式之让数组也变成响应式 - Python技术站