美文网首页
第三节 Vue的响应式数据

第三节 Vue的响应式数据

作者: darkTi | 来源:发表于2020-03-26 15:43 被阅读0次

一、getter和setter

  • 叫getter,在对象中写的话写get,后面接一个函数;
  • 叫setter,在对象中写set;
  • 在定义完一个对象后,你又想定义新的getter、setter该怎么办,这时候就要用Object.defineProperty
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做的任何修改我vm必须知道!!!
  • 可参考图127,你只把data给new Vue了,Vue就会给你生成一些getter、setter等属性;为了就是时时刻刻监听你的变化,好随时把这些变化体现在视图上~Vue真是操碎了心呐
    图127.png

如何来表述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只会检查一层data,如果发现视图里出现了没有定义在data里的属性,那么会警告;但是!!!如果像上面那样,包一层obj,然后使用obj里未定义的属性,vue是不会警告的;
  • vue有个特点,当它发现data里的属性值为undefined或null时,是不会显示在视图里的;
  • 当obj里没有定义b,下面方法里直接用this.obj.b = 1,对b进行定义是没有用的,必须用Vue.set(this.obj,'b',1)this.$set(this.obj,'b',1)来定义生成b(这两句的意思一模一样),给它赋值,然后才会触发视图,显示b;
  • 所以Vue.set()this.$set()作用是:
    ①新增key;
    ②自动创建代理和监听(如果没有创建过的话);
    ③触发UI更新(但并不会立即更新);

四、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')
  • this.array[3] = 'd' 这样写是没有作用的,因为data里的array可以看做是array:[ 0: 'a', 1: 'b', 2: 'c'],它的小标【3】还没生成呢,所以 this.array[3] = 'd'这样写不行,当然可以用this.$set(this.array, 3 , 'd'),但是duck不必这样写,因为vue帮你把数组组合变异生成了一些新特性呀,你就可以直接用this.array.push('d')来添加新的值;下图就是Vue组合生成的7个特性~~
    array.png
  • this.$set 作用于数组时,并不会自动添加监听和代理,原因未知,只能问尤雨溪了;set 了之后再用 this.array[n] += 1 是不会触发 UI 更新的,所以永远不要用this.array[n]这种写法!!!
  • 使用 Vue 提供的数组变异 API 时,会自动添加监听和代理;


    对象添加多个属性.png
延伸话题——Vue数组中的替换数组
替换数组.png
  • filter():哪个元素能通过我给你设的条件,那我就把你筛选出去组成一个新数组,但是不会改变原有数组(好比司马家选出道组,你满足条件了,我就把你放到出道组里,残忍( Ĭ ^ Ĭ ))

相关文章

  • 前端面试题【Day02】

    本篇绪论 1,Vue响应式原理 1,Vue响应式原理 在vue实例中声明的数据就是响应式的。响应式:数据发生改变,...

  • 2020-12-25

    Vue数据响应式 响应式:当一个物体对外界刺激做出反应,就是响应式。例如:我打你一拳你知道躲。 Vue 数据响应式...

  • Vue的响应式浅析

    1 Vue如何实现响应式? Vue的响应式是建立在监听data中的数据. 2 在Vue2中响应式的实现 Vue通过...

  • Vue源码03-响应式原理

    这节将专门讲解vue MVVM响应式处理 Vue采用的是 实现数据的响应式 数据劫持 Observer类 Obse...

  • 学习vue的响应式 mvvm -01 数据响应式

    理解VUE的设计思想:VUE的核心是MVVM MVVM框架的三要素:数据响应式 模板引擎以及渲染 数据响应式:监听...

  • Vue数据响应式

    1.什么是数据响应式 在 Vue 中,当 data 中的数据发生改变时,视图会进行更新,这就是Vue数据响应式的概...

  • 深入理解Vue数据响应式

    Vue数据响应式主要研究的是 Vue 构造选项中 data 属性的特性 深入响应式 官方文档 网址: https:...

  • VUE中数据响应式原理

    1.vue数据响应式的原理2.数据属性的四大特性3.访问器属性4.getter和setter vue数据响应式主要...

  • 双向绑定

    数据响应式原理 vue实现数据响应式的原理就是利用了Object.defineProperty(),重新定义了对象...

  • Vue 数据响应式原理

    前言 Vue.js 的核心包括一套“响应式系统”。 “响应式”,是指当数据改变后,Vue 会通知到使用该数据的代码...

网友评论

      本文标题:第三节 Vue的响应式数据

      本文链接:https://www.haomeiwen.com/subject/qaeeshtx.html