1. const App = {
    2. render(context) {
    3. return h("div", { id: "123", style: "color:red" }, [
    4. h("p", null, String(context.state.value)),
    5. h("div", { style: "color:blue" }, String(context.state.value * 2)),
    6. ]);
    7. },
    8. setup() {
    9. const state = reactive({
    10. value: 10,
    11. });
    12. window.state = state; //为了好改值
    13. return { state };
    14. },
    15. };
    16. createApp(App).mount(document.getElementById("app"));

    实现h函数,该函数为返回vdom

    1. //retrun vdom
    2. function h(tag, props, children) {
    3. return {
    4. tag,
    5. props,
    6. children,
    7. };
    8. }

    实现createApp函数,该函数返回mount方法

    1. function createApp(rootComponent) {
    2. return {
    3. mount(rootContainer) {
    4. const context = rootComponent.setup();
    5. effectWatch(() => {
    6. rootContainer.innerHTML = "";
    7. const subTree = rootComponent.render(context);
    8. mountElement(subTree, rootContainer);
    9. });
    10. },
    11. };
    12. }

    实现mountElement函数,把虚拟dom转为真实dom,这里简单实现一下,直接挂载,不考虑vdom diff

    1. //vdom => dom
    2. function mountElement(vnode, rootContainer) {
    3. const { tag, props, children } = vnode;
    4. //tag
    5. const el = document.createElement(tag);
    6. //props
    7. if (props) {
    8. for (const key in props) {
    9. const val = props[key];
    10. el.setAttribute(key, val);
    11. }
    12. }
    13. //chidren
    14. //数组or字符串
    15. if (typeof children === "string") {
    16. const textNode = document.createTextNode(children);
    17. el.append(textNode);
    18. } else if (Array.isArray(children)) {
    19. children.forEach((child) => {
    20. mountElement(child, el);
    21. });
    22. }
    23. rootContainer.append(el);
    24. }

    参考:

    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