侧边栏壁纸
博主头像
woku博主等级

成功的路上并不拥挤

  • 累计撰写 50 篇文章
  • 累计创建 13 个标签
  • 累计收到 3 条评论
vue

vue中的data属性和数据响应式

woku
2022-05-27 / 0 评论 / 0 点赞 / 153 阅读 / 1,588 字

data属性

data属性必须是一个函数

  • vue在创建实例的过程中要调用这个函数
  • 返回一个数据对象
  • 通过响应式包装后存储在实例的$data上
  • 实例可以直接越过$data来访问属性
import { createApp } from 'vue'

const vm = createApp({
  data:() => ({
    title: 'this is my title'
  }),
  template: `
    <div> 
      {{ title }}
    </div>
  `
}).mount('#app')

可以通过实例直接访问属性

console.log(vm.title)

也可以通过$data来访问

console.log(vm.$data.title)

这2个其实是同一个数据,只是存在2个不同的地方。
同样,也可以对数据进行修改

vm.$data.title = 'this is your title'
console.log(vm.title)   // 'this is your title'


vm.title = 'this is my title'
console.log(vm.$data.title)  // 'this is my title'

注意:如果直接给vm增加一个属性(没有在实例中的data中定义的)

vm.myName = 'wyg'
console.log(vm)
// vm.$data里面肯定没有这个myName属性的


// 手动的在$data中增加myName属性
vm.$data.myName = 'wyg'
console.log(vm)

上面这种直接给vm增加一个属性(没有在实例中的data中定义的,如果在template模板中使用的话是不行的)
image.png

data为什么要是一个函数

如果data是一个对象


function Vue(options) {
  this.$data = options.data
  var _this = this
  for (var key in this.$data) {
    (function(k) {
      Object.defineProperty(_this, k, {
        get() {
          return _this.$data[k]
        },
        set(val) {
          _this.$data[k] = val
        }
      })
    })(key)
  }
}
var data = {
  a: 1,
  b: 2
}
var vm1 = new Vue({
  data: data
})
var vm2 = new Vue({
  data: data
})
console.log(vm1)
console.log(vm1.a)
vm1.a = 10
console.log(vm1, vm2)
// 当改变vm1的a属性时候,vm2的a属性也会跟着改变。因为2个实例的$data都是同一个引用

如果data是一个函数的话,每次调用会返回一个全新的引用。

如果data就是一个对象,但是每次也要保证每个实例拥有自己的data属性,可以在Vue构造函数中,使用深拷贝来初始化$data

function Vue(options) {
  this.$data = options.data()
  var _this = this
  for (var key in this.$data) {
    (function(k) {
      Object.defineProperty(_this, k, {
        get() {
          return _this.$data[k]
        },
        set(val) {
          _this.$data[k] = val
        }
      })
    })(key)
  }
}
var vm1 = new Vue({
  data() {
    return {
      a: 1,
      b: 2
    }
  }
})

避免实例对象使用同一个引用,而导致每一个实例都不能拥有独一无二的data

上面的Object.defineProperty也可以用更底层的__defineSetter__和__defineGetter__来代替

  • Object.defineProperty是Object上面的一个静态方法
  • __defineSetter__和__defineGetter__是每个实例的原型上的一个方法

image.png

0

评论区