vue.js实现条件渲染的实例代码

一、初探条件渲染

vue 的条件渲染,仍旧依赖于指令系统,下面逐个介绍:

(1)v-if

<div id="app">
  <div v-if="c1">c1</div>
</div>
......
var app = new Vue({
  el: '#app',
  data: {
    c1: false
  }
});

当 c1 为真值的时候,渲染出 v-if 所绑定的元素,否则不渲染出该元素。渲染结果如下:

<div id="app"></div>

(2)v-else

<div id="app">
  <div v-if="c1">c1</div>
  <div v-else>c1 is not true</div>
</div>
......
var app = new Vue({
  el: '#app',
  data: {
    c1: false
  }
});

当 c1 为真值的时候,渲染 v-if 所绑定的元素,否则渲染 v-else 所绑定的元素。这里值得注意的是,在 Handlebars 模板引擎里面,else 可以和 each 所搭配,当遍历次数为0的时候,则渲染 else 块所对应的内容;而对于 vue,官方给出的说法是,每个 v-else 所绑定语句必须绑定在 v-if 或者 v-else-if 语句的后面。一开始我还抱有一丝希望地去试了一下,结果。。。

遍历次数为0的时候,v-else 绑定的元素没有渲染出来,而且控制台还报错了。

个人感觉,在这一方面,vue 的模板引擎可能有所欠缺。虽然说,我们可以利用在循环中添加条件判断实现相同的功能,但却需要添加额外的代码。

(3)v-else-if

<div id="app">
  <div v-if="c1">c1</div>
  <div v-else-if="c2">c2</div>
</div>
......
var app = new Vue({
  el: '#app',
  data: {
    c1: false,
    c2: true
  }
});

这里先检查 c1 是否为真值,是则渲染出 v-if 绑定的元素,否则检查 c2 是否为真值,是则渲染出 v-else-if 所绑定的元素。如果 c1 / c2 都不为真值,则都不渲染。渲染结果如下:

<div id="app">
  <div>c2</div>
</div>

不难理解,v-if、 v-else、 v-else-if 跟类 C 语言中的 if、else、else if 功能相仿。

二、条件渲染优化

除了提供跟类 C 语言中的 if、else、else if 相似的功能以外,vue 还为开发者提供了性能优化方案。

(1)v-show

v-show 有着和 v-if 相似而又不同的功能,v-if 依赖于控制 DOM 节点,而 v-show 是依赖于控制 DOM 节点的 display 属性。

<div id="app">
  <div v-show="c4">c4</div>
</div>
......
var app = new Vue({
  el: '#app',
  data: {
    c4: false
  }
});

当 v-show 绑定的值为真值的时候,节点正常渲染;当为假值的时候,节点仍旧渲染,但是添加了 style="display:none;",将节点通过 CSS 的方式隐藏。渲染结果如下:

<div id="app">
  <div style="display: none;">c4</div>
</div>

相比于 v-if,v-show 其实不管在什么条件下,一开始都会进行节点的渲染,而后续的状态切换都是基于 CSS 实现的。针对状态需要频繁切换状态的节点,v-show 相对于直接修改 DOM 节点的 v-if 有更好的性能。

然而,v-show 的缺点也是显而易见的,不管初始条件如何,它都将进行 DOM 节点的渲染,这对首屏加载优化不一定是个好事情。

(2)key

在使用 v-if 等指令的时候,vue 会尽可能地复用已经渲染的元素,而不是全部地重头渲染。例如一对绑定 v-if 与 v-else 的元素,如果二者内部 DOM 元素相同,则可能在所绑定数据改变时,只更新绑定了的属性,其它通过用户操作或者 JS 修改了的属性将被保留。

<div id="app">
  <form>
    <div class="input-group" v-if="name">
      <label for="name">name:</label>
      <input type="text" name="name" placeholder="user name" />
    </div>

    <div class="input-group" v-else>
      <label for="email">email:</label>
      <input type="text" name="email" placeholder="email" />
    </div>

    <button v-on:click.prevent="toggle">toggle</button>
  </form>
