前端Vue篇之Vue中封装的数组方法有哪些,如何实现页面更新

目录


Vue中封装的数组方法有哪些,如何实现页面更新

在 Vue 中,对于对象的响应式处理是通过 Object.defineProperty 来实现的,但是这种方式并不能直接监听到数组内部变化、长度变化以及截取操作等。为了让 Vue 能够监听到数组的这些变化,Vue 对数组进行了特殊处理。

数组的特殊处理

Vue 对数组的特殊处理主要包括两个方面:

  1. 重写数组的变异方法
    • Vue 重写了数组的变异方法(例如 push、pop、shift、unshift、splice、sort 和 reverse),在这些方法执行时,会触发通知机制,告知 Vue 数据发生了变化。
  2. 使用__proto__或者prototype
    • Vue 将数组的原型指向了一个特殊的对象,该对象包含了重写后的数组变异方法,这样就能够确保当调用这些方法时,能够触发数据更新。

Vue通过重写数组的变异方法,并且将数组的原型指向特殊对象的方式,使得 Vue 能够监听到数组的变化,从而确保了当数组发生变化时,页面能够及时地反映数据的变化。这种特殊处理让开发者在使用 Vue 时更加便利,不需要手动干预页面更新的过程,提供了更好的开发体验。

在Vue中,常用的数组方法封装在Vue实例的data属性中。这些方法包括:

  1. push()

    • 用法:this.array.push(newItem)
    • 功能:向数组末尾添加一个或多个元素
  2. pop()

    • 用法:this.array.pop()
    • 功能:删除并返回数组的最后一个元素
  3. shift()

    • 用法:this.array.shift()
    • 功能:删除并返回数组的第一个元素
  4. unshift()

    • 用法:this.array.unshift(newItem)
    • 功能:向数组的开头添加一个或多个元素,并返回新的长度
  5. splice()

    • 用法:this.array.splice(index, howMany, newItem1, ..., newItemX)
    • 功能:从数组中添加/删除项目,然后返回被删除的项目
  6. sort()

    • 用法:this.array.sort()
    • 功能:对数组元素进行排序
  7. reverse()

    • 用法:this.array.reverse()
    • 功能:颠倒数组中元素的顺序

实现页面更新

在Vue中,当使用上述数组方法修改数据时,Vue会自动检测到数据的变化,并触发相应的页面更新。

例如,当你使用 push 方法向数组中添加新元素时,Vue会自动更新相关的页面内容,无需手动干预页面更新的过程。这是因为Vue内部实现了响应式系统,它能够监听到数据的变化,并在数据改变时重新渲染相关的组件。

需要注意的是,在某些情况下,如果你直接使用索引更改数组元素,Vue可能无法自动检测到这种变化。在这种情况下,你可以使用 Vue.set 方法或者 array.splice 来确保 Vue 能够正确地追踪数组的变化并更新页面内容。

总之,Vue封装的数组方法能够简化数据操作,并且通过其内部的响应式系统,确保了当数组发生变化时,页面能够及时地反映数据的变化,从而提供了更好的开发体验。

Vue是如何实现让这些数组方法实现元素的实时更新的呢,下面是Vue中对这些方法的封装:

javascript 复制代码
// 缓存数组原型
const arrayProto = Array.prototype
// 实现 arrayMethods.__proto__ === Array.prototype
export const arrayMethods = Object.create(arrayProto)
// 需要进行功能拓展的方法
const methodsToPatch = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']

/**
 * Intercept mutating methods and emit events
 */
