返回介绍

模板语法

发布于 2021-04-10 06:03:37 字数 14519 浏览 1085 评论 0 收藏 0

Vdt中默认使用一对大括号{}作为分隔符,在{}中书写合法的js表达式,但这个表达式必须满足以下条件:

  • 作为输出时:表达式的值必须是,Number, String, null, undefined或模板引用中的一种,或者是由上述类型组成的数组
  • 作为属性值时:表达式可以为任意类型,具体取决于属性取值的类型

为了提高编译速度,Vdt不会分析{}中js表达式的合法性,也不会检测变量是否未定义

以下写法不合法

<div>{ {a: 1, b: 2} }</div>             // 不合法,Object不能渲染

<div>{ if (true) { 'a' } else { 'b' } }<div>    // 不合法,if语句不是表达式,可以使用三元操作符

变量

输出一个变量

<div>{name}</div>
<div>{data.name}</div>
<div>{data['name']}</div>

函数调用

你可以在{}中直接调用函数。Vdt中没有过滤器的概念,但可以调用函数来达到类似的目的

<div>{foo(name)}</div>
<div>{arr.join(',')}</div>

if & else & else if

用于逻辑控制的3条指令是v-if & v-else-if & v-else,本质上它们是三元操作符的语法糖,你也直接使用三元操作符

<div v-if={a === 1}>一</div>
<div v-else-if={a === 2}>二</div>

<div v-else>这个数字好诡异</div>

或者使用三元操作符

{a === 1 ? <div>一</div> : a === 2 ? <div>二</div> : <div>这个数字好诡异</div>}

v-if & v-else-if & v-else必须连起来写,中间不能穿插非空节点,否则会失效

循环

v-for指令用于实现循环,你也可以使用[].map来实现,但该指令支持遍历对象

<ul>
  <li v-for={items}>{key}: {value}</li>
</ul>
{
  "items" : {
    "width": "100px",
    "height": "100px"
  }
}
  • key指向对象的键,如果是数组则指向数组的索引
  • value指向对象或数组的值

更改键值命名

通过v-for-key & v-for-value指令,可以改变键值的命名

<ul>
  <li v-for={items} v-for-key="attrName" v-for-value="attrValue">
    {attrName}: {attrValue}
  </li>
</ul>
{
  "items" : {
    "width": "100px",
    "height": "100px"
  }
}

v-for & v-if 结合使用

v-for指令和v-if一起使用时,用于控制单条数据是否展示,并非控制整体v-for是否展示;

v-if中能够使用v-for提供的两个变量key & value,并且与这两条指令的书写顺序无关

<ul>
  <li v-for={items} v-if={key === 'width'}>
    只展示key === 'width'的属性
    {key}: {value}
  </li>
</ul>
{
  "items" : {
    "width": "100px",
    "height": "100px"
  }
}

v-raw

v-raw指令可以让你指定某个标签下所有子元素不进行编译,而是输出它的原始内容。这可以使 我们很方便地输出分解符{}。例如:

<script type="text/md" v-raw>
  var vdt = Vdt(template);
  vdt.render({
    test: 1
  });
</script>

宏函数

宏使你能够定义一块可复用的模板片段,Vdt中没有宏的概念,但可以通过函数实现该功能

var FormItem = function(attrs) {
  return <div class="form-item">
    <label>
      <span v-if={attrs.required}>*</span>{attrs.label}:
      {attrs.children}
    </label>
  </div>
};

<form>
  <FormItem required={true} label="姓名">
    <input type="text" name="name" />
  </FormItem>
  <FormItem required={true} label="密码">
    <input type="password" name="password" />
  </FormItem>
</form>
  • 宏函数名必须以大写字母开头
  • 传递给宏函数的参数是引用宏函数所定义的属性组成的对象
  • 可以通过attrs.children来引用宏函数的子元素

template

template是一个伪元素,它只会渲染子元素,自身不会被渲染成任何内容。这在我们结合v-forv-if 等指令,来渲染和判读多个元素时提供了便利。

<dl>
  <template v-for={list}>
    <dt>{value.name}</dt>
    <dd>{value.age}</dd>
  </template>
</dl>
{
  "list": [
    {"name": "Javey", "age": 18},
    {"name": "Tom", "age": 20}
  ]
}

设置临时变量

在标签语法的外部,可以书写任意的js代码,Vdt支持在模板顶部定义函数和变量;

另外在模板内部,也可以通过自执行函数进入js代码区域

var a;
var template = <span>新人</span>

<div>
  {function() {
    if (isNew) {
      a = 1;
    } else {
      a = 2;
    }
  }.call(this)} 
  <div v-if={a === 1}>{template}</div>
</div>
{"isNew": true}

上述例子展示了如何在标签语法和js语法间来回切换,标签语法可以直接穿插在js语法中,在标签语法 中使用自执行函数可以切换到js语法

  • 自执行函数的返回值必须合法,返回值会当做结果渲染到页面,可以返回undefined | null来阻止渲染。 (没有返回值的函数,默认返回undefined
  • 自执行函数不应该改变this指向,所以应该通过.call(this)的方式调用。ES6可以使用箭头函数(() => { })(),甚至do { }语法

转义

Vdt默认会对任何输出转义

<div>{'<script>alert(1)</script'}</div>

通过innerHTML属性,可以阻止转义(本质上就是element.innerHTML

<div innerHTML={'<script>alert(1)</script>'}></div>

非转义

当Vdt作为后端模板渲染时,有时需要输出整段html代码,并且不能使用innerHTML来输出。例如:在<header> 中,输出整段<style>代码。此时可以使用{= variable }语法来输出整段非转义代码

<html>
<header>
  <title>test</title>
  {= style }
</header>
<body></body>
</html>

注释

Vdt没有提供特殊的注释写法,有的只是js和html的注释,所以注释分为两种:

  1. 在标签语法里面,可以书写html注释 <!-- 注释 -->
  2. 在js语法里面,可以书写js注释 // 注释 /* 注释 */
// 注释
<div>
  <!-- 注释 -->
  <h1>标题</h1>
  {// 注释
  }
  {/* 注释 */}
  <div>内容</div>
</div>

需要注意的是:// 注释单行注释需要换行,否则最后的}分隔符也会当做注释内容,所以不建议使用,而是使用多行注释/**/

<div>
  {// 必须换行,像下面这样}
  {// 换行
  }
</div>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文