前端Vue专辑纵横研究院VU...Vue驿站

标签模板及其应用

2019-12-03  本文已影响0人  me_coder

1、标签模板

标签模板其实不是模板,而是函数调用的一种特殊形式。“标签”指的就是数,紧跟在后面的模板字符串就是它的参数。
但是,如果模板字符里面有变量,就不是简单的调用了,而是会将模板字符串先处理成多个参数,再调用函数。
例如:

let a = 5;
let b = 10;

tag`Hello ${ a + b } world ${ a * b }`;
// 等同于
tag(['Hello ', ' world ', ''], 15, 50);

下面给出一个示例代码及其运行结果:

let a = 5;
let b = 10;

function tag(s, v1, v2) {
  console.log(s[0]);
  console.log(s[1]);
  console.log(s[2]);
  console.log(v1);
  console.log(v2);

  return "OK";
}

tag`Hello ${ a + b } world ${ a * b}`;
// "Hello "
// " world "
// ""
// 15
// 50
// "OK"

一个复杂的例子:

let total = 30;
let msg = passthru`The total is ${total} (${total*1.05} with tax)`;

function passthru(literals) {
  let result = '';
  let i = 0;

  while (i < literals.length) {
    result += literals[i++];
    if (i < arguments.length) {
      result += arguments[i];
    }
  }

  return result;
}


msg // "The total is 30 (31.5 with tax)"

对这个例子写成如下分析代码:

let total = 30;
let msg = passthru`The total is ${total} (${total*1.05} with tax)`;

function passthru(literals) {
  let result = '';
  let i = 0;

  while (i < literals.length) {
    console.log(i,'literals',literals[i++]);
    if (i < arguments.length) {
      console.log(i,'arguments',arguments[i]);
    }
  }

  return result;
} ;


msg

得到结果为:

0 literals The total is 

1 arguments 30 

1 literals ( 

2 arguments 31.5 

2 literals with tax) 

采用rest参数写法如下:

function passthru(literals, ...values) {
  let output = "";
  let index;
  for (index = 0; index < values.length; index++) {
    output += literals[index] + values[index];
  }

  output += literals[index]
  return output;
}

对其进行分析:

let total = 30;
let msg = passthru`The total is ${total} (${total*1.05} with tax)`;

function passthru(literals, ...values) {
  let output = "";
  let index;
  for (index = 0; index < values.length; index++) {
    console.log(index,literals[index],values[index])
  }

  console.log(index,literals[index])
  
};


msg

输出为:

0 The total is 30 

1 ( 31.5 

2 with tax)

2、应用

(1)防止用户恶意输入
let message =
  SaferHTML`<p>${sender} has sent you a message.</p>`;

function SaferHTML(templateData) {
  let s = templateData[0];
  for (let i = 1; i < arguments.length; i++) {
    let arg = String(arguments[i]);

    // Escape special characters in the substitution.
    s += arg.replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;");

    // Don't escape special characters in the template.
    s += templateData[i];
  }
  return s;
}

上面代码中,sender变量往往是用户提供的,经过SaferHTML函数处理,里面的特殊字符都会被转义。

(2)多语言转换(国际化处理)
i18n`Welcome to ${siteName}, you are visitor number ${visitorNumber}!`
// "欢迎访问xxx,您是第xxxx位访问者!"

i18n为前端国际化工具。

(3)其他应用

通过标签函数,可以为模板添加条件判断和循环处理功能:

// 下面的hashTemplate函数
// 是一个自定义的模板处理函数
let libraryHtml = hashTemplate`
  <ul>
    #for book in ${myBooks}
      <li><i>#{book.title}</i> by #{book.author}</li>
    #end
  </ul>
`;

除此之外,你甚至可以使用标签模板,在 JavaScript 语言之中嵌入其他语言:

jsx`
  <div>
    <input
      ref='input'
      onChange='${this.handleChange}'
      defaultValue='${this.state.value}' />
      ${this.state.value}
  </div>
`

上面的代码通过jsx函数,将一个 DOM 字符串转为 React 对象。

模板处理函数的第一个参数(模板字符串数组),还有一个raw属性,其保存的是转义后的原字符串。

上一篇下一篇

猜你喜欢

热点阅读