关于前端:微信Vue框架构建Part5渲染对象数据

51次阅读

共计 1924 个字符,预计需要花费 5 分钟才能阅读完成。

概述

  • 本节内容是在上一篇的根底上,实现对象类型的数据渲染,渲染到实在页面中
  • 难点有:

    1. 如何晓得单个 vnode 中有那些模板语法
    2. 如何实现晓得模板语法对应的值
    3. 如何实现数据的替换,实现页面渲染
  • 流程概览图示

找到模板语法

  • 在上文中咱们实现了模板和 vnode 之间的互相映射,且用 Map 对象保留,所以可通过 Map 的内置办法实现
  • 代码实现

      /**
       * 渲染虚构 DOM
       * @param {*} vm
       * @param {*} vnode
       */
      function renderVNode(vm, vnode) {if (vnode.nodeType === NODE_TYPE_TEXT) {const templateArr = VNodeToTemplate.get(vnode);
          if (templateArr && templateArr.length) {for (let i = 0; i < templateArr.length; i++) {
                // 1. 遍历 vnode 下所有的模板语法
                // 2. 晓得每个模板语法对应的值
                // 3. 操作实在 DOM,替换模板语法,实现数据渲染
        
            }
          }
        } else {for (let i = 0; i < vnode.children.length; i++) {renderVNode(vm, vnode.children[i]);
          }
        }
      }
    

    找到模板语法在 data 中的值

  • vue 中的 data 属性值是一个变量,所以咱们将定义一个办法来实现这个性能
  • 模板的数据可能有两个,一个是 data 中定义的,一个可能是类型 v -for 循环这样的局部变量
  • 代码实现

      /**
       * 返回模板语法对应的数据
       * @param {*} dataArr 数据源
       * @param {*} template 模板语法
       */
      export function getTemplateValue(dataArr, template) {
        let templateValue;
        if (dataArr instanceof Array) {for (let i = 0; i < dataArr.length; i++) {templateValue = getObectValue(dataArr[i], template);
            if (templateValue) break;
          }
        }
        return templateValue;
      }
    
      function getObectValue(obj, template) {
        let tempalteValue;
    
        const keyArr = template.split(".");
    
        for (let i = 0; i < keyArr.length; i++) {const key = keyArr[i].trim();
          const value = obj[key];
         if (value instanceof Object) {
            // 数据是对象的状况
            return (tempalteValue = getObectValue(value, template));
          } else {tempalteValue = obj[key];
          }
        }
    
        if (!tempalteValue) {throw new Error(`${template} is not undefined`);
        }
        return tempalteValue || "undefined";
      }

    拿到模板语法的值后,渲染数据

  • 之前咱们定义的 vnode 中有实在 DOM,所以能够间接操作
  • 通过正则实现模板语法的替换
  • 代码实现

     function renderVNode(vm, vnode) {if (vnode.nodeType === NODE_TYPE_TEXT) {const templateArr = VNodeToTemplate.get(vnode);
          if (templateArr && templateArr.length) {for (let i = 0; i < templateArr.length; i++) {
                // 获取模板语法的值
              const templateValue = getTemplateValue([vm._data, vnode.env],
                templateArr[i]
              );
              let nodeValue;
              console.log("templateValue", templateValue);
               
               // 如果模板语法有对应的值,就替换模板语法
              if (templateValue) {
                nodeValue = vnode.text.replace(new RegExp(`{{[\s|${templateArr[i]}|\s]+}}`, "g"),
                  templateValue
                );
              }
              // 操作实在 DOM,实现数据渲染
              vnode.elm.nodeValue = nodeValue;
            }
          }
        } else {for (let i = 0; i < vnode.children.length; i++) {renderVNode(vm, vnode.children[i]);
          }
        }
      }
    

正文完
 0