const App = {render(context) {return h("div", { id: "123", style: "color:red" }, [h("p", null, String(context.state.value)),h("div", { style: "color:blue" }, String(context.state.value * 2)),]);},setup() {const state = reactive({value: 10,});window.state = state; //为了好改值return { state };},};createApp(App).mount(document.getElementById("app"));
实现h函数,该函数为返回vdom
//retrun vdomfunction h(tag, props, children) {return {tag,props,children,};}
实现createApp函数,该函数返回mount方法
function createApp(rootComponent) {return {mount(rootContainer) {const context = rootComponent.setup();effectWatch(() => {rootContainer.innerHTML = "";const subTree = rootComponent.render(context);mountElement(subTree, rootContainer);});},};}
实现mountElement函数,把虚拟dom转为真实dom,这里简单实现一下,直接挂载,不考虑vdom diff
//vdom => domfunction mountElement(vnode, rootContainer) {const { tag, props, children } = vnode;//tagconst el = document.createElement(tag);//propsif (props) {for (const key in props) {const val = props[key];el.setAttribute(key, val);}}//chidren//数组or字符串if (typeof children === "string") {const textNode = document.createTextNode(children);el.append(textNode);} else if (Array.isArray(children)) {children.forEach((child) => {mountElement(child, el);});}rootContainer.append(el);}
参考:
https://dafunk.gitee.io/views/vue/mini-vue-reactive.html https://github.com/mewcoder/codebase/tree/main/mini-vue3 https://github.com/ReySun/vue3-deep-dive-width-evan-you
