vue中v-model和响应式的实现原理解析

目录
  • v-model
  • 响应式实现

v-model

  • 首先要了解v-model就是vue帮我们封装的语法糖,真正实现靠的还是:
  • v-bind:绑定响应式数据 触发 input 事件 并传递数据

例如下面示例:

<template>
	// 这两种写法等价
	<input v-bind:name="name" v-on:input="name=$event.target.value"/>
	<input v-model="name"/>
</template>

1、使用v-model经典例子

  • textarea 元素
  • select 下拉框
  • input type='radio' 单选框
  • input type='checkbox' 多选框

2、使用v-model的副作用

绑定的响应式对象某个不存在的属性,那么vue会悄悄增加这个属性,并设置为响应式

// template中:
<el-input v-model="user.tel"></el-input>
// script中:
export default {
  data() {
    return {
      user: {
        name: 'xxx',
      }
    }
  }
}

3、自己开发的组件如何支持v-model

model属性的默认值为

// 默认的 model 属性
export default {
  model: {
    prop: 'value',
    event: 'input'
  },
  data() {...},
  methods: {...},
}

响应式实现

简单一句话理解就是:通过重写数据的get和set属性方法,让数据在被渲染时通过get属性方法把所有用到自己的观察者watcher放入自己的观察者列表subs中,当数据发生变化之后,通过set属性方法将该变化通知给所有的观察者watcher,达到重新渲染。

  • 使用观察者模式
  • 底层使用Object.defineProperty(),给所有的数据都添加gettersetter方法
  • 主要涉及到三个函数:
  • Dep:被观察者类,每个data都有一个Dep实例对象,用于Observer的data触发getter时执行
  • dep.depend收集依赖的watcher
  • Watcher:观察者类,依赖收集以后Watcher对象会被保存在Dep的subs中,数据变动的时候Dep会通知Watcher实例,然后由Watcher实例回调cb进行视图的更新。
  • Observer:将普通数据转化为响应式数据

实现响应式的主要流程:

1、Observer类的构造方法

  • 给当前的数据对象新建一个订阅器Dep
  • 遍历对象的 key 调用 defineReactive 方法(实际绑定getter和setter的地方。get 方法是对依赖进行收集, set 方法是当数据改变时通知 Watcher 派发更新)

2、收集依赖
视图被渲染时,触发get属性方法,调用dep的一个方法dep.depend进行依赖收集

  • Watcher类:依赖就是watcher的实例
  • Dep类:存放依赖的位置,通过Dep.subs[]进行管理依赖

举个
当前正在渲染componentA时,组件用到了数据 data () { return { a: b + 1} },那么此时就会触发b的get属性方法,将当前的watcher添加到b的订阅者列表subs中

3、派发更新
修改data属性上的某一个值时,会它的触发set属性方法,根据自身的dep.notify(subs保存着所有的观察者,在 notify 方法中首先对 subs 这个观察者列表按照其 id 进行了排序)开始派发更新

为什么要进行排序?

  • 组件的更新由父到子;因为父组件的创建过程是先于子的,所以 watcher 的创建也是先父后子,执行顺序也应该保持先父后子。
  • 用户的自定义 watcher 要优先于渲染 watcher 执行;因为用户自定义 watcher 是在渲染 watcher 之前创建的。
  • 如果一个组件在父组件的 watcher 执行期间被销毁,那么它对应的 watcher 执行都可以被跳过,所以父组件的 watcher 应该先执行。

排序结束以后,会对这个队列进行遍历,执行watcher.run()方法实现数据更新通知

run的逻辑是:

  • 新的值与老的值不同时会触发通知;
  • 但是当值是对象或者 deep 为 true 时无论如何都会进行通知

这也就是为什么可以解释watch数据的时候可以拿到新旧两个值了
watch: { num(new, old) {...} }

自己实现一个响应式

根据以上分析,自己实现一个简易版的数据双向绑定

借鉴文章

