Придерживайтесь первого дня сборки колеса - шаблонизатор

Vue.js

Придерживайтесь первого дня сборки колеса - шаблонизатор

Кроме того, я могу построить колеса.Ты боишься, что тебя спросят на собеседовании? Стройте колесо в день, и все готово.

Аспект

  • Рукописные вопросы для письменного теста и собеседования
  • Разработка TDD
  • С видео пояснением

программа по сборке колес

(План не поспевает за изменениями, повторяется в любое время, добро пожаловать, чтобы оставить сообщение и почувствовать рыбу в любое время)

шаблонизатор

Чтобы добиться разделения представления и бизнес-логики, независимо от того, какой V является MVP, MVVM или MVC, будет использоваться механизм шаблонов. На линии поговорим о требованиях к шаблонизатору.

нужно

{{ }} выражение

Фактически это замена значения в {{ }} результатом выражения.

шаблон результат
<b>{{ name }}</b> <b>tom</b>
<b>{{ name.toUpperCase() }}</b> <b>TOM</b>
<b>{{ '[' + name + ']' }}</b> <b>[tom]</b>

С точки зрения тестовых случаев это так

  it("{{}} 表达式", () => {
    const output = compile("<b>{{ name }}</b>")({ name: "tom" });
    expect(output).toBe(`<b>tom</b>`);
  });

  it("{{}} toUpperCase 表达式", () => {
    const output = compile("<b>{{ name.toUpperCase() }}</b>")({ name: "tom" });
    expect(output).toBe(`<b>TOM</b>`);
  });

  it("{{}} +连接", () => {
    const output = compile("<b>{{ '[' + name + ']' }}</b>")({ name: "tom" });
    expect(output).toBe(`<b>[tom]</b>`);
  });


forEach обход

{%arr.forEach(item => {%}
    <li>{{item}}</li>
{%})%}

генерировать результаты

    <li>aaa</li>
    <li>bbb</li>

если суждение

{% if(isShow) { %} <b>{{ name }}</b> {% } %}

генерировать результаты

     <b>tom</b> 

Реализация функции

Функцию рендеринга шаблона можно условно разделить на два этапа:

  1. Скомпилируйте шаблон в функцию Generate
  2. выполнить функцию рендеринга

Например, самый простой шаблон

<b>{{ name }}</b>

Сгенерированная функция рендеринга

generate(obj){
  let str = '';
  with(obj){
  str+=`<b>${name}</b>`}
  return str;
}

Выполнить генерировать результат

const ret = generate({name : 'tom'})

// 运行结果: <b>tom</b>

процесс компиляции

На самом деле мы называем процесс компиляции сопоставлением с помощью регулярных выражений.

Первый шаг — преобразовать выражение {{ xxx }} в строку шаблона ES6 ${ xxx }

  // 全局正则表达式替换
  template = template.replace(/\{\{([^}]+)\}\}/g, function () {
    let key = arguments[1].trim();
    return "${" + key + "}";
  });

Вторые шаги {%}% выражений в JS такие операторы могут быть использованы, если шаблон, foreach

Например, если суждение:

{% if(isShow) { %} <b>{{ name }}</b> {% } %}
// 转化的函数
let str = '';
   with(obj){
   str+=``
   if(isShow) {
    str+=`<b>${name}</b> `
   }
   return str;

код реализации

  let head = `let str = '';\r\n with(obj){\r\n`;
  head += "str+=`";
  template = template.replace(/\{\%([^%]+)\%\}/g, function () {
    return "`\r\n" + arguments[1] + "\r\nstr+=`\r\n";
  });
  let tail = "`}\r\n return str;";

Создайте функцию Генерировать

Для этого требуется синтаксис, который мы обычно не используем new Function() для динамического создания тела функции. Например

new Function('arg', 'console.log(arg + 1);');
// 相当于创建了一个匿名函数
function (arg) {
    console.log(arg + 1);
}

полная реализация кода

template = template.replace(/\{\{([^}]+)\}\}/g, function () {
    let key = arguments[1].trim();
    return "${" + key + "}";
  });

  let head = `let str = '';\r\n with(obj){\r\n`;
  head += "str+=`";
  template = template.replace(/\{\%([^%]+)\%\}/g, function () {
    return "`\r\n" + arguments[1] + "\r\nstr+=`\r\n";
  });

  let tail = "`}\r\n return str;";
  console.log(`==========render=========`)
  console.log(head + template + tail);
  return new Function("obj", head + template + tail);

тестовое задание

ОК задача выполнена

Обратите внимание на дядю Рана из всего стека и берите с собой делать колеса каждый день (отдыхайте по выходным, отбрасывайте 996)

  • Исходный адрес https://github.com/su37josephxia/wheel-awesome

В этой статье используетсяmdniceнабор текста