模板字符串,也叫模板字面量.模板字符串是用反引号(`)包起来的语法结构.通常用于大量复杂的文字插入变量,替换点位符用.

[参考]
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Template_literals

语法

// 单行
`hello world!`

// 多行
`
    白日依山尽,
    黄河入海流.
`

// 模板替换
`姓名:${name},性别:${gender}`


// 带标签模板
tagTrim`我的名字叫${name}.`

使用变量和表达式

在模板字符串中,可以用${表达式},{}可以是任何变量,可以是表达式,甚至函数.
最终结果相当于表达式的最终值,转成string的效果.
举例:

let str="javascript"
// out: hello javascript
console.log(`hello ${str}`)
// out: 1+1=2
console.log(`1+1=${1+1}`)
// out: obj:[object Object]
console.log(`obj:${{a:1,"b":2}}`)
let func=(a,b)=>{return a+b}
// func:3
console.log(`func:${func(1,2)}`)

嵌套:

//  hello javascript 3
console.log(`
    hello ${`javascript ${1+2}`}
`)

标签模板

以上这种都很常见,在php中也是差不多的语法.
JS的模板字符串还有一种用法,就是标签语法.

语法:

func `模板字符串内容`

func (str[],...args){
  // str[],所有字符串的数组,使用${}分开,数组数量,大于${}的数量
  // ...args,其他${变量}结果
}

如下实现 一个"echo"标签,第1个参数为数组['姓名: ',',年龄:',''] ,第2参数:${name}的值,第3个参数:${18+10}=28

echo `姓名: ${name},年龄:${18+10}`

​ 实际上是一个函数.相当于 echo(xxx)

​ 例子,echo

const echo=(strs,...args)=>{
    let message='';
    strs.forEach((str,index)=>{
        message+=`${str}${args[index]??''}`
    })
    console.log(message)
}

let name="张三";
echo `姓名: ${name},年龄:${18+10}`

如上代码输出: 姓名: 张三,年龄:28

image-20230728231912634

String.raw

第1个参数,中多出了一个raw属性,raw是不可修改的特殊属性.

参考: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/raw

image-20230729022607282

raw属性干什么用的呢?

原样字符串,不经过转义后字符串. "\n"在字符串中表示换行. 在raw表示两个字符\n,不被转义.

举例:

console.log("hello\nworld");//输出: hello 换行 world

如果要原样输出,改一下.

  const echo=(strs,...args)=>{
      let message='';
      strs.raw.forEach((str,index)=>{
          message+=`${str}${args[index]??''}`
      })
      console.log(message);
  }

  let name="张三";
  echo `姓名: ${name},\n年龄:${18+10}`

输出: 姓名: 张三,\n年龄:28

使用 strs.raw 代替strs.

es6 系统提供了一个自带的标签函数. String.raw

上面可以写成

 String.raw `姓名: ${name},\n年龄:${18+10}`

image-20230730234944822

也可以直接调用String.raw,但不建议直接使用.

String.raw({raw:['姓名: ',',\n年龄:','']},name,18+10)

上面echo 函数也可以改成.

  // const echo=(strs,...args)=>{
  //     let message='';
  //     strs.raw.forEach((str,index)=>{
  //         message+=`${str}${args[index]??''}`
  //     })
  //     console.log(message);
  // }
  const echo=(strs,...args)=>console.log(String.raw(strs,...args))

  let name="张三";
  echo `姓名: ${name},\n年龄:${18+10}`

应用例子

styled-compents

styled-compents 是css-in-js 的react 插件. 可以像写JS一样写css. 不像sass,less一样需要编译.

https://styled-components.com/

styled-compents 就是典型的tagFun 应用. 我们看一下styled的语法:

创建一个带样式的button.

const Button = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid #BF4F74;
  color: #BF4F74;
  margin: 0 1em;
  padding: 0.25em 1em;
`
<Button>Normal Button</Button>

styled.button 就是一个标签函数. 原理就是利用标签模板函数,解析样式.

原生JS如何实现?

  const Button=document.createElement("button");
  Button.style=`background: transparent;
  border-radius: 3px;
  border: 2px solid #BF4F74;
  color: #BF4F74;
  margin: 0 1em;
  padding: 0.25em 1em;`

  Button.innerHTML="提交"
  document.body.appendChild(Button)

省略了创建button的过程.

const styled=function(){};
styled.button=function(css,...vals){
    const button= document.createElement('button');
    button.style=String.raw(css,...vals);
    return button;
}
styled.props=function(){}

const Button = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid #BF4F74;
  color: #BF4F74;
  margin: 0 1em;
  padding: 0.25em 1em;
`
Button.innerHTML="提交"
document.body.appendChild(Button)

改进一下成通用组件.

const styled= new  function() {
    this.version="1.0"
    function createElement(name,css={},vals=[]){
        const dom= document.createElement(name);
        if(!css.raw){
            return dom;
        }
        dom.style=String.raw(css,...vals);
        return dom;
    }
    return new Proxy(this,{
        get:function(target,prop){
            if (prop in target){
                return target[prop]
            }
            return function(css,...vals){
                return createElement(prop,css,vals)
            }
        }
    });
}

const Button=styled.button`background: transparent;
    border-radius: 3px;
    border: 2px solid #BF4F74;
    color: #BF4F74;
    margin: 0 1em;
    padding: 0.25em 1em;
`
Button.innerHTML="提交"

const Div=styled.div`background:#ccc;height:100px;`
Div.innerHTML="hello world";
Div.appendChild(Button);

document.body.appendChild(Div)

原作者:阿金
本文地址:https://hi-arkin.com/archives/Template_literals.html

标签: javascript styled-compents 模板字符串 模板字面量

(本篇完)

评论