Vue 如何关掉响应式问题

目录
  • Vue如何关掉响应式
    • 例子
    • v-once
  • Vue响应式的处理过程

Vue如何关掉响应式

大家都知道Vue有双向数据绑定 ,但是很少人知道怎样把它这个功能关掉

比如想要让某个值的改变不改变原有值

使用 Object.freeze(),这会阻止修改现有的 property,也意味着响应系统无法再追踪变化。

例子

var obj = {
  foo: 'bar'
}

Object.freeze(obj)

new Vue({
  el: '#app',
  data: obj
})
<div id="app">
  <p>{{ foo }}</p>
  <!-- 这里的 `foo` 不会更新! -->
  <button v-on:click="foo = 'baz'">Change it</button>
</div>

额外 Vue 也为大家提供了一个 只能修改数据一次的方法

v-once

通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:

<span v-once>这个将不会改变: {{ msg }}</span>

Vue响应式的处理过程

响应式是从vue实例的init方法开始的。

在Init方法中先调用initState()初始化vue实例的状态,在这个方法中调用了initData(),initData()是把我们的data属性注入到vue实例上,并且调用observe()把data对象转换成响应式对象。于是observe()就是我们响应式的入口。

observe()做了什么事情:observe接收一个参数value,这个参数value就是我们响应式要处理的对象。

那么在创建observe对象时做了什么事:来看他的构造函数

数组的响应式处理:其实就是设置数组的那几个特殊方法,比如push,pop,sort等等,这些方法会改变原数组,所以当这些方法被调用的时候,我们要去发送通知。发送通知的时候是找到数组对象对应的ob,也就是observe对象,在找到这个observe中的dep,调用dep的notify方法。更改完数组的特殊方法之后,遍历数组的每一个成员,对每一个成员再去调用observe,如果这个成员是对象的话,也会把这个对象转换成响应式对象。

对象的响应式处理:如果当前的value是对象的话,此时会调用walk()方法。Walk方法里面会遍历这个对象的所有属性,对每一个属性调用defineReactive()。

在defineReactive中,会为每一个属性创建dep对象,让dep去收集依赖。如果当前属性的值是对象,则会调用observe,把这个对象也转换成响应式对象。

在defineReactive里最核心的事情就是定义getter和setter。

在getter中去收集依赖,收集依赖时要为每一个属性收集依赖,如果这个属性的值是对象,他也要为这个子对象收集依赖,在getter中最终返回这个属性的值。

在setter中首先要把新的值保存下来,如果新的值是对象,就调用observe,把我们新设置的值也转换成响应式对象。在setter中,数据发生了变化,所以要发送通知,其实就是调用dep.notify()。

收集依赖的过程:

在收集依赖时,首先要调用watcher对象的get方法,在get方法中调用pushTarget,在pushTarget中会把当前的watcher对象记录到Dep.target属性中。

在访问data中成员的时候去收集依赖,当我们访问这个属性的值的时候,就会去触发defineReactive中的getter,在getter中去收集依赖。他会把我们属性对应的watcher对象添加到dep的subs数组中,也就是为属性收集依赖。如果这个属性的值也是对象,此时要创建一个childOb对象,要为我们这个子对象收集依赖。目的是将来子对象发生变化时可以发送通知。(其实数组中内容发生变化时,就用到了这个childOb)。

Wacher:当数据发生变化时,会调用dep.notify()发送通知,他会调用wacher的update方法,在wacher的update方法中,会去调用queueWatcher函数去判断wacher是否被处理了,如果这个wacher对象没有被处理,则会被添加到queue队列中,并且调用flushSchedulerQueue去刷新任务队列。

在flushSchedulerQueue函数中会触发beforeUpdate钩子函数,然后调用wacher.run()方法,在wacher.run方法中去调用wacher的get方法去调用getter方法,而getter中存储的其实就是updateComponent(此处针对渲染wacher来说的)。在wacher.run运行完成后就已经将数据更新到了视图上,我们就可以再页面上看见变化了,剩下一些清理工作。

他会去清空我们上一次的依赖,重置wacher中的状态,接下来去触发actived钩子函数,最后触发updated钩子函数。

