Skip to content

src-modules ​

本节目标:理解“src-modules”的核心思路,并能把它用于实际开发或面试表达。

说明:原 OneNote 中有图片引用,但图片未包含在导出目录中;本页保留了可用的文字与代码内容。

attr.ts
export function patchAttr(el, key, nextValue) {
  if (nextValue) {
    el.setAttribute(key, nextValue);
  } else {
    el.removeAttribute(key);
  }
}
class.ts
export function patchClass(el, nextValue) {
  if (nextValue == null) {
    // 如果不需要class直接移除
    el.removeAttribute('class');
  } else {
    el.className = nextValue
  }
}
style.ts
export function patchStyle(el, prevValue, nextValue = {}) {
  // 样式需要比对差异
  for (let key in nextValue) {
    // 用新的直接覆盖即可
    el.style[key] = nextValue[key];
  }
  if (prevValue) {
    for (let key in prevValue) {
      if (nextValue[key] == null) {
        el.style[key] = null;
      }
    }
  }
}
event.ts
function createInvoker(callback) {
  const invoker = (e) => invoker.value(e);
  invoker.value = callback;
  return invoker
}
如果之前有且现在还有同名事件,就更新事件回调函数即可;
如果之前存在同名事件,现在没有同名事件,要移除事件绑定;
如果之前不存在此名称事件,现在有了,则增加事件
export function patchEvent(el, eventName, nextValue) {
  // 事件绑定都缓存到了当前dom上
  // 可以先移除掉事件,再重新绑定事件
  // 但 add + 自定义事件 (里面调用绑定的方法)更佳
  let invokers = el._vei || (el._vei = {});
  let exits = invokers[eventName]; // 先看有没有缓存过
  // 如果绑定的是一个空
  if (exits && nextValue) { // 已经绑定过事件了
    exits.value = nextValue; // 没有卸载函数,只是改了invoker.value 属性
  } else {
    // 有!exits&&nextValue和exist&&!nextValue两种情况
    let event = eventName.slice(2).toLowerCase();
    if (nextValue) { // 只能是!exits才可以满足,不存在则创建事件
      const invoker = invokers[eventName] = createInvoker(nextValue);
      el.addEventListener(event, invoker)
    } else if (exits) {
     // 只有!nextValue满足,如果有老值,需要将老的绑定事件移除掉
      el.removeEventListener(event, exits);
      invokers[eventName] = undefined
    }
  }
}

本站总访问 — 次