Fortunately, we explored the Vue source code above: mustache template engine (10) to solve the problem of not being able to find multi-layer objects with continuous dot symbols, and to pave the way for the compilation cycle structure. We solved the problem that the js string cannot get the value in the object through what point or something This question
needs to be remembered because this method was written as an interview question before.
Then in this article, we are going to write the recursion mentioned above. Find renderTemplate.js
and add a condition below the judgment here.
Judging that if the current first subscript is a pound sign, the logic of opening a new one
is what we said before. Can handle text and name types, but he has no processing ability in the way of number sign cycle
We will change the index.html code under www to this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src = "/xuni/bundle.js"></script>
<script>
let templateStr = `
<div>
{
{#students}}
<ul>
<li>{
{ name }}</li>
{
{#list}}
<li>{
{ . }}</li>
{
{/list}}
</ul>
{
{/students}}
</div>
`;
let data = {
name: "小猫猫",
age: 2,
students: [
{
id: 0,
name: "小明",
list: [
"篮球",
"唱",
"跳"
]
},
{
id: 1,
name: "小红",
list: [
"电子游戏",
"计算机编程"
]
}
]
}
GrManagData.render(templateStr,data);
</script>
</body>
</html>
Let's create a parseArray.js file under src and write and expose a function first.
/*
处理数组逻辑
*/
export default function parseArray(token,data) {
console.log(token,data);
}
Here our function receives two parameters, token, which is a single subscript of tokens, and data, which is the overall data.
There is nothing to say.
This function is used to process the logic of the array loop.
Here we import and call renderTemplate.js
Here we judge the cycle number and throw it directly to it for processing.
After running the project, we find that the token and the overall data of our data are printed out,
which means that the data of parseArray is still obtained
, and then parseArray needs to call renderTemplate call cyclically The number of times depends on the length of the traversal array
, but first we need to take out this array from data
, so we need lookup, which
we can import and then write like this.
The result of the operation is as follows.
You can see that the syntax successfully outputs the contents of students in our data
, and here we write a simple
Change the index.html code under www to the following
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src = "/xuni/bundle.js"></script>
<script>
let templateStr = `
<div>
{
{#students}}
<ul>
<li>{
{name}}</li>
</ul>
{
{/students}}
</div>
`;
let data = {
name: "小猫猫",
age: 2,
students: [
{
id: 0,
name: "小明",
list: [
"篮球",
"唱",
"跳"
]
},
{
id: 1,
name: "小红",
list: [
"电子游戏",
"计算机编程"
]
}
]
}
GrManagData.render(templateStr,data);
</script>
</body>
</html>
Here we don't engage in multi-level nesting, we need a first-level loop
, and then we change the final output of renderTemplate to return.
Here we change it to return after processing and then return directly.
Then parseArray.js code is written as follows
import lookup from "./lookup";
import renderTemplate from "./renderTemplate";
/*
处理数组逻辑
*/
export default function parseArray(token,data) {
let view = lookup(data,token[1]);
let resultStr = "";
for(let i = 0; i < view.length; i++) {
resultStr += renderTemplate(token[2],view[i]);
}
return resultStr;
}
Here we get the traversed array and loop through the view
, then define a resultStr to store the content generated by loop traversal , and then call renderTemplate for each loop to accept the returned result. The token[2] here is
because when we wrote nestTokens.
The tokens structure has the 2 subscripts of the pound token. I don’t know if you still remember.
Then view[i] is the subscript currently being cycled. For example, the array structure is
[
{
id: 1,name:"你好"},
{
id: 2,name:"小猫猫"}
]
Then the first cycle i is 0, view[i] is view[0] and the corresponding value is {id: 1, name: "Hello"} and so on. Use the subscript of the current cycle as the
data
source and then use the second The subscripted token is the page structure inside the loop.
The result of the operation is as follows.
We have completed a simple version
But there is still a problem at present, that is, if our array structure is simpler, there will still be problems.
We will change the index.html code under www as follows
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src = "/xuni/bundle.js"></script>
<script>
let templateStr = `
<div>
{
{#students}}
<ul>
<li>{
{.}}</li>
</ul>
{
{/students}}
</div>
`;
let data = {
name: "小猫猫",
age: 2,
students: [
"小明",
"小芳"
]
}
GrManagData.render(templateStr,data);
</script>
</body>
</html>
The result of the operation is as follows
, it directly becomes undefined
because our level is unable to recognize the meaning of this small point. In mustache, the small point means directly taking the subscript of the current number
We can directly change parseArray to
export default function parseArray(token,data) {
let view = lookup(data,token[1]);
let resultStr = "";
for(let i = 0; i < view.length; i++) {
resultStr += renderTemplate(token[2],{
".": view[i]});
}
return resultStr;
}
It’s equivalent to writing an object whose key is “.”, and the value is the current item of the array itself. The result is as follows.
Writing
this way can indeed solve the problem, but putting the format of the array object before it will ruin
us again. Restore the index.html under www to our previous appearance.
After running, it will be undefined,
because the object you passed is data. When we set it up like this, it only has one field, which is the dot
Here we change this sentence to this
resultStr += renderTemplate(token[2],{
".": view[i],...view[i]});
Here we assign all the fields of the current object to this object through the ES feature of three small points
In this way, we change the index.html under www back, and
this mode can also be adapted
. Not only can they all be able to have a multi-layer nested structure, but now
we can change the index.html code under www to
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src = "/xuni/bundle.js"></script>
<script>
let templateStr = `
<div>
{
{#students}}
<ul>
<li>{
{name}}</li>
{
{#list}}
<li>{
{.}}</li>
{
{/list}}
</ul>
{
{/students}}
</div>
`;
let data = {
name: "小猫猫",
age: 2,
students: [
{
id: 0,
name: "小明",
list: [
"篮球",
"唱",
"跳"
]
},
{
id: 1,
name: "小红",
list: [
"电子游戏",
"计算机编程"
]
}
]
}
GrManagData.render(templateStr,data);
</script>
</body>
</html>
Then we change the judgment of lookup.js.
Simply put, our name can contain dots, but it cannot be a dot. It is a dot itself. The
final running result is as follows, which
is perfect
Then we will change the function in index.js for the last time,
we will return directly without output
Then we modify the index.html code under www as follows
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id = "container"></div>
<script src = "/xuni/bundle.js"></script>
<script>
let templateStr = `
<div>
{
{#students}}
<ul>
<li>{
{name}}</li>
{
{#list}}
<li>{
{.}}</li>
{
{/list}}
</ul>
{
{/students}}
</div>
`;
let data = {
name: "小猫猫",
age: 2,
students: [
{
id: 0,
name: "小明",
list: [
"篮球",
"唱",
"跳"
]
},
{
id: 1,
name: "小红",
list: [
"电子游戏",
"计算机编程"
]
}
]
}
let templateDom = GrManagData.render(templateStr,data);
var container = document.getElementById('container');
container.innerHTML = templateDom;
</script>
</body>
</html>
The results of the operation are as follows
. Congratulations to everyone who has reached the end