到此这篇关于vue中v-model和响应式的实现原理的文章就介绍到这了,更多相关vue v-model响应式原理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue响应式系统的原理详解

    目录 vue响应式系统的基本原理 1.回顾一下Object.defineProperty的用法 2.实战1:使用 Object.defineProperty 对 person的age属性 进行监听 3.数据代理 4.vue中实现响应式思路 总结 1.Vue中的数据代理: 2.Vue中数据代理的好处: 3.基本原理: 4.vue中实现响应式思路 vue响应式系统的基本原理 我们使用vue时,对数据进行操作,就能影响对应的视图.那么这种机制是怎么实现的呢? 思考一下,是不是就好像我们对数据的操作 被

  • Vue响应式原理的示例详解

    Vue 最独特的特性之一,是非侵入式的响应系统.数据模型仅仅是普通的 JavaScript 对象.而当你修改它们时,视图会进行更新.聊到 Vue 响应式实现原理,众多开发者都知道实现的关键在于利用 Object.defineProperty , 但具体又是如何实现的呢,今天我们来一探究竟. 为了通俗易懂,我们还是从一个小的示例开始: <body> <div id="app"> {{ message }} </div> <script> v

  • vue3.0响应式函数原理详细

    目录 1.reactive 2.ref 3.toRefs 4.computed 前言: Vue3重写了响应式系统,和Vue2相比底层采用Proxy对象实现,在初始化的时候不需要遍历所有的属性再把属性通过defineProperty转换成get和set.另外如果有多层属性嵌套的话只有访问某个属性的时候才会递归处理下一级的属性所以Vue3中响应式系统的性能要比Vue2好. 接下来我们自己实现Vue3响应式系统的核心函数(reactive/ref/toRefs/computed/effect/trac

  • VUE响应式原理的实现详解

    目录 总结 前言 相信vue学习者都会发现,vue使用起来上手非常方便,例如双向绑定机制,让我们实现视图.数据层的快速同步,但双向绑定机制实现的核心数据响应的原理是怎么样的呢,接下来让我们开始介绍: function observer(value) { //给所有传入进来的data 设置一个__ob__对象 一旦value有__ob__ 说明该value已经做了响应式处理 Object.defineProperty(value, '__ob__', { value: this, //当前实例 也

  • 详解Vue3的响应式原理解析

    目录 Vue2响应式原理回顾 Vue3响应式原理剖析 嵌套对象响应式 避免重复代理 总结 Vue2响应式原理回顾 // 1.对象响应化:遍历每个key,定义getter.setter // 2.数组响应化:覆盖数组原型方法,额外增加通知逻辑 const originalProto = Array.prototype const arrayProto = Object.create(originalProto) ;['push', 'pop', 'shift', 'unshift', 'splic

  • 详解VUE响应式原理

    目录 1.响应式原理基础 2.核心对象:Dep与Watcher 3.收集依赖与更新依赖 3.1 收集依赖 3.2 更新依赖 4.源码调试 4.1 测试的页面代码 1.对象说明 2.Dep与Watcher的关系 3.最终的关系结果 4.2  源码调试 1.收集依赖的入口函数:initState(页面初始化时执行); 2.初始化computed和watch时,生成Watcher实例化对象 总结 1.响应式原理基础 响应式基本原理是基于Object.defineProperty(obj, prop,

  • 如何在Vue中使localStorage具有响应式(思想实验)

    响应式是Vue.js的最大特色之一.如果你不知道幕后情况,它也是最神秘的地方之一.例如,为什么它不能用于对象和数组,而不能用于诸如 localStorage 之类的其他东西? 让我们回答这个问题,在解决这个问题时,让Vue响应式与 localStorage 一起使用. 如果运行以下代码,则会看到计数器显示为静态值,并且不会像我们期望的那样发生变化,这是因为setInterval在 localStorage 中更改了该值. new Vue({ el: "#counter", data:

  • vue中v-model和响应式的实现原理解析

    目录 v-model 响应式实现 v-model 首先要了解v-model就是vue帮我们封装的语法糖,真正实现靠的还是: v-bind:绑定响应式数据 触发 input 事件 并传递数据 例如下面示例: <template> // 这两种写法等价 <input v-bind:name="name" v-on:input="name=$event.target.value"/> <input v-model="name&quo

  • vue中provide inject的响应式监听解决方案

    目录 provide inject的响应式监听解决 vue监听赋值及provide与inject provide inject的响应式监听解决 提示:provide 和 inject 绑定并不是可响应的.这是刻意为之的.然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的. 所以传值传对象即可 provide(){     return {       provObj: {         uuidList:{}       }     }   }, this._provided.p

  • 使用Vue.js和MJML创建响应式电子邮件

    MJML是一种现代的电子邮件工具,使开发人员可以在所有设备和邮件客户端上创建美观.响应迅速的出色电子邮件.这种标记语言是为了减少编写响应式电子邮件的痛苦而设计的. 它的语义语法使其易于使用.它还具有功能丰富的标准组件,可缩短开发时间.在本教程中,我们将使用MJML构建漂亮的响应式邮件,并在多个邮件客户端上进行测试. 开始MJML 你可以使用npm安装MJML,以将其与Node.js或CLI结合使用: $ npm install -g mjml 构建我们的电子邮件 首先,请创建一个名为 email

  • Vue源码学习之响应式是如何实现的

    目录 前言 一.一个响应式系统的关键要素 1.如何监听数据变化 2.如何进行依赖收集--实现 Dep 类 3.数据变化时如何更新--实现 Watcher 类 二.虚拟 DOM 和 diff 1.虚拟 DOM 是什么? 2.diff 算法--新旧节点对比 三.nextTick 四.总结 前言 作为前端开发,我们的日常工作就是将数据渲染到页面➕处理用户交互.在 Vue 中,数据变化时页面会重新渲染,比如我们在页面上显示一个数字,旁边有一个点击按钮,每次点击一下按钮,页面上所显示的数字会加一,这要怎么

  • JS中使用media实现响应式布局

    常见写法: 下面总结常见的响应式布局的分类: @media screen and (max-width:320px){ #talkFooter .editArea{-- } } @media screen and (min-width:321px) and (max-width:375px){ #talkFooter .editArea{-- } } @media screen and (min-width:376px) and (max-width:414px){ #talkFooter .e

  • solid.js响应式createSignal 源码解析

    目录 正文 createSignal readSignal writeSignal 案例分析 总结 正文 www.solidjs.com/docs/latest… createSignal 用来创建响应式数据,它可以跟踪单个值的变化. solid.js 的响应式实现参考了 S.js,它是一个体积超小的 reactive 库,支持自动收集依赖和简单的响应式编程. createSignal createSignal 首先我们来看下 createSignal 的声明: // packages/soli

  • Vue 中 template 有且只能一个 root的原因解析(源码分析)

    引言 今年, 疫情 并没有影响到各种面经的正常出现,可谓是络绎不绝(学不动...).然后,在前段时间也看到一个这样的关于 Vue 的问题, 为什么每个组件 template 中有且只能一个 root? 可能,大家在平常开发中,用的较多就是 template 写 html 的形式.当然,不排除用 JSX 和 render() 函数的.但是,究其本质,它们最终都会转化成 render() 函数.然后,再由 render() 函数转为 Vritual DOM (以下统称 VNode ).而 rende

  • 详解vue3 响应式的实现原理

    目录 核心设计思想 Vue.js 2.x 响应式 Vue.js 3.x 响应式 依赖收集:get 函数 派发通知:set 函数 总结 源码参考 核心设计思想 除了组件化,Vue.js 另一个核心设计思想就是响应式.它的本质是当数据变化后会自动执行某个函数,映射到组件的实现就是,当数据变化后,会自动触发组件的重新渲染.响应式是 Vue.js 组件化更新渲染的一个核心机制. Vue.js 2.x 响应式 我们先来回顾一下 Vue.js 2.x 响应式实现的部分: 它在内部通过 Object.defi

  • Vue中的数据监听和数据交互案例解析

    现在我们来看一下vue中的数据监听事件$watch, js代码: new Vue({ el:"#div", data:{ arr:[1,2,3] } }).$watch("arr",function () { alert("数据改变了") }) html代码: <div id="div"> <input type="button" value="改变" @click=&

随机推荐