标签模板及其应用

作者: me_coder | 来源:发表于2019-12-03 11:27 被阅读0次

    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属性,其保存的是转义后的原字符串。

    相关文章

      网友评论

        本文标题:标签模板及其应用

        本文链接:https://www.haomeiwen.com/subject/oefcgctx.html