这就是整个响应式的处理过程。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 深度解析 Vue3 的响应式机制

    目录 什么是响应式 响应式原理 定制响应式数据 Vueuse 工具包 什么是响应式 响应式一直都是 Vue 的特色功能之一:与之相比,JavaScript 里面的变量,是没有响应式这个概念的:你在学习 JavaScript 的时候首先被灌输的概念,就是代码是自上而下执行的: 我们看下面的代码,代码在执行后,打印输出的两次 double 的结果也都是 2:即使 我们修改了代码中 count 的值后,double 的值也不会有任何改变 let count = 1 let double = count

  • vue视图响应式更新详细介绍

    目录 概述 思路 第一步统一封装更新函数 第二步监听并触发视图更新 引入Dep管家 实现下语法糖v-model 概述 前面两篇文章已经实现了对数据的变化的监听以及模板语法编译初始化,但是当数据变化时,视图还不能够跟随数据实时更新.本文就在之前的基础上介绍下视图响应式更新部分. 思路 统一封装更新函数 待数据发生改变时调用对应的更新函数 这里思考个问题: 在何时注册这个更新函数? 如何找到对应的更新函数? 第一步统一封装更新函数 基于上篇文章compile的部分,将数据初始化的部分统一封装起来.

  • 关于vue2响应式缺陷的问题

    目录 vue2响应式缺陷 1.对象新增的属性没有响应式 2.数组的部分操作没有响应式 vue2与vue3的响应式原理 vue2响应式 vue3响应式雏形 vue3的响应式相较于vue2的优势 vue2响应式缺陷 响应式 : 数据改变 ==> 视图跟着改变 vue2响应式缺陷 1.对象新增的属性没有响应式 对象,新增属性b,修改b的值,值改变但视图并未更新 解决方案 : 使用vue提供的 api $set(对象,属性名,值) 效果如属性c 2.数组的部分操作没有响应式 数组中有7种操作有响应式 a

  • 实现一个VUE响应式属性装饰器详析

    目录 前言 不使用任何的响应Api 使用 reactive 实现 使用 ref 实现 使用装饰器实现 实现Reactive装饰器 实现Watch装饰器 总结 前言 使用面向对象的开发思想难免会用到类,既然有了类,那就应该有实例,然而我们使用类的时候可能需要实例中的某个属性是vue的响应属性,也可能里面的某个方法也可以被vue的watch监听.我就开始琢磨如何通过 Composition API 来实现这个类属性装饰器 不使用任何的响应Api // TestReactive.ts export c

  • vue中响应式布局如何将字体大小改成自适应

    目录 响应式布局将字体大小改成自适应 vue文字大小自适应问题 响应式布局将字体大小改成自适应 1.在app.vue的生命周期函数中添加一段代码来设置页面的rem mounted: function() {     // 页面开始加载时修改font-size     var html = document.getElementsByTagName("html")[0];     var oWidth = document.body.clientWidth || document.doc

  • vue如何使用媒体查询实现响应式

    目录 使用媒体查询实现响应式的两种方式 前提 1.在每个组件中为其使用媒体查询 2.写n套页面,在使用这些页面的组件中进行一次媒体查询 vue中的媒体查询 语法 使用媒体查询实现响应式的两种方式 前提 依赖: sass,sass-loader 1.在每个组件中为其使用媒体查询 这种方法的有点是减少了重写不同终端同一组件的工作量,缺点是每个组件都要使用媒体查询,当一套页面组件不同时,需要进行组件的显示与隐藏(display:none!important),在不同终端区别不大的情况下建议使用这种方法

  • Vue 如何关掉响应式问题

    目录 Vue如何关掉响应式 例子 v-once Vue响应式的处理过程 Vue如何关掉响应式 大家都知道Vue有双向数据绑定 ,但是很少人知道怎样把它这个功能关掉 比如想要让某个值的改变不改变原有值 使用 Object.freeze(),这会阻止修改现有的 property,也意味着响应系统无法再追踪变化. 例子 var obj = {   foo: 'bar' } Object.freeze(obj) new Vue({   el: '#app',   data: obj }) <div id

  • Vue的事件响应式进度条组件实例详解

    写在前面 找了很多vue进度条组件,都不包含拖拽和点击事件,input range倒是原生包含input和change事件,但是直接基于input range做进度条的话,样式部分需要做大量调整和兼容性处理.即使做好了,将来需要修改外观,又是一番折腾. 基于以上两个原因,做了一个可以响应input和change事件(即一个是拖动进度条到某处,一个是在进度条某位置点击使其值变为该位置)的div实现的Vue组件,这样既满足了对进度条事件的需求,也带来了如有需求变动,样式修改很方便的好处. 效果图 以

  • 稍微学一下Vue的数据响应式(Vue2及Vue3区别)

    什么是数据响应式 从一开始使用 Vue 时,对于之前的 jq 开发而言,一个很大的区别就是基本不用手动操作 dom,data 中声明的数据状态改变后会自动重新渲染相关的 dom. 换句话说就是 Vue 自己知道哪个数据状态发生了变化及哪里有用到这个数据需要随之修改. 因此实现数据响应式有两个重点问题: 如何知道数据发生了变化? 如何知道数据变化后哪里需要修改? 对于第一个问题,如何知道数据发生了变化,Vue3 之前使用了 ES5 的一个 API Object.defineProperty Vue

  • 详解实现vue的数据响应式原理

    这篇文章主要是给不了解或者没接触过 vue 响应式源码的小伙伴们看的,其主要目的在于能对 vue 的响应式原理有个基本的认识和了解,如果在面试中被问到此类问题,能够知道面试官想让你回答的是什么?「PS:文中如有不对的地方,欢迎小伙伴们指正」 响应式的理解 响应式顾名思义就是数据变化,会引起视图的更新.这篇文章主要分析 vue2.0 中对象和数组响应式原理的实现,依赖收集和视图更新我们留在下一篇文章分析. 在 vue 中,我们所说的响应式数据,一般指的是数组类型和对象类型的数据.vue 内部通过

  • 深入理解Vue的数据响应式

    1. ES语法的getter和setter 在开始了解 Vue 的数据响应式原理前应该先搞清楚 ES语法 中的 getter 和 setter 方法的具体用法. getter和setter 方法是以 get 和 set 关键字来为对象添加虚拟属性的一种方式.这种属性其实并不真实存在,而是以取值函数 getter 和存值函数 setter 来模拟的一种属性.目的是对某个属性设置存值函数和取值函数,拦截该属性的存取行为,以便于对该属性的存取做一些限定处理.如下所示(以下代码来源于 mdn) gett

  • Vue解读之响应式原理源码剖析

    目录 初始化 initState() initProps() initData() observe() Observer defineReactive() 依赖收集 Dep Watcher 依赖收集过程 移除订阅 派发更新 notify() update() queueWatcher() flushSchedulerQueue() updated() defineProperty 缺陷及处理 Vue.set() 重写数组方法 总结 先看张图,了解一下大体流程和要做的事 初始化 在 new Vue

  • Vue.js3.2响应式部分的优化升级详解

    目录 背景 响应式实现原理 依赖收集 派发通知 副作用函数 响应式实现的优化 依赖收集的优化 响应式 API 的优化 trackOpBit 的设计 总结 背景 Vue 3 正式发布距今已经快一年了,相信很多小伙伴已经在生产环境用上了 Vue 3 了.如今,Vue.js 3.2 已经正式发布,而这次 minor 版本的升级主要体现在源码层级的优化,对于用户的使用层面来说其实变化并不大.其中一个吸引我的点是提升了响应式的性能: More efficient ref implementation (~

  • vue.js数据响应式原理解析

    目录 Object.defineProperty() 定义 defineReactive 函数 递归侦测对象的全部属性 流程分析 observe 函数 Observer 类 完善 defineReactive 函数 One More Thing Object.defineProperty() 得力于 Object.defineProperty() 的特性,vue 的数据变化有别于 react 和小程序,是非侵入式的.详细介绍可以看 MDN 文档,这里特别说明几点: get / set 属性是函数

  • 一文彻底搞懂Vue的MVVM响应式原理

    目录 前言 Vue的MVVM原理 创建一个html示例 在MVue.js中创建MVue入口 创建Compile 1.处理元素节点compileElement(child) 2.处理文本节点compileText(child) 3.实现compileUtil指令处理 更新器Updater更新数据 实现数据观察者Observer 数据依赖器Dep 观察者Watcher 实现视图驱动数据驱动视图 总结 前言 这些天都在面试,每当我被面试官们问到Vue响应式原理时,回答得都很肤浅.如果您在回答时也只是停

  • Vue如何实现响应式系统

    前言 最近深入学习了Vue实现响应式的部分源码,将我的些许收获和思考记录下来,希望能对看到这篇文章的人有所帮助.有什么问题欢迎指出,大家共同进步. 什么是响应式系统 一句话概括:数据变更驱动视图更新.这样我们就可以以"数据驱动"的思维来编写我们的代码,更多的关注业务,而不是dom操作.其实Vue响应式的实现是一个变化追踪和变化应用的过程. vue响应式原理 以数据劫持方式,拦截数据变化:以依赖收集方式,触发视图更新.利用es5 Object.defineProperty拦截数据的set

随机推荐