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

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

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

以下写法不合法

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

变量

输出一个变量

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

函数调用

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

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

if & else & else if

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

  1. <div v-if={a === 1}></div>
  2. <div v-else-if={a === 2}></div>
  3. <div v-else>这个数字好诡异</div>

或者使用三元操作符

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

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

循环

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

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

  • value指向对象或数组的值

更改键值命名

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

    1. <ul>
    2. <li v-for={items} v-for-key="attrName" v-for-value="attrValue">
    3. {attrName}: {attrValue}
    4. </li>
    5. </ul>
    1. {
    2. "items" : {
    3. "width": "100px",
    4. "height": "100px"
    5. }
    6. }

v-for & v-if 结合使用

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

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

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

v-raw

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

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

宏函数

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

    1. var FormItem = function(attrs) {
    2. return <div class="form-item">
    3. <label>
    4. <span v-if={attrs.required}>*</span>{attrs.label}:
    5. {attrs.children}
    6. </label>
    7. </div>
    8. };
    9. <form>
    10. <FormItem required={true} label="姓名">
    11. <input type="text" name="name" />
    12. </FormItem>
    13. <FormItem required={true} label="密码">
    14. <input type="password" name="password" />
    15. </FormItem>
    16. </form>
  • 宏函数名必须以大写字母开头

  • 传递给宏函数的参数是引用宏函数所定义的属性组成的对象
  • 可以通过attrs.children来引用宏函数的子元素

template

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

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

设置临时变量

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

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

    1. var a;
    2. var template = <span>新人</span>
    3. <div>
    4. {function() {
    5. if (isNew) {
    6. a = 1;
    7. } else {
    8. a = 2;
    9. }
    10. }.call(this)}
    11. <div v-if={a === 1}>{template}</div>
    12. </div>
    1. {"isNew": true}

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

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

转义

Vdt默认会对任何输出转义

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

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

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

非转义

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

  1. <html>
  2. <header>
  3. <title>test</title>
  4. {= style }
  5. </header>
  6. <body></body>
  7. </html>

注释

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

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

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

  1. <div>
  2. {// 必须换行,像下面这样}
  3. {// 换行
  4. }
  5. </div>