做淘客app要网站吗,恩施市建设银行网站,网站开发后端培训,wordpress图片设置水印2019前言
双向绑定机制是Vue中最重要的机制之一#xff0c;甚至可以说是Vue框架的根基#xff0c;它将数据与视图模板相分离#xff0c;使得数据处理和页面渲染更为高效#xff0c;同时它也是前端面试题中的常客#xff0c;接下来让我们来了解什么是双向绑定以及其实现原理。…前言
双向绑定机制是Vue中最重要的机制之一甚至可以说是Vue框架的根基它将数据与视图模板相分离使得数据处理和页面渲染更为高效同时它也是前端面试题中的常客接下来让我们来了解什么是双向绑定以及其实现原理。 什么是双向绑定
vue的双向绑定即数据与视图的响应式设计。具体表现为View 的改变能实时让Model发生变化而 Model 的变化也能实时更新 View。而单项数据绑定所有数据只有一份一旦数据变化就去更新页面(只有data--DOM没有DOM--data)。
总之所谓双向绑定指的是 Vue 实例中的 data 与其渲染的 DOM 元素的内容保持一致无论谁被改变另一方会相应的更新为相同的数据。
使用双向绑定v-model
Vue2
templatediv idappinput typetext v-modelmessagep{{message}}/p/div
/template
script
export default {data() {return {message: Hello, Vue2!};}};
/scriptVue3
templatediv idappinput typetext v-modelmessagep{{message}}/p/div
/template
script
import { ref } from vue;export default {setup() {const message ref(Hello, Vue 3!);return { message};}};
/script注意Vue双向绑定的对象一定要是响应式的。
双向绑定的原理
实现模式
Vue双向数据绑定是通过数据劫持发布订阅者模式来实现的。Vue 采用的是 MVVM 架构实现 MVVM 主要包含两个方面一是数据变化更新视图二是试图变化更新数据。 在实现过程上来说主要有四个模块
监听器Observer执行劫持监听的所有属性如果属性发生变化了就通知订阅者Watcher看是否需要更新。订阅者Watcher可以受到属性的变化通知并执行相应的函数从而更新视图。消息订阅器Dep因为订阅者有很多个所以需要一个消息订阅器Dep来专门收集这些订阅者然后在监听器Observer和订阅者Watcher之间进行统一管理。解析器Compile可以扫描和解析每个节点的相关指令并根据初始化模板数据以及初始化相应的订阅器。 Vue2与Vue3绑定模式的实现差异
需要注意的是虽然Vue2与Vue3都采用了数据劫持发布订阅者的模式但二者的实现原理有所不同
Vue2是通过 ES5 提供的 Object-defineProperty() 方法来劫持监听各属性的 getter、setter并在当监听的属性发生变动时通知订阅者是否需要更新若更新就会执行对应的更新函数。Vue3加入ES2015中新增的 Proxy() 代替了原本的 Object.defineProperty()。
Vue3为什么弃用了ObjectdefineProperty选择了Proxy
Proxy() 可以拦截数组和对象的变化。而 Object.defineProperty() 只能拦截对象属性的变化。相较于 Object.defineProperty() 劫持某个属性Proxy() 则更彻底不在局限某个属性而是直接对整个对象进行代理。Proxy能够监听到对象属性的增加、删除。Object.defineProperty() 不能对 ES6 新产生的 Map 、Set 这样的数据结构进行监听。Object.defineProperty() 无法监控到数组下标的变化导致通过数组下标添加元素不能实时响应。
手写 Object.defineProperty() 双向数据绑定
div展示h1/h1输入: input typetext
/divscript// 创建definePropertyFn来挟持数据function definePropertyFn() {let obj {}let val nullObject.defineProperties(obj, {val: {get() {return val},set(newV) {val newV// 数据控制视图 将更改的数据赋值给h1document.querySelector(h1).innerText newVconsole.log(调用了set,获取: newV, val);}}})return obj}let newObj definePropertyFn()document.querySelector(h1).innerText newObj.val // 调用了get,执行数据渲染视图document.querySelector(input).value newObj.val // 调用了get,执行数据渲染视图// 下面监听视图 input 标签标签一变动将最新数据获取调用set赋值给val并且赋值给h1document.querySelector(input).addEventListener(input, function () {newObj.val document.querySelector(input).value})
/script