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

 更新时间:2022年03月18日 15:52:44   作者:前端碎碎念  
这篇文章主要介绍了vue中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响应式原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue实现页面加载动画效果

    vue实现页面加载动画效果

    这篇文章主要为大家详细介绍了vue实现页面加载动画效果,vue页面出现正在加载的初始页面与实现动画效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • vue 开发企业微信整合案例分析

    vue 开发企业微信整合案例分析

    这篇文章主要介绍了vue 开发企业微信整合,结合具体案例形式分析了vue.js使用企业微信JSSDK实现手机端程序可以和企业微信进行整合功能的相关操作技巧,需要的朋友可以参考下
    2019-12-12
  • element-plus+Vue3实现表格数据动态渲染

    element-plus+Vue3实现表格数据动态渲染

    在Vue中,el-table是element-ui提供的强大表格组件,可以用于展示静态和动态表格数据,本文主要介绍了element-plus+Vue3实现表格数据动态渲染,感兴趣的可以了解一下
    2024-03-03
  • vue复合组件实现注册表单功能

    vue复合组件实现注册表单功能

    这篇文章主要为大家详细介绍了vue复合组件实现注册表单功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • 解决elementui导航折叠卡顿的问题

    解决elementui导航折叠卡顿的问题

    这篇文章主要介绍了解决elementui导航折叠卡顿的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • Vue3引入SVG图标的流程步骤

    Vue3引入SVG图标的流程步骤

    我们在开发 Vue 项目的时候会使用一些前端组件库,例如 Element、Ant Design 等,这些组件库虽然方便,但是也有一些缺点,比如内置的图标太少,例如我们开发医疗、财务、工程等一些前端项目,内置的图标不能满足我们的需求,所以我们常常在Vue项目中引入SVG图标
    2024-09-09
  • Vue errorHandler异常捕获

    Vue errorHandler异常捕获

    这篇文章主要介绍了Vue errorHandler异常捕获,需要的朋友可以参考下
    2023-10-10
  • 浅析Vue中Virtual DOM和Diff原理及实现

    浅析Vue中Virtual DOM和Diff原理及实现

    这篇文章主要为大家详细介绍了Vue中Virtual DOM和Diff原理及实现的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-03-03
  • Vue实现监听某个元素滚动,亲测有效

    Vue实现监听某个元素滚动,亲测有效

    这篇文章主要介绍了Vue实现监听某个元素滚动,亲测有效!具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • 在vue中使用echarts实现飞机航线水滴图词云图效果

    在vue中使用echarts实现飞机航线水滴图词云图效果

    这篇文章主要介绍了在vue中使用echarts实现飞机航线 水滴图 词云图,通过引入中国地图JS文件,会自动注册地图,文中结合示例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-08-08

最新评论