资讯专栏INFORMATION COLUMN

用 Vue 来观察属性变化

hot_pot_Leo / 1841人阅读

摘要:创建实例时,将遍历的属性,通过的将它们转为,在其内部可以追踪依赖通知变化。在内部,同是响应的观察属性变化的实例提供了方法,用于观察属性变化。

响应系统是 Vue 一个显著功能,修改属性,可以更新视图,这让状态管理变得非常简单且直观。
创建 Vue 实例时,Vue 将遍历 data 的属性,通过 ES5 的 Object.defineProperty 将它们转为 getter/setter,在其内部 Vue 可以追踪依赖、通知变化。

const vm = new Vue({
  data: {foo: 1} // "vm.foo" (在内部,同 "this.foo") 是响应的
})
观察属性变化

Vue 的实例提供了 $watch 方法,用于观察属性变化。

const vm = new Vue({
  data: {foo: 1}
})

vm.$watch("foo", function (newValue, oldValue) {
  console.log(newValue, oldValue) // 输出 2 1
  console.log(this.foo) // 输出 2
})

vm.foo = 2

当属性变化后,响应函数将会被调用,在其内部,this 自动绑定到 Vue 的实例 vm 上。
需要注意的是,响应是异步的。如下:

const vm = new Vue({
  data: {foo: 1}
})

vm.$watch("foo", function (newValue, oldValue) {
  console.log("inner:", newValue) // 后输出 "inner" 2
})

vm.foo = 2
console.log("outer:", vm.foo) // 先输出 "outer" 2

通过 $watch Vue 实现了数据和视图的绑定。观察到数据变化,Vue 便异步更新 DOM ,在同一事件循环内,多次数据变化将会被缓存起来,在下次事件循环中,Vue 刷新队列并仅执行必要的更新。如下:

const vm = new Vue({
  data: {foo: 1}
})

vm.$watch("foo", function (newValue, oldValue) {
  console.log("inner:", newValue) // 后只输出一次 "inner" 5
})

vm.foo = 2
vm.foo = 3
vm.foo = 4
console.log("outer:", vm.foo) // 先输出 "outer" 4
vm.foo = 5
计算属性

MV* 中,将 Model 层数据展现到 View,经常有复杂的数据处理逻辑,这种情况下,使用计算属性 (computed property) 更加明智。

const vm = new Vue({
  data: {
    width: 0,
    height: 0,
  },
  computed: {
    area () {
      let output = ""
      if (this.width > 0 && this.height > 0) {
        const area = this.width * this.height
        output = area.toFixed(2) + "m²"
      }
      return output
    }
  }
})

vm.width = 2.34
vm.height = 5.67
console.log(vm.area) // 输出 "13.27m²"

在计算属性内部,this 自动绑定 vm,因此声明计算属性时需要避免使用箭头函数
上例中,vm.widthvm.height 是响应的,vm.area 内部首次读取 this.widththis.height 时,Vue 收集其做为 vm.area 的依赖,此后 vm.widthvm.height 变化时,vm.area 重新求值。
计算属性是基于它的依赖缓存,如果 vm.widthvm.height 没有变化,多次读取 vm.area,会立即返回之前的计算结果,而不必再次求值。
同样由于 vm.widthvm.height 是响应的,在 vm.area 中可以将依赖的属性赋值给一个变量,通过读取变量来减少读取属性次数,同时解决在条件分支中,Vue 有时会无法收集到依赖的问题
新的实现如下:

const vm = new Vue({
  data: {
    width: 0,
    height: 0,
  },
  computed: {
    area () {
      let output = ""
      const {width, height} = this
      if (width > 0 && height > 0) {
        const area = width * height
        output = area.toFixed(2) + "m²"
      }
      return output
    }
  }
})

vm.width = 2.34
vm.height = 5.67
console.log(vm.area) // 输出 "13.27m²"
通过 ob.js smart-observe 多带带使用 Vue 的属性观察模块

为方便学习和使用,smart-observe 将 Vue 中属性观察模块提取并封装了一下。

smart-observe GitHub 地址:https://github.com/cnlon/smar...

安装

npm install --save smart-observe

观察属性变化

const target = {a: 1}
observe(target, "a", function (newValue, oldValue) {
  console.log(newValue, oldValue) // 3 1
})
target.a = 3

添加计算属性

const target = {a: 1}
observe.compute(target, "b", function () {
  return this.a * 2
})
target.a = 10
console.log(target.b) // 20

像声明 Vue 实例一样传入参数集合

const options = {
  data: {
    PI: Math.PI,
    radius: 1,
  },
  computed: {
    "area": function () {
      return this.PI * this.square(this.radius)
    },
  },
  watchers: {
    "area": function (newValue, oldValue) {
      console.log(newValue) // 28.274333882308138
    },
  },
  methods: {
    square (num) {
      return num * num
    },
  },
}
const target = observe.react(options)
target.radius = 3

更详细的使用介绍请 点击这里

同时推荐其它两款同类库

Watch.JS https://github.com/melanke/Wa...

observe.js https://github.com/kmdjs/obse...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80894.html

相关文章

  • 深入浅出Vue响应式原理

    摘要:总结最后我们依照下图参考深入浅出,再来回顾下整个过程在后,会调用函数进行初始化,也就是过程,在这个过程通过转换成了的形式,来对数据追踪变化,当被设置的对象被读取的时候会执行函数,而在当被赋值的时候会执行函数。 前言 Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。这使得状态管理非常简单直接,不过理解...

    yiliang 评论0 收藏0
  • Vue中如何使方法、计算属性观察

    摘要:如何实现一个查看在线在中我们放置了一些事件处理方法,我们可以在事件绑定中直接应用,不会依赖于任何的属性。例如计算属性依赖于属性,只要属性发生变化,我们的也会发生变化,从而筛选出我们需要的数据。 熟悉 Vue 的都知道 方法methods、计算属性computed、观察者watcher 在 Vue 中有着非常重要的作用,有些时候我们实现一个功能的时候可以使用它们中任何一个都是可以的,但是...

    zhaot 评论0 收藏0
  • 浅谈Vue中计算属性computed的实现原理

    摘要:虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。当某个属性发生变化,触发拦截函数,然后调用自身消息订阅器的方法,遍历当前中保存着所有订阅者的数组,并逐个调用的方法,完成响应更新。 虽然目前的技术栈已由Vue转到了React,但从之前使用Vue开发的多个项目实际经历来看还是非常愉悦的,Vue文档清晰规范,api设计简洁高效,对前端开发人员友好,上手快,甚至个人认为在很多...

    laznrbfe 评论0 收藏0
  • 做面试的不倒翁:浅谈 Vue 中 computed 实现原理

    摘要:当某个属性发生变化,触发拦截函数,然后调用自身消息订阅器的方法,遍历当前中保存着所有订阅者的数组,并逐个调用的方法,完成响应更新。 编者按:我们会不时邀请工程师谈谈有意思的技术细节,希望知其所以然能让大家在面试有更出色表现。也给面试官提供更多思路。 showImg(https://segmentfault.com/img/bVbgYyU?w=1200&h=600); 虽然目前的技术...

    Anonymous1 评论0 收藏0
  • 关于框架

    摘要:事件订阅发布者模式什么是读音类似于是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,采用自底向上增量开发的设计。 MVC && MVVM 前端框架前端 MV*框架的意义 被误解的MVC和被神化的MVVM Vue.js新手入门指南 单页应用SPA的路由 单页面应用的路由问题 本文是在自己总结时,看了许多篇文章有了些体会,然后把我认为有意义的摘抄下来,文中很大部分摘录以上...

    Richard_Gao 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<