手撸mini-vue之注册事件

98 阅读1分钟

首先对之前的happy path进行一下改造

export const App = {
  render() {
    return h(
      "div",
      {
        id: "root",
        class: ["red", "blue"],
        onClick: () => {
          console.log("click");
        },
        onMousedown: () => {
          console.log("mousedown");
        },
      },
      "hi, " + this.msg
    );
  },

  setup() {
    return {
      msg: "mini-vue",
    };
  },
};

接下来我们要实现的就是,鼠标在div上摁下执行mousedown,放开执行click
还记得我们之前在renderer.ts中的mountElement方法中对props进行了操作
注册事件就是在之前对props进行操作的基础上做一些改进

// renderder.ts
function mountElement(vnode, container) {
  const el = (vnode.el = document.createElement(vnode.type));
  
  const { props, shapeFlag, children } = vnode;
  
  ...
  
  for (const key in props) {
    const val = props[key];
    // 正则判断 key 是不是以 on 开头
    const isOn = (key: string) => /^on[A-Z]/.test(key);
    if (isOn(key)) {
      const event = key.slice(2).toLocaleLowerCase();
      el.addEventListener(event, val);
    } else {
      el.setAttribute(key, val);
    }
  }
}