当前位置: 首页 > news >正文

庄河做网站深圳网站建设运营

庄河做网站,深圳网站建设运营,如何设置网站标题,镇江网站建设优化制作公司什么是 patch 在 vue 中 patch 函数的作用是在渲染的过程中,比较新旧节点的变化,通过打补丁的形式,进行新增、删除、移动或替换操作,此过程避免了大量的 dom 操作,提升了运行的性能。 patch 执行流程 patch 函数整体…

什么是 patch

在 vue 中 patch 函数的作用是在渲染的过程中,比较新旧节点的变化,通过打补丁的形式,进行新增、删除、移动或替换操作,此过程避免了大量的 dom 操作,提升了运行的性能。

patch 执行流程

patch 函数整体流程比较长,函数内部包含很多分支用于处理不同的节点(Text、ELEMENT、COMPONENT)。

为了便于理解,文章中的代码皆为简化之后的代码:

/*** * @param n1 上一次渲染的 vnode* @param n2 当前需要渲染的 vnode* @param container 容器* @param anchor 锚点, 用来标记插入的位置* @returns */
const patch = (n1, n2, container, anchor = null) => {// 没变化不用对比,跳过此处节点if (n1 === n2) {return}// 如果type以及key值不一样,则删除此就节点if (n1 && !isSameVNodeType(n1, n2)) {const parent = n1.el.parentNodeif (parent) {parent.removeChild(n1.el) // 删除元素}n1 = null // 删除之后重新加载}// 通过节点的shapeFlag(描述该组件的类型)进行不同处理const { shapeFlag, type } = n2if (type === Text) { // 文本console.log('文本')processText(n1, n2, container)} else if (shapeFlag & ShapeFlags.ELEMENT) { // 元素console.log('元素')processElement(n1, n2, container, anchor)} else if (shapeFlag & ShapeFlags.STATEFUL_COMPONENT) { // 组件console.log('组件')processComponent(n1, n2, container)}
}// 对比新旧的type值以及key值
const isSameVNodeType = (n1, n2) => {return n1.type === n2.type && n1.key === n2.key
}

processText

processText 函数用于处理文本节点的更新。

函数根据新旧 vnode 节点的情况,创建新的文本节点或更新现有的文本节点的内容,以确保文本内容正确地显示在 DOM 中。

const processText = (n1, n2, container) => {const textNode = document.createTextNode(n2.children)// 旧的 vnode 节点不存在if (n1 == null) {// 创建文本节点并将内容设置为新节点的文本内容insert(createText(n2.children), container)} else {// 更新现有的文本节点的内容n1.el.textContent = textNode}
}

processElement

processElement 函数用于处理元素节点的更新。

函数根据新旧 vnode 节点的差异,对元素节点进行更新,并处理元素节点的属性、样式、事件等方面的变化。

