【前端3分钟】MVVM数据变更检测

⭐️ 本文首发自 前端修罗场(点击加入),是一个由 资深开发者 独立运行 的专业技术社区,我专注 Web 技术、Web3、区块链、答疑解惑、面试辅导以及职业发展博主创作的 《前端面试复习笔记》(点击订阅),广受好评,已帮助多人提升实力、拿到 offer。现在订阅,私聊我即可获取一次免费的模拟面试机会,帮你评估知识点的掌握程度,获得更全面的学习指导意见!

MVP模式

P 代表 Presenter,与 Controller 有些类似,但是不同的是,在用户进行DOM修改操作时将通过 View 上的行为进行触发,然后将修改的通知告诉给 Presenter 来完成对 Model 与其他 View 的更新;而MVC模式下,用户的操作是直接通过 Controller进行。

通常,Presenter 与 View 的操作是双向绑定的,即 View 的操作会触发 Presenter,Presenter 的操作会触发 View。

MVVM模式

MVVM 是一种自动化的 MVP 框架,使用 ViewModel 代替 Presenter,并使用 ViewModel 自动完成对数据Model的调用和模板内容的渲染。

当用户进行操作时,ViewModel 会捕获数据变化,直接将变化反映到 View 层。在 MVVM 模式下,通过使用 Directive 来管理ViewModel的数据操作。

什么是 Directive 呢?例如模板数据的渲染和数据绑定可以通过 q-html 或 q-click(不同框架前缀不同)等特殊的属性来控制完成,这些特殊的元素标签属性就是我们所说的 Directive。

具体说来,Directive是指定,简单地说是自定义的执行函数。
有如下代码:

<form action="#" id="form">
  <label for="text" q-html="label"></label>
  <input type="text" q-value="value" q-model="value" q-mydo="number | getValue">
  <button q-on="click: submit"></button>
</form>

let viewModel = new VM({
  $el: document.getElementById('form'),
  data:{
    label:'用户名',
    value:'输入初始值',
    number:0
  },
  method:{
    submit(){
     //todo
    }
  },
  directive:{
    mydo(value){
     console.log(value);
    }
  },
  filter:{
    getValue(){
      return ++ value;
    }
  }
});

代码解释:首先 js 会找到 document.getElementById('form') 这个元素并开始扫描元素节点,对这个元素的属性节点 attribute 和所有子节点中的 attribute 进行遍历,一旦遍历到民名称中含有q-开头的属性,就认为是MVVM框架自定义的 Directive,此时会执行相对应的操作。例如遍历到q-html="label" 时,就将 ViewModel 初始化时默认的数据对象 data 中的 label 值赋予这个元素的 innerHtml,遍历到q-on="click: submit"时,就在这个元素上绑定 click 事件,事件触发的函数为 submit;而自定义的 q-mydo 指令,当遍历到该节点的q-mydo属性时,调用 Directive 中的 mydo 方法,输入参数为data中 getValue 方法的返回值。用户在 View层操作时会自定改变ViewModel的数据,然后 ViewModel 会检测数据的变化,重新遍历扫描节点属性,执行对应的 Directive。

数据变更检测方法

  • 手动触发绑定

通过在数据对象上定义 get() 方法和 set() 方法,调用时手动触发 get() 或 set() 函数来获取、修改数据,改变数据后会主动触发get() 和 set() 函数中 View 层的重新渲染功能。

  • 脏检测

在ViewModel对象的某个属性值发生变化时找到与这个属性值相关的所有元素,然后再比较数据变化,如果变化则进行Directive指令调用,对这个元素进行重新扫描渲染。与手动绑定不同的是,脏检测只针对可能修改的元素进行扫描,从而提高ViewModel内容变化后扫描视图并渲染的效率。

  • 数据劫持

使用Object.definePropertyObject.defineProperies对ViewModel数据对象进行属性get()和Set()的监听,当有数据读取和赋值操作时,则扫描节点,运行指定对应节点的Directive指令。

  • ES6 Proxy

用于在已有的对象基础上重新定义一个对象,并重新定义对象原型上的方法,包括get()和set()方法。

❤️ 现在关注【前端修罗场】,后台回复【666】,即可获取一份【免费的优质学习资料】,一起学习,一起进步,不走弯路,不吃亏~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程轨迹_

期望和你分享一杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值