Skip to content

1. 接口定义 ​

本节目标:理解“1. 接口定义”的核心思路,并能把它用于实际开发或面试表达。

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

我们MVVM的框架接口和Vue3一模一样。
初始化需要确定
视图模板
数据模型
模型行为 - 比如我们希望click的时候数据模型的message会会倒序排列。
const App = {
  // 视图
  template: `
  <input v-model="message"/>
  <button @click='click'>{{message}}</button>
  `,
  setup() {
    // 数据劫持
    const state = new Proxy(
      {
        message: "Hello Vue 3!!",
      },
      {
        set(target, key, value, receiver) {
          const ret = Reflect.set(target, key, value, receiver);
          // 触发函数响应
          effective();
          return ret;
        },
      }
    );
    const click = () => {
      state.message = state.message.split("").reverse().join("");
    };
    return { state, click };
  },
};
const { createApp } = Vue;
createApp(App).mount("#app");
**2.** **程序骨架**
const Vue = {
  createApp(config) {
    // 编译过程
    const compile = (template) => (content, dom) => {
    };
    // 生成渲染函数
    const render = compile(config.template);
    return {
      mount: function (container) {
        const dom = document.querySelector(container);
        // 实现setup函数
        const setupResult = config.setup();
        // 数据响应更新视图
        effective = () => render(setupResult, dom);
        render(setupResult, dom);
      },
    };
  },

};
**3.** **编译渲染函数**
MVVM框架中的渲染函数是会通过视图模板的编译建立的。
// 编译函数
// 输入值为视图模板
const compile = (template) => {
  //渲染函数
  return (observed, dom) => {
    // 渲染过程
  }
}
简单的说就是对视图模板进行解析并生成渲染函数。
大概要处理以下三件事
确定哪些值需要根据数据模型渲染
// <button>{{message}}</button>
// 将数据渲染到视图
button = document.createElement('button')
button.innerText = observed.message
dom.appendChild(button)
绑定模型事件
// <button @click='click'>{{message}}</button>
// 绑定模型事件
button.addEventListener('click', () => {
  return config.methods.click.apply(observed)
})
确定哪些输入项需要双向绑定
// <input v-model="message"/>
// 创建keyup事件监听输入项修改
input.addEventListener('keyup', function () {
  observed.message = this.value
})
完整的代码
const compile = (template) => (observed, dom) => {
  // 重新渲染
  let input = dom.querySelector('input')
  if (!input) {
    input = document.createElement('input')
    input.setAttribute('value', observed.message)
    input.addEventListener('keyup', function () {
      observed.message = this.value
    })
    dom.appendChild(input)
  }
  let button = dom.querySelector('button')
  if (!button) {
    console.log('create button')
    button = document.createElement('button')
    button.addEventListener('click', () => {
      return config.methods.click.apply(observed)
    })
    dom.appendChild(button)
  }
  button.innerText = observed.message
}

本站总访问 — 次