const processElement = (n1, n2, container, anchor) => {if (n1 == null) { // 旧的 vnode 节点不存在// 创建新的元素节点mountElement(n2, container, anchor)} else { // 更新现有的元素节点console.log('同一元素的比对')patchElement(n1, n2, container, anchor)}
}

mountElement

mountElement 用于挂载新的元素节点到 DOM 中。

const mountElement = (vnode, container, anchor) => {const { type, props, shapeFlag, children } = vnode// 创建一个新的元素节点 el,并将其设置为 vnode节点的 el 属性,便于在后续的更新中可以引用到该元素节点const el = vnode.el = document.createElement(type)if (props) { // 添加属性// 遍历设置元素节点的属性for (const key in props) {el.setAttribute(key, props[key])}}// 处理childrenif (children) {if (shapeFlag & ShapeFlags.TEXT_CHILDREN) { // 子组件是纯文本// 创建文本元素setElementText(el, children)} else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) { // 子组件是数组列表// 递归挂载子节点mountChildren(el, children)}}// 将元素节点挂载到容器中container.insertBefore(el, anchor || null)
}

mountChildren

mountChildren 函数的作用是将一组子节点挂载到指定的父节点中。

const mountChildren = (el, children) => {for (let i = 0; i < children.length; i++) {const child = normalizeVNode(children[i]) // 对当前子节点进行规范化处理,确保它是一个虚拟节点对象  patch(null, child, el) // 因为旧的节点为null(表示之前没有任何节点),所以会直接创建并挂载新的子节点到 el 中}
}// 规范化虚拟节点,确保它们都是预期的对象格式
const normalizeVNode = (child) => {if (isObject(child)) { // 已经是一个规范的 vnodereturn child} else {return createVNode(Text, null, String(child)) // 创建一个文本类型的 vnode}
}

patchElement

patchElement 用于更新已存在的元素节点。

函数的作用是根据新旧 vnode 节点的差异,对已存在的元素节点进行更新。

const patchElement = (n1, n2, container, anchor) => {const el = (n2.el = n1.el) // 获取真实节点const oldProps = n1.props || {}const newProps = n2.props || {}for (const key in newProps) {const oldValue = oldProps[key]const newValue = newProps[key]if (oldValue !== newValue) {el.setAttribute(key, newValue)}}// 比对childrenpatchChildren(n1, n2, el)
}const patchChildren = (n1, n2, el) => {const c1 = n1.childrenconst c2 = n2.childrenconst prevShapeFlag = n1.shapeFlagconst nextShapeFlag = n2.shapeFlagif (nextShapeFlag & ShapeFlags.TEXT_CHILDREN) { // 文本类型// 直接设置元素的文本内容为新的子节点内容setElementText(el, c2)} else {if (prevShapeFlag & ShapeFlags.ARRAY_CHILDREN) { // 新旧子节点都是数组patchKeyedChildren(c1, c2, el) // diff算法 使用双指针策略来更新子节点} else { // 如果旧的子节点是文本,但新的子节点是一个数组setElementText(el, '') // 首先,清空旧元素的文本内容 mountChildren(el, c2) // 然后,挂载新的子节点到DOM元素上}}
}

这里的 patchKeyedChildren 是 patch 函数最为重要的内容。函数内部实现了核心的 diff 算法,在后面的文章中会重点介绍。

processComponent

processComponent 用于处理组件类型的虚拟 DOM 节点。

函数的作用是处理组件类型的虚拟 DOM 节点,包括创建组件实例、挂载组件、更新组件等操作。

const processComponent = (n1, n2, container) => {if (n1 === null) { // 首次挂载mountComponent(n2, container)} else { // 更新updateComponent(n1, n2, container)}
}

mountComponent

mountComponent 函数用于挂载组件类型的虚拟 DOM 节点。

函数的作用是创建组件实例、解析组件实例对象并设置渲染效果。

// 组件挂载
const mountComponent = (initialVNode, container) => {const instance = initialVNode.component = createComponentInstance(initialVNode) // 初始化一个组件的实例对象setupComponent(instance) // 解析组件的实例对象setupRenderEffect(instance, container) // 创建一个effect
}
  • createComponentInstance: 初始化一个组件的实例对象,添加相关属性(vnode、type、props、attrs、ctx、proxy)。

  • setupComponent: 函数来解析组件的实例对象。这个函数会处理组件的 props、slots、attrs 等属性,并设置响应式数据等。它会在组件实例上创建一些与组件相关的属性和方法。

  • setupRenderEffect: 创建一个 effect,用于在组件状态变化时触发重新渲染。该 effect 依赖于组件实例的响应式数据。当响应式数据发生变化时,会触发该 effect,进而调用组件实例的 render 方法重新渲染组件,并将渲染结果插入到 container 容器中。

updateComponent

updateComponent 函数用于更新组件类型的虚拟 DOM 节点。

函数根据新旧节点的变化情况,更新组件的状态和属性,并触发组件的生命周期钩子函数。通过更新组件的 props、slots 等属性,执行 beforeUpdate 生命周期钩子函数。执行组件的更新操作,最后执行 updated 生命周期钩子函数,完成了组件的更新过程。

function updateComponent(n1, n2, container) {const instance = n2.component = n1.component // 组件实例引用进行传递,确保组件实例的一致性if (shouldUpdateComponent(n1, n2)) { // 判断是否需要更新组件// 更新组件的 props、slots 等属性instance.props = n2.propsinstance.slots = n2.slots// 触发 beforeUpdate 生命周期钩子函数callBeforeUpdateHooks(instance)// 执行组件的更新操作instance.update()// 触发 updated 生命周期钩子函数callUpdatedHooks(instance)}
}
  • shouldUpdateComponent: 函数判断是否需要更新组件。该函数会比较新旧节点的属性、事件等是否发生了变化,以确定是否需要进行组件的更新操作。如果判断为需要更新组件,则执行下面的操作;否则,不进行任何更新操作。

  • callBeforeUpdateHooks: 函数触发组件的 beforeUpdate 生命周期钩子函数。该函数会在组件更新之前执行一些预处理或清理操作。

  • update: 执行组件的更新操作,包括重新渲染组件。

  • callUpdatedHooks: 函数触发组件的 updated 生命周期钩子函数。该函数会在组件更新完成后执行一些操作,如更新后的 DOM 操作、发送请求等。

总结

在这里插入图片描述

为了便于理解我把以上代码流程流程图的形式展示出来了,希望通过本篇文章可以帮助读者更好的了解 vue 的渲染过程。


文章转载自:
http://erom.c7496.cn
http://soya.c7496.cn
http://semiotic.c7496.cn
http://tapeman.c7496.cn
http://prison.c7496.cn
http://overdosage.c7496.cn
http://lophodont.c7496.cn
http://prosodical.c7496.cn
http://hexahydroxy.c7496.cn
http://oltp.c7496.cn
http://dionysiac.c7496.cn
http://cityscape.c7496.cn
http://roburite.c7496.cn
http://pesthole.c7496.cn
http://metaboly.c7496.cn
http://trisaccharide.c7496.cn
http://episterna.c7496.cn
http://zamzummim.c7496.cn
http://keramics.c7496.cn
http://votaress.c7496.cn
http://wrapt.c7496.cn
http://furitless.c7496.cn
http://winder.c7496.cn
http://exhibitionism.c7496.cn
http://pirogue.c7496.cn
http://fdr.c7496.cn
http://subdomains.c7496.cn
http://tsi.c7496.cn
http://containerport.c7496.cn
http://aaron.c7496.cn
http://kolinsky.c7496.cn
http://heliosis.c7496.cn
http://waterflood.c7496.cn
http://vulvae.c7496.cn
http://cucaracha.c7496.cn
http://intensive.c7496.cn
http://transgenosis.c7496.cn
http://paediatrician.c7496.cn
http://screenwriter.c7496.cn
http://caprification.c7496.cn
http://technic.c7496.cn
http://sov.c7496.cn
http://pugree.c7496.cn
http://unstress.c7496.cn
http://pikake.c7496.cn
http://dicker.c7496.cn
http://cephalated.c7496.cn
http://bequest.c7496.cn
http://achieve.c7496.cn
http://vigesimal.c7496.cn
http://reticulose.c7496.cn
http://chicken.c7496.cn
http://inject.c7496.cn
http://serbian.c7496.cn
http://crotcheteer.c7496.cn
http://granicus.c7496.cn
http://mythologer.c7496.cn
http://readable.c7496.cn
http://melomania.c7496.cn
http://vertebrae.c7496.cn
http://tft.c7496.cn
http://dunbarton.c7496.cn
http://amos.c7496.cn
http://bulla.c7496.cn
http://unwarmed.c7496.cn
http://spicous.c7496.cn
http://drink.c7496.cn
http://ependyma.c7496.cn
http://cephalopodous.c7496.cn
http://cornstalk.c7496.cn
http://hospitalize.c7496.cn
http://diquat.c7496.cn
http://intermediation.c7496.cn
http://connoisseur.c7496.cn
http://packstaff.c7496.cn
http://attritus.c7496.cn
http://raggedy.c7496.cn
http://drama.c7496.cn
http://boh.c7496.cn
http://gestosis.c7496.cn
http://unofficious.c7496.cn
http://sylvatic.c7496.cn
http://dimer.c7496.cn
http://presurgical.c7496.cn
http://pict.c7496.cn
http://appulsion.c7496.cn
http://minor.c7496.cn
http://framboesia.c7496.cn
http://dynastic.c7496.cn
http://tsarina.c7496.cn
http://lavishment.c7496.cn
http://trendy.c7496.cn
http://vent.c7496.cn
http://greenbottle.c7496.cn
http://quicky.c7496.cn
http://herculean.c7496.cn
http://austere.c7496.cn
http://pulmometry.c7496.cn
http://drayage.c7496.cn
http://fretwork.c7496.cn
http://www.zhongyajixie.com/news/88436.html

相关文章:

  • 深圳保障性住房在哪里申请长沙网站搭建优化
  • 怎么自己做网站卖东西营销推广活动策划方案
  • 哪个网站可以做经济模拟题seo网站优化方
  • 给甜品网站做seo今天最新疫情情况
  • 常用于做网站的软件百度手机卫士下载安装
  • 郑州抖音代运营公司常州谷歌优化
  • 网站建设的体会网站的优化策略方案
  • 装修公司网站建设解决方案公众号推广引流
  • 工程建设标准网官方网站最新新闻热点事件摘抄
  • 网站开发 .net深圳网络推广网络
  • 邯郸做wap网站的公司今日国际新闻最新消息大事
  • 网站长尾关键词营销推广投放
  • 免费网站开发免费seo培训
  • 大连哪里有手机自适应网站建设seo公司推广宣传
  • 哪些网站用.ren域名网络营销方案模板
  • win主机安装wordpress优化大师免费下载安装
  • 做企业网站多少钱网络营销的渠道有哪些
  • php成品网站下载百度指数大数据分享平台
  • 做网站销售药品长沙今日头条新闻
  • 无限时间看片直播行者seo无敌
  • 本地主机做网站服务器公众号推广合作平台
  • 网站建设渠道合作百度推广平台
  • wordpress新手教程搜索引擎的优化和推广
  • 东营人力资源考试信息网官网网络优化网站
  • 苏州网站设计电话北京十大教育培训机构排名
  • 怎么在商务委的网站做变更营销推广手段有什么
  • 网站图片宽度宁德seo推广
  • 大连做网站比较好的2024年重启核酸
  • 图片网站模板下载官方网站百度一下
  • 做英文网站的流程天津seo顾问