Vuejs设计与实现5-挂载与更新

五、挂载与更新

挂载子元素

DOM Properties != HTML Attributes
但是二者往往(并非所有!)一一对应,如 id="123" 对应 el.id

把 HTML Attributes 与 DOM Properties 具有相同名称(即 id)的属性看作直接映射

核心理念:

  1. HTML Attributes 的作用是设置与之对应的 DOM Properties 的初始值
  2. 一个 HTML Attribute 可以对应多个 DOM Properties
  3. 浏览器有矫正作用,即把不正确的属性值调整为默认值

元素属性

对于布尔类型,空字符串相当于 false
针对属性 disable,我们希望不传入任何参数(即空字符串)时,隐藏元素

这个时候就要加一个判断,当属性为布尔类型且值为空字符串时,手动设置为 true,而不是让浏览器矫正为 false!!!


class 处理

请看下方一段 DOM 以及其对应的 vnode

// 渲染结果
<p class="pig cat"></p>;

// vnode
const vnode = {
  type: "p",
  props: {
    class: "pig cat",
  },
};

设置 class 速度优劣

目前有三种设置 class 的方式,其中速度最快的是使用 el.className

  1. setAttribute
  2. el.className
  3. el.classList

卸载

若要结束渲染,单纯设置 innerHTML 为空是不严谨的;

应当通过 vnode 获取真实 DOM,并使用原生 DOM 操作进行卸载;
下面代码指在挂载 vnode 时自动关联真实 DOM

function mountElement(vnode, container) {
  const el = (vnode.el = createElement(vnode.type));

  ...
}

不同类型 vnode 打补丁流程
  1. 如果旧节点存在且类型不等于新节点,则卸载旧节点并置 null
  2. vnode 可以是普通标签或者组件或者 fragment,要做出判断
function patch(n1, n2, container) {
  if (n1 && n1.type !== n2.type) {
    unmount(n1);
    n1 = null;
  }
  // 代码运行到这里,证明 n1 和 n2 所描述的内容相同
  const { type } = n2;
  // 如果 n2.type 的值是字符串类型,则它描述的是普通标签元素
  if (typeof type === "string") {
    if (!n1) {
      mountElement(n2, container);
    } else {
      patchElement(n1, n2);
    }
  } else if (typeof type === "object") {
    // 如果 n2.type 的值的类型是对象,则它描述的是组件
  } else if (type === "xxx") {
    // 处理其他类型的 vnode
  }
}

事件处理

普通版处理流程:

  1. 添加事件使用 addEventListener
  2. 更新事件,先 removeEventListener 移除事件,再添加新事件

进阶版处理流程:

  1. 绑定一个伪事件处理函数 invoker,设置真正事件处理函数为 invoker.value 的值
  2. 每次更新事件仅需修改 invoker.value 即可
  3. 使用一个对象管理所有的注册事件,避免事件之间的覆盖(原始情况下,后注册的事件会直接覆盖掉前面的)

事件冒泡处理

屏蔽所有绑定时间晚于事件触发时间的事件处理函数的执行


fragment

使用 fragment 片段来描述多个根节点

fragment 实现多根节点实际上就是把根节点全部存在 children 里面了!

描述一个模板标签 template 下存在四个 li 标签,可以用 vnode 这么表示

const vnode = {
  type: Fragment,
  children: [
    { type: "li", children: "1" },
    { type: "li", children: "2" },
    { type: "li", children: "3" },
  ],
};

fragment 本身不会被渲染,故仅渲染其子节点


小结哦!

HTML Attributes 和 DOM Properties

class 属性增强以及设置 class 的三种方式性能优劣分析

卸载操作需要注意的挂载问题

vnode 更新时判据,新旧 vnode 判断是否需要打补丁 patch

props 事件处理与伪事件 invoker 使用

绑定事件的时间与触发事件的时间


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhillery

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值