像这样,为这两个不需要“优化”的 input 元素添加了唯一标识的 key 以后,vue 便不会再复用这两个元素。每次切换之后,修改的内容将不会被保留。
三、更多思考
(1)基于标签的指令(v-bind 、v-if)
Handlebars 的 helpers 有自己独立的语法,比如:
{{#if ok}} <h1>Yes</h1> {{/if}}
它定义了一组自己的语法。而实现同样的功能,vue 使用类似于 v-bind、v-if 之类的指令,它们都是绑定在一个个标签上面的,如
<h1 v-if="ok">Yes</h1>
这样的语法更加简洁、清晰。
Handlebars 的语法,支持同时绑定多个 DOM 节点。
{{#if ok}} <h1>Yes</h1> <h1>Yes</h1> <h1>Yes</h1> {{/if}}
按照前面的思路,难道 vue 要实现成这样?
<h1 v-if="ok">Yes</h1> <h1 v-if="ok">Yes</h1> <h1 v-if="ok">Yes</h1>
那根本不可能,添加额外的 DOM 节点包裹住它们?那就更不可能。vue 扩展了一个 template 节点,使用的时候,我们可以像 HTML 节点一样去使用它,但是渲染页面的时候,它不会被渲染在页面上。于是,前面的代码可以实现成这样:
<template v-if="ok"> <h1>Yes</h1> <h1>Yes</h1> <h1>Yes</h1> </template>
想想,其实和 Handlebars 也差不多了,甚至显得还要复杂些了,毕竟 template 这个单词这么长~
(2)利用条件渲染字符串
前面说,v-if 等指令都是基于标签的,那如果我不想创建额外的标签,只是想按照条件去修改一个字符串呢?没错,你猜对了,template 节点,它里面除了可以存放节点,也可以直接存放字符串,就像这样:
<div> <template v-if="c3">text</template> </div> ...... var app = new Vue({ el: '#app', data: { c3: true } });
渲染结果:
<div>text</div>
这里其实也就是利用了 template 节点不会被渲染在页面上的特性。
(3)属性的“条件渲染”
既然 HTML 节点可以条件渲染,多个 HTML 节点可以条件渲染,HTML 节点内字符串可以条件渲染,那么 HTML 属性呢?在编写模板的时候,HTML 属性其实也是字符串,我们能想上面那样,利用 template 模板创建字符串作为 HTML 的属性吗?
复制代码 代码如下:
<div title="<template v-if='c3'>title content</template>">此处应有 title</div>
是不是一看就感觉怪怪的?vue 也这样觉得,于是控制台里就解析成了:
复制代码 代码如下:
<div title="<template v-if='c3'>title content</template>">此处应有 title</div>
中间的 <template v-if='c3'>title content</template> 整个的被识别成了字符串,那如果去掉外面的双引号呢?
复制代码 代码如下:
<div title=<template v-if='c3'>title content</template>>此处应有 title</div>
好像看起来更奇怪了。最后的渲染结果:
<div title="<template">title content>此处应有 title</div>
vue 的模板解析不是简单的依赖于字符串的解析,所以其实这里不能使用这种方法。正确的姿势是利用 v-bind 指令:
<div v-bind:title="c3 ? 'title content' : '' ">title</div>
因为 v-bind 指令的预期值实际上可以接受 js 表达式的,这里我们传入了一个条件表达式。当 c3 为真值的时候,渲染为 title="title content",当 c3 为假值的时候,渲染为 title=""。
您可能感兴趣的文章: