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

怎样可以做网站十大放黄不登录不收费

怎样可以做网站,十大放黄不登录不收费,广州哪里能看海,wordpress optimizer前言 前面我们实现了基本的数据更新到视图渲染的逻辑,但是这种方式(innerHTML)是极其低效的, 因此,我们相应引入 dom 和 diff 算法, 数据到视图的过程变为: state -> vdom -> dom vNode 层 所谓 vNode, 就是一个表示 dom 结构的轻量对象 {tag, props, children; }为…

前言

前面我们实现了基本的数据更新到视图渲染的逻辑,但是这种方式(innerHTML)是极其低效的, 因此,我们相应引入 dom 和 diff 算法, 数据到视图的过程变为:

state -> vdom -> dom

vNode 层

所谓 vNode, 就是一个表示 dom 结构的轻量对象

{tag, props, children;
}

为了方便创建, 引入创建一个创建节点的方法h

export function h(tag, props, children) {return {tag,props,children,};
}

我们需要修改 render 函数, 让其返回一个创建好的 vNode(vTree)

render(context) {return h('div',{id: 'id-1',class: 'class-1'},[h('p', null, String(context.value)), h('p', null, String(context.value))])},

接下来对返回的 vTree 挂载到真实的节点

let subTree = rootComponent.render(context);
mountElement(subTree, rootContainer);

mountElement 的实现逻辑

  1. 根据标签创建元素
  2. 更新属性
  3. 如果子节点为文本节点,直接创建, 若为数组,则递归创建
export function mountComponent(vnode, container) {const { tag, props, children } = vnode;// taglet ele = document.createElement(tag);// propsfor (const key in props) {if (Object.hasOwnProperty.call(props, key)) {const value = props[key];ele.setAttribute(key, value);}}/* children1. string2. object*/if (typeof children === "string") {const textNode = document.createTextNode(children);ele.appendChild(textNode);} else if (isArray(children)) {children.forEach((vnode) => {mountComponent(vnode, ele);});}container.appendChild(ele);
}function isArray(ele) {return typeof ele.sort === "function";
}

diff 算法

除了第一次挂载需要生成所有节点以外, 新的更新是在旧的基础上"缝缝补补", 这个差量更新的过程交给我们的 diff 算法

我们用一个变量isMounted来将挂载和更新两阶段分开

export default function createApp(rootComponent) {return {mount(rootContainer) {let context = rootComponent.setup();let isMounted = false;let oldSubTree;effectWatch(() => {if (!isMounted) {isMounted = true;let subTree = (oldSubTree = rootComponent.render(context));mountElement(subTree, rootContainer);} else {let newSubTree = rootComponent.render(context);diff(newSubTree, oldSubTree);oldSubTree = newSubTree;}});},};
}

接下来我们就可以处理diff的逻辑了, 需要分别对tag,props,children的变更做处理,

因为 diff 的郭恒要对真实的 dom 节点进行操作, 在 mounted 过程中将 dom 渲染完成后,我们需要将其挂载到对应的 vNode 上

export function mountElement(vNode, container) {// ...let ele = (vNode.el = document.createElement(tag));// ...
}
  1. tag 变化的处理 ,这里用到了原生的replaceWith操作方法
if (newTree.tag !== oldTree.tag) {oldTree.el.replaceWith(document.createElement(newTree.tag));
}
  1. props 节点的处理
newTree.el = oldTree.el;
// props, 对比两个对象, 各自遍历一遍,找出各自不同的地方
let { props: newProps } = newTree;
let { props: oldProps } = oldTree;
if (newProps && oldProps) {Object.keys(newProps).forEach((key) => {// 同时存在,意味着需要更新节点let newVal = newProps[key];if (Object.hasOwnProperty.call(oldProps, key)) {let oldVal = oldProps[key];if (newVal !== oldVal) {newTree.el.setAttribute(key, newVal);}} else {// 旧的不存在, 创建newTree.el.setAttribute(key, newVal);}});
}
// 移除已不存在的旧节点
if (oldProps) {Object.keys(oldProps).forEach((key) => {if (!Object.hasOwnProperty.call(newProps, key)) {newTree.el.removeAttribute(key);}});
}

当然, 为了演示, 这里的处理过程比较简单,

  1. children 的处理

chilren 的处理相对比较麻烦,为了简化, 目前根据 children 的类型区分

即: newChildren[string, array] * oldChildren[array, string] = 4 种情况

前三种比较简单

let { children: oldChildren } = oldTree;
let { children: newChildren } = newTree;
if (typeof newChildren === "string") {if (typeof oldChildren === "string") {if (newChildren !== oldChildren) {newTree.el.textContent = newChildren;}} else if (isArray(oldChildren)) {newTree.el.textContent = newChildren;}
} else if (isArray(newChildren)) {if (typeof oldChildren === "string") {newTree.el.textContent = ``;mountElement(newTree, newTree.el);} else if (Array.isArray(oldChildren)) {// ...}
}

下面分析两者都是数组的情况, 为了简化, 只对节点的长度作处理,不处理相同长度内的节点移位操作

// 暴力解法: 只对节点的长度作处理,不处理相同长度内的节点移位操作
const length = Math.min(newChildren.length, oldChildren.length);
// 更新相同长度的部分
for (var index = 0; index < length; index++) {let newTree = newChildren[index];let oldTree = oldChildren[index];diff(newTree, oldTree);
}
// 创建
if (newChildren.length > oldChildren.length) {for (let index = length; index < newChildren.length; index++) {const newVNode = newChildren[index];mountElement(newVNode, newTree.el);}
}
// 删除
if (oldChildren.length > newChildren.length) {for (let index = length; index < oldChildren.length; index++) {const vNode = oldChildren[index];vNode.el.remove(); // 节点移除自身}
}

本文首发于个人 Github前端开发笔记,由于笔者能力有限,文章难免有疏漏之处,欢迎指正

http://www.15wanjia.com/news/56257.html

相关文章:

  • 公司网站建设的请示ai智能营销系统
  • 闵行做网站站长工具seo排名查询
  • 网站建设太仓百度怎么做广告
  • 网站备案怎么注销百家号官网
  • 做公众号用什么网站seo如何优化图片
  • 有关应用网站石家庄新闻
  • 郑州做网站的公司有哪些个人域名注册流程
  • 苏州高端模板建站推广链接怎么自己搞定
  • 成都网站制作成都网站制作it培训班出来工作有人要么
  • 网站设计贵不贵爱站长工具
  • 政和网站建设wzjseo台州网站seo
  • php做的网站优缺点网站排行
  • 一个专门做ppt的网站营业推广的形式包括
  • 济南优化网站方法西安百度竞价外包
  • 工具类网站做排名交换链接的例子
  • 赌博游戏网站怎么做沪深300指数
  • 外贸网站建设注意湖人队最新消息
  • 优秀作文网站推荐刷钻业务推广网站
  • 外国购物网站设计风格seo网络优化公司哪家好
  • 学做网站去哪学设计一个简单的网页
  • 网站如何快速被百度收录促销活动推广方案
  • 做网站挣钱快吗安徽网站关键词优化
  • c mvc网站开发网页优化包括
  • 政府网站建设工作存在的不足首页关键词排名
  • 新郑做网站搜索引擎的营销方法有哪些
  • 免费网站建设软件有哪些今日新闻摘抄
  • 菏泽网站开发网站免费软件
  • 做传奇私服网站有钱赚吗攀枝花网站seo
  • 如何快速找到做网站的客户百度网页版 入口
  • 网站建设模板是什么电商具体是做什么的