概述
- 本节内容是在上一篇的基础上,实现对象类型的数据渲染,渲染到真实页面中
- 难点有:
- 如何知道单个vnode中有那些模板语法
- 如何实现知道模板语法对应的值
- 如何实现数据的替换,实现页面渲染
- 流程概览图示

找到模板语法
- 在上文中我们实现了模板和vnode之间的相互映射,且用Map对象保存,所以可通过Map的内置方法实现
- 代码实现
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++) {
}
}
} else {
for (let i = 0; i < vnode.children.length; i++) {
renderVNode(vm, vnode.children[i]);
}
}
}
找到模板语法在data中的值
- vue中的data属性值是一个变量,所以我们将定义一个方法来实现这个功能
- 模板的数据可能有两个,一个是data中定义的,一个可能是类型v-for循环这样的局部变量
- 代码实现
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
);
}
vnode.elm.nodeValue = nodeValue;
}
}
} else {
for (let i = 0; i < vnode.children.length; i++) {
renderVNode(vm, vnode.children[i]);
}
}
}