</div>
......
var app = new Vue({
  el: '#app',
  data: {
    name: true
  },
  methods: {
    toggle: function () {
      this.name = ! this.name;
    }
  }
});

这里就是如此,点击 toggle 按钮的时候,v-if 所绑定的值会切换,相应的,DOM 节点也会跟着切换,但是实际上,由于 vue 重用了 input 元素,切换的同时,用户填写的内容并没有被清空。同理,label 元素在切换的工程中,其实也只是修改了 for 属性和元素内的文字,并没有销毁原有 DOM 节点和生成新的 DOM节点。

但是 vue 做的这种优化并不总是为人们所需要的,不需要它的时候,我们为这个元素添加一个唯一的 key 值就可以了。

<div id="app">
  <form>
    <div class="input-group" v-if="name">
      <label for="name">name:</label>
      <input type="text" name="name" placeholder="user name" key="name" />
    </div>

    <div class="input-group" v-else>
      <label for="email">email:</label>
      <input type="text" name="email" placeholder="email" key="email" />
    </div>

    <button v-on:click.prevent="toggle">toggle</button>
  </form>
</div>
......
var app = new Vue({
  el: '#app',
  data: {
    name: true
  },
  methods: {
    toggle: function () {
      this.name = ! this.name;
    }
  }
});

像这样,为这两个不需要“优化”的 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 id="app">
  <template v-if="c3">text</template>
</div>
......
var app = new Vue({
  el: '#app',
  data: {
    c3: true
  }
});

渲染结果:

<div id="app">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=""。

(0)

相关推荐

  • Vue.JS入门教程之列表渲染

    你可以使用 v-repeat 指令来基于 ViewModel 上的对象数组渲染列表.对于数组中的每个对象,该指令将创建一个以该对象作为其 $data 对象的子 Vue 实例.这些子实例继承父实例的数据作用域,因此在重复的模板元素中你既可以访问子实例的属性,也可以访问父实例的属性.此外,你还可以通过 $index 属性来获取当前实例对应的数组索引. <ul id="demo"> <li v-repeat="items" class="ite

  • Vue.js仿Metronic高级表格(二)数据渲染

    上篇使用Vue.js制作仿Metronic高级表格(一)静态设计介绍了需求.原型设计以及静态页面实现,这篇讲解如何使用Vue渲染数据,实现动态展示. 表格数据 先定义一个数组来保存所有数据: var vm = new Vue({ el:'#content', data: { book_list: [ {id:1, name:"标准日本语", type: "文化", price:19.00, time: 1492502043}, {id:2, name:"微

  • Vue.js实现多条件筛选、搜索、排序及分页的表格功能

    与上篇实践教程一样,在这篇文章中,我将继续从一种常见的功能--表格入手,展示Vue.js中的一些优雅特性.同时也将对filter功能与computed属性进行对比,说明各自的适用场景,也为vue2.0版本中即将删除的部分filter功能做准备. 需求分析 还是先从需求入手,想想实现这样一个功能需要注意什么.大致流程如何.有哪些应用场景. 表格本身是一种非常常用的组件,用于展示一些复杂的数据时表现很好. 当数据比较多时,我们需要提供一些筛选条件,让用户更快列出他们关注的数据. 除了预设的一些筛选条

  • Vue.js学习教程之列表渲染详解

    本文主要给大家介绍了关于Vue.js列表渲染的相关资料,分享出来给大家参考学习,下面来看看详细的介绍: v-for 可以使用 v-for 指令基于一个数组渲染一个列表.这个指令使用特殊的语法,形式为item in items,items 是数据数组,item 是当前数组元素的别名: 示例: <ul id="example-1"> <li v-for="item in items"> {{ item.message }} </li>

  • 用v-html解决Vue.js渲染中html标签不被解析的问题

    前言 最近在工作中遇到一个问题,在网页中后台传来的json数据中包含html标签,将该json数据绑定到Vue.js中对象中,对该对象进行for循环,发现数据中的html标签不能被解析,而是当作字符显示出来. 问题如下所示: 解决方法: Vue.js中提供了v-html这个指令来解决这个问题,或者对数据对象使用{{{vm.data}}}三个大括号来包裹对象,就可以正常解析了. 代码改动如下: 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家都 学习或者工作能带来一定的帮助,如果有疑问大家

  • vue.js声明式渲染和条件与循环基础知识

    vue.js声明式渲染和条件与循环的具体内容,分享给大家 绑定 DOM 元素文本值 html代码: <div id="app"> {{ message }} </div> JavaScript代码: var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }) 运行结果:Hello Vue! 总结:数据和 DOM 已经被关联在一起,当我们改变app.message的数据,所渲染的的DOM元素

  • 学习vue.js条件渲染

    本文实例为大家分享了vue.js中条件渲染的练习代码,供大家参考,具体内容如下 html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>条件渲染</title> </head> <body> <!-- v-if 作为判断条件 如果满足则展示它所附着的元素的内容-->

  • vue.js实现条件渲染的实例代码

    一.初探条件渲染 vue 的条件渲染,仍旧依赖于指令系统,下面逐个介绍: (1)v-if <div id="app"> <div v-if="c1">c1</div> </div> ...... var app = new Vue({ el: '#app', data: { c1: false } }); 当 c1 为真值的时候,渲染出 v-if 所绑定的元素,否则不渲染出该元素.渲染结果如下: <div id=

  • Vue.js实现输入框绑定的实例代码

    实现效果如下: 实现代码及注释 <!DOCTYPE html> <html> <head> <title>vue.js数据动态编辑</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style type=

  • vue.js自定义组件directives的实例代码

    自定义指令:以v开头,如:v-mybind. 代码示例: <input v-mybind /> directives:{ mybind:{ bind:function (el) { el.value = "this is mybind-bind" } }} 这时页面初始化时,input中会显示this is mybind-bind. 通过directives注册自定义指令mybind,每一个自定义指令中又提供若干钩子,如示例中的bind,bind的作用是定义一个在绑定时执行

  • vue.js实现开关(switch)组件实例代码

    最近开发组件的时候,自定义开发了开关(switch)组件,现将代码整理如下,方便日后复用. toggle-switch.vue <template> <label role="checkbox" :class="['switch', { toggled }]"> <input type="checkbox" class="switch-input" @change="toggle&quo

  • vue.js el-table虚拟滚动完整实例代码

    目录 前言 实例代码 总结 前言 基于Element-UI的Table 组件开发的虚拟滚动组件,支持动态高度,解决数据量大时滚动卡顿的问题 实例代码 <template> <div ref="listWrap" style="height: 400px; overflow-y: scroll; margin-top: 20px; padding: 10px" @scroll="scrollListener" > <d

  • Vue.js进行查询操作的实例详解

    Vue.js进行查询操作的实例详解 实例代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script src="../lib/vue.min.js" type="text/javascript" ></script> <title>字符转换</title> </head>

  • vue做网页开场视频的实例代码

    本demo背景是一个视频,文字是打印机效果,按钮在文字打完才会显示,点击按钮背景向上收起,同时显示默认首页组件(如是初建vue项目列表,则为helloWorld.vue的组件内容) 公司电脑没有gif动图尽情谅解 文末会附上demo地址,如需看效果,可前往下载 本人一直很喜欢网页开场有一段视频或动画,个人认为网页的开场动画起到引导浏览作用,相当于网页的一个开始,一个好的开始往往就成功了一半,对于浏览网站的用户来说,也就吸引了极大地注意力. 以上都是废话,网页开场动画在移动端的应用十分广泛,具体操

  • Vue.js实现拖放效果的实例

    页面效果如下所示: 代码请看这里,当当当当: html: <template> <div class='drag-content'> <div class='project-content'> <div class='select-item' draggable='true' @dragstart='drag($event)' v-for='pjdt in projectdatas'>{{pjdt.name}}</div> </div>

  • Vue.js框架路由使用方法实例详解

    Vue.js框架路由使用方法实例详解 html代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name='viewport' content='width=device-width,initial-

随机推荐