vue模板的首次渲染,和重新渲染,有哪些区别?
搞明白这个,能帮助我们理解开发中出现的很多问题。
一、我们先来回顾一下vue模板的渲染过程:
(1)执行render函数,生成虚拟DOM。
render函数是根据render、templete、el这三个选项得来的,优先级依次降低。如果有render函数,则直接使用;否则如果有templete选项,则把templete作为模板编译成render函数;否则把el的outerHTML作为模板编译成render函数。单页面组件中,使用<templete>标签作为模板编译成render函数。
render函数首次执行时,会触发模板依赖数据的getter,getter会记录哪个模板用到了自己,同时模板也会记录自己用到了哪些属性,这个过程叫依赖收集。
每次模板重新渲染时,模板中的表达式、methods函数、全局函数都会重新执行。因为render函数就是个函数,当它执行时,里面的表达式和函数都会跟着执行。但这里面有一个例外,就是计算属性,因为计算属性会缓存结果,多用计算属性是个好习惯。
(2)虚拟DOM和数据结合,生成真实的DOM。
(3)如果不是首次渲染,生成的虚拟DOM会和原来的进行比较,通过diff算法,计算出来最少的需要更新的DOM。
(4)如果是首次渲染,把DOM挂载到页面中。如果是重新渲染,则更新DOM。这一步是vue能影响的最后一步。
(5)浏览器渲染页面。这一步是浏览器渲染进程操作的,和vue无关。但vue可以在上一步里,计算出DOM的最小更新,来尽量避免回流和重绘。
二、首次渲染和重新渲染的不同
vue从创建实例,到mounted执行结束,这一整个生命周期是一个同步的过程。意味着,如果你试图在created前加async,来让异步数据获取完成后再进入beforeMount钩子,是没用的。
模板的首次渲染,也是一个同步的过程。它是从beforeMount的同步代码结束开始,同步的生成虚拟DOM、真实DOM、挂载到页面这一系列操作之后,最后进入mounted钩子。
要注意的是,我们通常习惯在created里异步获取数据,异步数据是不会参与到模板的首次渲染中的。模板首次渲染采用的数据,是prop、data、计算属性的初始值,更准确的说,是render函数开始执行之前的数据。那么,在beforeCreate、created、beforeMount里对数据进行的同步操作,是会作用于模板的首次渲染的。
但是,从模板首次渲染完成开始,也就是从进入mounted钩子开始,之后的渲染逻辑就完全不一样了,被称为异步更新队列。如果说首次渲染是生命周期驱动的,那么重新渲染,就是数据的变化驱动的。
当模板所依赖的属性被重新赋值时,该属性的setter被触发。因为这个属性记录了哪些模板用到了自己,它就通知这些模板的Watcher进入微任务队列。在同一个事件循环中,如果一个模板所依赖的多个属性发生改变,它不会被重复放入到微任务队列。这就是我们所熟悉的,多次修改数据,vue只会更新DOM一次。
哪些操作会导致模板的重新渲染呢?从mounted钩子开始,所有对模板依赖数据的更改,都会导致模板的重新渲染。
比如,在mounted中同步修改数据,在浏览器事件中修改数据,在created中异步获取数据后修改数据等。
三、所以,知道这些有什么用?
(1)在给data中的属性设初始值时,要考虑健壮性。不要忘了,这些初始值会用于模板的首次渲染。
在开发中我们经常犯这样的错误,就是没有考虑data初始值对首次渲染的兼容。当然,有个好处是代码会报错,帮助我们发现错误。
给我们的启发是什么呢?对data赋初值,能多赋,不要少赋。我以前喜欢把所有属性初始值都设为null,这个习惯很不好,容易出错,至少应该用[]、''、0这些代替null。
(2)开发中经常出现,进入页面后某个元素闪一下没了。
是因为我们在这个元素使用了v-if,首次使用初始值渲染时是有的,后面异步获取数据后重新计算就没了,所以会闪一下。
为了避免这个问题,我们应该养成一个习惯,就是元素默认是不显示的,拿到异步数据后再决定是否显示,这样就避免了闪一下的情况出现。如果在元素上再加一个进入动画,就更好了。
vue模板的首次渲染,和重新渲染,有哪些区别?的更多相关文章
- 【Vue】Vue框架常用知识点 Vue的模板语法、计算属性与侦听器、条件渲染、列表渲染、Class与Style绑定介绍与基本的用法
Vue框架常用知识点 文章目录 Vue框架常用知识点 知识点解释 第一个vue应用 模板语法 计算属性与侦听器 条件渲染.列表渲染.Class与Style绑定 知识点解释 vue框架知识体系 [1]基 ...
- Vue源码探究-虚拟DOM的渲染
Vue源码探究-虚拟DOM的渲染 在虚拟节点的实现一篇中,除了知道了 VNode 类的实现之外,还简要地整理了一下DOM渲染的路径.在这一篇中,主要来分析一下两条路径的具体实现代码. 按照创建 Vue ...
- Vue 列表渲染及条件渲染实战
条件渲染 有时候我们要根据数据的情况,决定标签是否进行显示或者有其他动作.最常见的就是,表格渲染的时候,如果表格没有数据,就显示无数据.如果有数据就显示表格数据. Vue 帮我们提供了一个v-if的指 ...
- 细说后端模板渲染、客户端渲染、node 中间层、服务器端渲染(ssr)
细说后端模板渲染.客户端渲染.node 中间层.服务器端渲染(ssr) 前端与后端渲染方式的发展大致经历了这样几个阶段:后端模板渲染.客户端渲染.node 中间层.服务器端渲染(ssr). 1. 后端 ...
- Vue躬行记(7)——渲染函数和JSX
除了可通过模板创建HTML之外,Vue还提供了渲染函数和JSX,前者的编码自由度很高,后者对于开发过React的人来说会很熟悉.注意,Vue的模板最终都会被编译成渲染函数. 一.渲染函数 虽然在大部分 ...
- 基于Vue的单页面应用的Markdown渲染
之前渲染 Markdown 的时候, 笔者使用的是 mavonEditor 的预览模式, 使用起来比较爽, 只需要引入组件即可, 但是在最近的开发中, 遇到了困难. 主要问题在于作为单页面应用, 站内 ...
- vue中数据接收成功,页面渲染失败
1.vue中数据接收成功,页面渲染失败.代码如下 经过查找资料修改代码为 或是 原因是: 由于 JavaScript 的限制, Vue 不能检测以下变动的数组: 当你利用索引直接设置一个项时,例如: ...
- Vue学习笔记(三)条件渲染和循环渲染
目录 一.条件渲染 1. v-if 2. 与v-else配合使用 3. 与v-else-if配合使用 4. v-show的使用 5. 类型切换案例 二.列表渲染 1. 遍历数组 2. 遍历对象 获取v ...
- Vue学习计划基础笔记(三)-class与style绑定,条件渲染和列表渲染
Class与style绑定.条件渲染和列表渲染 目标: 熟练使用class与style绑定的多种方式 熟悉v-if与v-for的用法,以及v-if和v-for一起使用的注意事项 class与style ...
- vue 模板如何解析
1.模板 一个最简答的模板: <div id="app"> {{ message }} </div> v-for模板: <ul id="ex ...
随机推荐
- 分布式应用开发的核心技术系列之——基于TCP/IP的原始消息设计
本文由葡萄城技术团队原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 本文的内容主要围绕以下几个部分: TCP/IP的简单介绍. 消息的介绍 ...
- LLM探索:为ChatGLM2的gRPC后端增加连续对话功能
前言 之前我做 AIHub 的时候通过 gRPC 的方式接入了 ChatGLM 等开源大模型,对于大模型这块我搞了个 StarAI 框架,相当于简化版的 langchain ,可以比较方便的把各种大模 ...
- 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(10) -- 在DataGrid上直接编辑保存数据
有时候,一些数据的录入可能需要使用表格直接录入会显得更加方便快捷,这种情况有时候也是由于客户使用习惯而提出,本篇随笔介绍在WPF应用端上使用DataGrid来直接新增.编辑.保存数据的处理. 录入数据 ...
- ES6入门(一)
1.let声明的变量只在let命令所在的代码块内有效 2.不存在变量提升,先使用变量,后定义变量,就会报错. 3.let不允许在相同作用域内,重复声明同一个变量.
- IoC容器趣谈
今天我们来谈谈Spring的内核之一--IoC容器 大家可能会有这样的疑问: "这玩意为啥要叫容器呢?好奇怪" "容器不是装东西的吗?难道IoC容器也是用来装什么东西的? ...
- 🔥🔥Java开发者的Python快速进修指南:控制之if-else和循环技巧
简单介绍 在我们今天的学习中,让我们简要了解一下Python的控制流程.考虑到我们作为有着丰富Java开发经验的程序员,我们将跳过一些基础概念,如变量和数据类型.如果遇到不熟悉的内容,可以随时查阅文档 ...
- C语言根据公式Cnm= 算出从n个不同元素中取出m个元素(m≤n)的组合数。建议定义和调用函数fact(n)计算n!,其中n的类型是int,函数类型是double。
/* 开发者:慢蜗牛 开发时间:2020.5.28 程序功能:开发公式Cnm */ #include<stdio.h> long fact_1(int m); long fact_2(in ...
- Cassandra中的MerkleTree反熵机制
构建MerkleTree Cassandra 是一个分布式数据库系统,它使用 Merkle 树来实现数据一致性和数据完整性的验证. 在 Cassandra 中,每个节点都维护着自己的数据副本.为了确保 ...
- .NET8 依赖注入
依赖注入(Dependency Injection,简称DI)是一种设计模式,用于解耦组件(服务)之间的依赖关系.它通过将依赖关系的创建和管理交给外部容器来实现,而不是在组件(服务)内部直接创建依赖对 ...
- Jupyter Notebook 使用与安装
简介 Jupyter Notebook就是以网页的形式打开,可以在网页页面中直接编写代码和运行代码,代码的运行结果也会直接在代码块下显示的程序.如在编程过程中需要编写说明文档,可在同一个页面中直接编写 ...