methodsToPatch.forEach(function (method) {
  // 缓存原生数组方法
  const original = arrayProto[method]
  def(arrayMethods, method, function mutator(...args) {
    // 执行并缓存原生数组功能
    const result = original.apply(this, args)
    // 响应式处理
    const ob = this.__ob__
    let inserted
    switch (method) {
      // push、unshift会新增索引,所以要手动observer
      case 'push':
      case 'unshift':
        inserted = args
        break
      // splice方法,如果传入了第三个参数,也会有索引加入,也要手动observer。
      case 'splice':
        inserted = args.slice(2)
        break
    }
    //
    if (inserted) ob.observeArray(inserted) // 获取插入的值,并设置响应式监听
    // notify change
    ob.dep.notify() // 通知依赖更新
    // 返回原生数组方法的执行结果
    return result
  })
})

这段代码是 Vue 中对数组方法进行拦截和响应式处理的关键部分。

  1. 缓存原生数组方法

    • 首先,代码通过 const arrayProto = Array.prototype 缓存了原生的数组方法,以备后续使用。
  2. 创建扩展后的数组对象

    • 然后,通过 Object.create(arrayProto) 创建了一个名为 arrayMethods 的对象,这样就可以在这个对象上添加新的方法或者重写原有的方法,而不影响原生的 Array.prototype
  3. 遍历需要拓展的方法

    • 接下来,代码遍历了需要拓展的数组方法,对每个方法进行拓展。这些方法包括 push、pop、shift、unshift、splice、sort 和 reverse。
  4. 拓展方法的实现

    • 对于每个方法,使用 def 函数将原生方法替换为新的方法。新方法在执行原生方法后,进行响应式处理并通知依赖更新。具体的响应式处理包括:
      • 获取操作的数据对象的 Observer 实例(ob)。
      • 根据操作类型,获取需要设置响应式监听的值。
      • 如果有需要设置响应式监听的值,调用 Observer 实例的 observeArray 方法进行处理。
      • 最后,通过 ob.dep.notify() 通知依赖更新。

需要注意的

  • 此段代码的作用是为 Vue 实现数组变更时的响应式更新。它会在数组的变更操作后,自动触发 Vue 的响应式更新机制,确保页面能够及时地反映数据的变化。
  • 在拓展数组方法时,需要考虑到新增的元素,确保新增的元素也能被设置为响应式数据。
  • 此段代码中的 def 函数可能是用来定义属性的,但在给出的代码中未提供该函数的实现。需要确保在代码其他地方有对该函数的定义和实现。

总结

以上代码片段主要实现了对数组方法的拦截和响应式处理,确保当数组发生变化时,Vue 能够自动更新相关的页面内容。这对于 Vue 来说是非常重要的,因为它保证了数据和视图之间的同步更新。

持续学习总结记录中,回顾一下上面的内容:
Vue中封装的数组方法包括push、pop、shift、unshift、splice、sort和reverse。页面更新是通过Vue对这些方法进行特殊处理,确保当数组发生变化时,Vue能够自动更新相关的页面内容。这样,开发者无需手动干预页面更新,提供了更好的开发体验。

相关推荐
Mr.Liu69 分钟前
小程序25- iconfont 字体图标的使用
前端·微信小程序·小程序
爱写代码的派大星12 分钟前
el-table :span-method 合并单元格(2.0)
前端·javascript·vue.js
stonefisher24 分钟前
深挖`React`里程碑之作`AutoStore`与`helux`的渊源
前端·react.js·前端框架
夫琅禾费米线27 分钟前
CSS 设置宽高的单位概览
前端·javascript·css
chusheng184037 分钟前
Java 基于SpringBoot+Vue的家政服务管理平台
java·vue.js·spring boot·家政服务·家政服务平台
张雨zy1 小时前
Vue Form表单的使用,rules格式校验网络校验,键盘按键监听
javascript·vue.js
anyup1 小时前
【附源码】微信公众号 h5 网页授权开发
前端·微信·uni-app
余生H1 小时前
transformer.js(四): 模型接口介绍
前端·javascript·深度学习·transformer
神秘代码行者1 小时前
Vue 3 动态组件教程
vue.js
BLACK5951 小时前
使用Vue与MarsCode实现信息分步填写表单
vue.js·豆包marscode