<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          vue-toy200 行左右代碼模擬 vue 實現(xiàn)

          聯(lián)合創(chuàng)作 · 2023-09-19 17:57

          vue-toy

          npm install --save vue-toy
          

          200行左右代碼模擬vue實現(xiàn)。

          Vue(options)

          interface Options {
              el: HTMLElement | string;
          	propsData?: Record<string, any>;
          	props?: string[];
          	name?: string;
          	data?: () => Record<string, any>;
          	methods?: Record<string, (e: Event) => void>;
          	computed?: Record<string, () => any>;
          	watch?: Record<string, (newValue: any, oldValue: any) => any>;
          	render: (h: typeof React.createElement) => React.ReactNode;
          	renderError?: (h: typeof React.createElement, error: Error) => React.ReactNode;
          	mounted?: () => void;
          	updated?: () => void;
          	destroyed?: () => void;
          	errorCaptured?: (e: Error, vm: React.ReactInstance) => void;
          }

          示例:

          import Vue from "vue-toy";
          
          new Vue({
            el: document.getElementById("root"),
            data() {
              return {
                msg: "hello vue toy"
              };
            },
            render(h) {
              return h("h1", null, this.msg);
            }
          });
          
          

          注1vue-toy不包含template的編譯實現(xiàn),因為vue的template最終是編譯成類似代碼:

          render(h) {
              with(this){
                  return h("h1", null, msg);
              }
          }
          

          本教程中使用了嚴格模式無法使用with,所以在render里無法省略this

          注2vue-toy的視圖渲染使用的react,所以render方法的使用同react#render,如:

          import Vue from "vue-toy";
          import React from "react";
          
          new Vue({
            el: document.getElementById("root"),
            data() {
              return {
                msg: "hello vue toy"
              };
            },
            render() {
              return <h1>{this.msg}</h1>
            }
          });
          

          全局 API

          Vue.component(ComponentOptions)

          interface ComponentOptions {
          	props?: string[];
          	name?: string;
          	data?: () => Record<string, any>;
          	methods?: Record<string, (e: Event) => void>;
          	computed?: Record<string, () => any>;
          	watch?: Record<string, (newValue: any, oldValue: any) => any>;
          	render: (h: typeof React.createElement) => React.ReactNode;
          	renderError?: (h: typeof React.createElement, error: Error) => React.ReactNode;
          	mounted?: () => void;
          	updated?: () => void;
          	destroyed?: () => void;
          	errorCaptured?: (e: Error, vm: React.ReactInstance) => void;
          }

          示例:

          const Hello = Vue.component({
              props: ["msg"],
              render(h){
                  return h('div', null, this.msg);
              }
          });
          export default Hello;

          基本原理

          // 創(chuàng)建觀察對象
          // 觀察對象主要使用的是Object.defineProperty或Proxy來實現(xiàn),
          // 也可使用類似angular.js的臟檢測(不過需要額外的檢測調(diào)用),
          // 如果不在意寫法也可以參考knockout或 setXXX getXXX的方式
          const data = observable({
              name: 'vue-toy',
          });
          
          // 渲染模版
          const render = function(){
              return <h1>{data.name}</h1>
          }
          
          // 計算render的依賴屬性,
          // 依賴屬性改變時,會重新計算computedFn,并執(zhí)行監(jiān)控函數(shù)watchFn,
          // 屬性依賴計算使用棧及可以了。
          // watch(computedFn, watchFn);
          watch(render, function(newVNode, oldVNode){
              update(newVNode, mountNode);
          });
          
          //初始渲染
          mount(render(), mountNode);
          
          // 改變觀察對象屬性,如果render依賴了該屬性,則會重新渲染
          data.name = 'hello vue toy';

          視圖渲染部分(既render)使用的是vdom技術(shù),vue2+使用Snabbdom庫,vue-toy使用的是react來進行渲染,所以在render函數(shù)里你可以直接使用React的JSX語法,不過別忘記import React from 'react',當然也可以使用preact inferno 等 vdom庫。

          由于vue的template的最終也是解析并生成render函數(shù),模版的解析可用htmleParser庫來生成AST,剩下就是解析指令并生產(chǎn)代碼,由于工作量大,這里就不具體實現(xiàn),直接使用jsx。

          瀏覽 21
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          編輯 分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          編輯 分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产又爽又黄无码无遮挡在线观看 | 国产探花丝袜 | 日韩午夜激情电影 | 青娱乐亚洲视频在线 | 日本五十肥熟交尾 |