vue中的响应式是什么? 怎么理解响应式原理?

vue中响应式是什么?

概念:

官网解释:Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。

简而言之就是数据变页面变

实现原理:

Vue在组件和实例初始化的时候,会将data里的数据进行数据劫持(object.definepropty对数据做处理)。被解除过后的数据会有两个属性:一个叫getter,一个叫setter

getter是使用数据的时候触发,setter是在修改数据的时候触发,修改数据的时候触发setter,同时也触发了底层的watcher监听,通知dom修改刷新。

举个例子:
我们新创建一个对象data,并在控制台输出

let data={name:1}
console.log(data)

我们看到的结果是这样的
在这里插入图片描述
接着我们用Object.defineProperty处理一下数据,比如创建一个成员

let data={name:1}

Object.defineProperty(data,'age',{
  // getter
  get(){

  },
  // setter
  set(){
    
  }
})

console.log(data)

再来看,这时多了两个方法
在这里插入图片描述
这就是Object.definepropty的作用,是es5中的一个方法,处理数据,给数据赋予gettersetter

Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。

正常情况下,这两个方法都不会触发,当我们给age赋值和改变age值的情况下会执行这两个函数

let middle = 6
Object.defineProperty(data,'age',{
  get(){
    console.log('获取age')
    return middle
  },
  set(parmas){
    //参数就是赋值的数据
    console.log('修改age数据',parmas)
    middle = parmas
  }
})
console.log(data)
// 取值的时候触发getter
console.log(data.age)
//赋值的时候触发setter
data.age = 15
console.log(data.age)

在这里插入图片描述

difinePropty模拟响应式:

我们用这个方法来模拟vue底层的源码

通过按钮修改dom里面的数字:

<div id ='test'>
  2
</div>
<button onclick="change()">change</button>
<script>
let data={}

function change(){
 data.age =999
}

// 模拟vue中的源码 
let middle = 2
Object.defineProperty(data,'age',{
  get(){
   return middle
  },
  set(params){
    middle=params
    // 只要是数据修改了就会指令
    watcher()
  } 
})

// 绑定watcher监听
function watcher(){
  // 数据改变之后触发 进行diff【判断是否应该修改dom】
  renderDom()
}

// 重新渲染的方法
function  renderDom(h) {
 let test = document.getElementById('test')
 let age = data.age 
 test.innerHTML = age 
}
console.log(data)

Vue中数据变页面一定变嘛?

  • 那么问题来了,数据变页面一定变么?
  • 不一定,数据变页面变的原因是因为数据劫持了data

先来看一个小例子:

<div id ='app'>
    {{user}}
    <hr>  
    <button @click='changeName'>changeName</button>
</div>

<script>
new Vue({
  el:'#app',
  data:{
    user:{
      age:15
    }
  },
  methods: {
    changeName(){
      this.user.name = '韩梅梅'
      console.log(this.user)
    }
  },
})
</script>

这时候我按钮,发现改变不了name的值,所以打开控制看一下
在这里插入图片描述
我们会发现只有age有gettersetter,name没有,Vue 无法检测到对象属性的添加或删除,所以没法进行响应式改变数据

TIPS:两种情况新添加的属性都有没有gettersetter,数据变页面也不变:1. 对象数据的添加 2. 数组长度的改变

解决方式:动态的往里面添加数据,使用this.$set方法

以上面例子为例:

methods: {
    changeName(){
      // this.user.name = '韩梅梅'
      // set 将数据用 object.defainPropty进行处理 添加getter和setter
      this.$set(this.user,'name','韩梅梅')
      console.log(this.user)
    }
  }

这样我们就能在页面上看到新增的属性
在这里插入图片描述

  • 23
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值