源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

用Vue.js实现监听属性的变化

  • 时间:2022-12-03 07:49 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:用Vue.js实现监听属性的变化
[b]前言[/b] 创建 Vue 实例时,Vue 将遍历 data 的属性,通过 ES5 的 [code]Object.defineProperty [/code]将它们转为 getter/setter,在其内部 Vue 可以追踪依赖、通知变化。
const vm = new Vue({
 data: {foo: 1} // 'vm.foo' (在内部,同 'this.foo') 是响应的
})
[b]观察属性变化[/b] 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 上。 [b]需要注意的是,响应是异步的。[/b] [b]如下:[/b]
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
通过 [code]$watch Vue[/code] 实现了数据和视图的绑定。观察到数据变化,Vue 便异步更新 DOM ,在同一事件循环内,多次数据变化将会被缓存起来,在下次事件循环中,Vue 刷新队列并仅执行必要的更新。 [b]如下:[/b]
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
[b]计算属性[/b] 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,因此声明计算属性时需要避免使用箭头函数。 上例中,[code]vm.width[/code] 和 [code]vm.height [/code]是响应的,[code]vm.area [/code]内部首次读取[code] this.width [/code]和 [code]this.height [/code]时,Vue 收集其做为 [code]vm.area [/code]的依赖,此后 [code]vm.width [/code]或[code] vm.height [/code]变化时,[code]vm.area [/code]重新求值。计算属性是基于它的依赖缓存,如果 [code]vm.width [/code]和 [code]vm.height [/code]没有变化,多次读取 [code]vm.area[/code],会立即返回之前的计算结果,而不必再次求值。 同样由于 [code]vm.width[/code] 和 [code]vm.height [/code]是响应的,在 [code]vm.area [/code]中可以将依赖的属性赋值给一个变量,通过读取变量来减少读取属性次数,同时解决在条件分支中,Vue 有时会无法收集到依赖的问题。 [b]实现如下:[/b]
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²"
[b]通过 ob.js 单独使用 Vue 的属性观察模块[/b] 为方便学习和使用,ob.js 将 Vue 中属性观察模块提取并封装了一下。 ob.js GitHub 地址:https://github.com/cnlon/ob.js [b]安装[/b]
npm install --save ob.js
[b]观察属性变化[/b]
const target = {a: 1}
ob(target, 'a', function (newValue, oldValue) {
 console.log(newValue, oldValue) // 3 1
})
target.a = 3
[b]添加计算属性[/b]
const target = {a: 1}
ob.compute(target, 'b', function () {
 return this.a * 2
})
target.a = 10
console.log(target.b) // 20
[b]像声明 Vue 实例一样传入参数集合[/b]
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 = ob.react(options)
target.radius = 3
[b]总结[/b] 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部