第三节 Vue的响应式数据

2020-03-26  本文已影响0人  darkTi

一、getter和setter

let obj0 = {
  姓: "高",
  名: "圆圆",
  age: 18
};

// 需求一,得到姓名

let obj1 = {
  姓: "高",
  名: "圆圆",
  姓名() {
    return this.姓 + this.名;
  },
  age: 18
};

console.log("需求一:" + obj1.姓名()); //需求一:高圆圆
// 姓名后面的括号能删掉吗?不能,因为它是函数
// 怎么去掉括号?

// 需求二,姓名不要括号也能得出值

let obj2 = {
  姓: "高",
  名: "圆圆",
  get 姓名() {
    return this.姓 + this.名;
  },
  age: 18
};

console.log("需求二:" + obj2.姓名);  //需求二:高圆圆

// 总结:getter 就是这样用的。不加括号的函数,仅此而已。

// 需求三:姓名可以被写

let obj3 = {
  姓: "高",
  名: "圆圆",
  get 姓名() {
    return this.姓 + this.名;
  },
  set 姓名(xxx){
    this.姓 = xxx[0]
    this.名 = xxx.slice(1)
  },
  age: 18
};

obj3.姓名 = '高媛媛'

console.log(`需求三:姓 ${obj3.姓},名 ${obj3.名}`)   //需求三:姓 高,名 媛媛

// 总结:setter 就是这样用的。用 = xxx 触发 set 函数
var _yyy  //它的作用只是用来过渡装yyy的值得
Object.defineProperty(obj3,'yyy',{  
  get(){
         return  _yyy
  },
  set(value){
    _yyy = value
  }    
})
obj3.yyy = 127
console.log(obj3)
console.log(obj3.yyy)
 //这里一定注意!!!通过Object.defineProperty定义的yyy是虚拟的,不存在的,所以一定要再定义一个变量来装它的值;

image.png

二、代理和监听

// 需求五:就算用户擅自修改 myData,也要拦截他

let myData5 = {n:0}
let data5 = proxy2({ data:myData5 }) // 括号里是匿名对象,无法访问

function proxy2({data}/* 解构赋值,别TM老问 */){
  // 这里的 'n' 写死了,理论上应该遍历 data 的所有 key,这里做了简化
 
  let value = data.n
   //  delete data.n  这里写不写这句话都无所谓,因为下面用defineProperty定义data.n时会覆盖原来的值
  Object.defineProperty(data, 'n', {
    get(){
      return value
    },
    set(newValue){
      if(newValue<0)return
      value = newValue
    }
  })
  // 就加了上面几句,这几句话会监听 data

  const obj = {}
  Object.defineProperty(obj, 'n', {
    get(){
      return data.n
    },
    set(value){
      if(value<0)return//这句话多余了
      data.n = value
    }
  })
  
  return obj // obj 就是代理
}

// data3 就是 obj
console.log(`需求五:${data5.n}`)
myData5.n = -1
console.log(`需求五:${data5.n},设置为 -1 失败了`)
myData5.n = 1
console.log(`需求五:${data5.n},设置为 1 成功了`)


// 这代码看着眼熟吗?
// let data5 = proxy2({ data:myData5 }) 
// let vm = new Vue({data: myData})

// 现在我们可以说说 new Vue 做了什么了

如何来表述Vue的数据响应式?
它主要通过object.defineProperty()里的getter和setter函数对数据的属性进行监听,通过setter可以改变数据的值,在页面上通过getter可以访问到数据的值;但是它有一个缺点,一开始没有在vue的data中声明的属性,是无法进行监听,实现数据响应的,不过Vue给了一个解决办法,通过Vue.set()来添加属性,可以实现数据响应;
想要了解更详细的可以参考:这里

三、Vue.set()和this.$set()

<div id="app">
     <div>{{obj.b}}</div>
     <button @click="setB">显示b</button>
  </div>
new Vue({
  data:{
    obj:{
      a:1
    }
  },
  methods:{
    setB(){
      this.obj.b = 1   //这样是不会显示b的
//       Vue.set(this.obj,'b',1)   
//       this.$set(this.obj,'b',1)   这两句都会让b显示
    }
  }
}).$mount('#app')

四、Vue中数组的变异

 <div id="app">
   {{array}}
     <button @click="add">添加d</button>
  </div>
new Vue({
  data:{
      array: ['a','b','c'] 
  },
  methods:{
   add(){
     this.array[3] = 'd'  //这样写是没有作用的
    this.array.push('d')
   }
  }
}).$mount('#app')
延伸话题——Vue数组中的替换数组
替换数组.png
上一篇 下一篇

猜你喜欢

热点阅读