从render到mount
H函数
interface H_Interface {
tag: string;
props: object | null;
child?: string | any[];
}
const h = (
tag: string,
props: object | null,
child?: string | any[]
): H_Interface => {
return {
tag,
props,
child,
};
};
export default h;
mount函数
interface Vnode_Interface {
tag: string;
props: object | null;
child?: string | any[];
}
const mount = (Vnode: Vnode_Interface): HTMLElement => {
//挂载
let parentNode: HTMLElement = document.createElement(Vnode.tag);
if (Vnode.props) {
for (let key in Vnode.props) {
if (key.startsWith("on")) {
//处理事件
const EventName = key.slice(2).toLocaleLowerCase();
parentNode.addEventListener(EventName, Vnode.props[key]);
} else {
//纯attribute
parentNode.setAttribute(key, Vnode.props[key]);
}
}
}
if (Vnode.child) {
if (Array.isArray(Vnode.child)) {
if (Vnode.child.length) {
for (let i = 0; i < Vnode.child.length; i++) {
if (typeof Vnode.child[i] == "string") {
parentNode.textContent += Vnode.child[i];
} else {
parentNode.appendChild(mount(Vnode.child[i]));
}
}
}
} else {
parentNode.textContent += Vnode.child;
}
}
return parentNode;
};
export default mount;
Vue构造函数
import mount from "./mount";
import h from "./h";
interface H_Interface {
tag: string;
props: object | null;
child?: string | any[];
}
interface Vnode_Interface extends H_Interface {}
interface Vue_Options_Interface {
el?: string;
data?: object | (() => object);
methods?: object;
props?: Array<string> | object;
render?: (
h: (
tag: string,
props: object | null,
child?: string | any[]
) => H_Interface
) => Vnode_Interface;
}
class Vue {
public $root: HTMLElement;
public $data: object | (() => object);
public $methods: object;
public $props: Array<string> | object;
constructor(options: Vue_Options_Interface) {
this.$root = document.querySelector(options.el);
this.$data = options.data
? typeof options.data == "function"
? options.data()
: options.data
: null;
this.$methods = options.methods ? options.methods : null;
// this.$props = options.props ? options.props : null;
if (this.$data) {
for (let key in this.$data) {
this[key] = this.$data[key];
}
}
if (this.$methods) {
for (let key in this.$methods) {
this[key] = this.$methods[key];
}
}
//beforMount
this.$root.appendChild(mount(options.render(h)));
//mounted
}
}
export default Vue;
测试code
import Vue from "./vue";
const vm = new Vue({
el: "#app",
data() {
return {
msg: "zz",
};
},
methods: {
say() {
console.log(this.msg);
},
},
render(h) {
return h("h1", { id: "red" }, [
"hello",
"world",
h("span", { class: "span" }, "i am child"),
h("span", { class: "span" }, "i am child2"),
h("span", { class: "span", id: "lastSpan" }, [
h("i", { class: "i" }, "icon"),
]),
]);
},
});
console.log(vm);
效果--->Vnode成功渲染至指定根节点上


浙公网安备 33010602011771号