Vue.js - 基础指令

以下笔记皆基于 Vue 2

指令是本身是给框架识别的一种标记,可以指示框架快速对元素进行处理,减少 DOM 操作,而 Vue.js 指令的本质就是以 v- 开头的 HTML 自定义属性。

内容处理


v-once 指令

使元素内部的插值表达式值生效一次。

<body>
  <div id="app">
    <p>此内容会随数据变化而自动变化:{{ content }}</p>
    <p v-once>此内容不会随数据变化而自动变化: {{ content }}</p>
  </div>

  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        content: '内容文本'
      }
    })
  </script>
</body>

v-text 指令

元素内容整体替换为指定纯文本数据。与插值表达式不同的是,v-text 指令会覆盖整个元素的原始内容,其底层调用的是 textContent 属性。
属性。

<body>
  <div id="app">
    <p v-text="content">这是 p 标签的原始内容</p>  
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        content: '内容文本',
      }
    });
  </script>
</body>

v-html 指令

元素内容整体替换为指定的 HTML 文本。和 v-text 类似,该指令会覆盖整个元素的原始内容。

<body>
  <div id="app">
    <p v-html="content">这是默认的文本内容</p>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        content: '<span>span的内容</span>'
      }
    });
  </script>
</body>

属性绑定


v-bind 指令

v-bind 指令用于动态绑定 HTML 属性,同时 Vue.js 还为 v-bind 指令提供了简写方式。也与插值表达式类似,v-bind 中也允许使用表达式。

<body>
  <div id="app">
    <p v-bind:title="myTitle">p标签的内容</p>
    <!-- 简化写法 -->
    <p :title="myTitle">p标签的内容</p>
    <!-- 使用表达式 -->
    <p :class="'num' + 1 + 2 + 3">p标签的内容</p>
    <p :class="prefix + num"></p>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        myTitle: '这是title的内容',
        prefix: 'demo',
        num: 10
      }
    });
  </script>
</body>

如果需要一次绑定多个属性,还可以绑定对象。

<body>
  <div id="app">
    <p v-bind="attrObj">这是 p 标签的内容</p>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        attrObj: {
          id: 'box',
          title: '示例内容',  // 固有属性
          class: 'clearFix', // 固有属性
          'data-title': '这是 data-title 的内容' // 自定义属性
        }
      }
    });
  </script>
</body>

class 绑定

class 是 HTML 属性,可以通过 v-bind 进行绑定,并且可以与 class 属性共存。

<body>
  <div id="app">
    <p v-bind:class="cls">标签内容</p>
    <p class="a" :class="cls">标签内容</p>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        cls: 'x',
      }
    });
  </script>
</body>

对于 class 绑定, Vue.js 中还提供了特殊处理方式:

  • 对象结构,对象结构中,键作为类名(带 - 类名可以用 '' 包裹),值使用布尔值判断类名是否生效,对象中可以同时书写多个类名:
    <body>
      <div id="app">
        <p :class="{ b: isB, c: isC, 'class-d': true }"></p>
      </div>
      <script src="lib/vue.js"></script>
      <script>
        var vm = new Vue({
          el: '#app',
          data: {
            isB: true,
            isC: false
          }
        });
      </script>
    </body>
    
  • 数组结构,该方式同样可以设置多个类名,并且可以在数组内设置固定的类名,以及需要条件判断的类名:
    <body>
      <div id="app">
        <p :class="[ 'a', {b: isB}, 'c' ]"></p>
      </div>
      <script src="lib/vue.js"></script>
      <script>
        var vm = new Vue({
          el: '#app',
          data: {
            isB: true,
          }
        });
      </script>
    </body>
    

style 绑定

style 是 HTML 属性,可以通过 v-bind 进行绑定,并且可以与 style 属性共存,需要传入对象形式的值。键表示样式属性名,可以使用传统命名法或者驼峰命名法;值表示样式属性值,样式单位不能省略。

<body>
  <div id="app">
    <p :style="styleObj">标签内容</p>
    <!-- 以绑定的 width 值为准,即最后宽度为 200px -->
    <p style="width: 100px" :style="styleObj">标签内容</p>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        styleObj: {
          width: '200px',
          height: '200px',
          border: '1px solid #ccc',
          backgroundColor: 'red',
          'font-size': '30px'
        }
      }
    });
  </script>
</body>

当我们希望给元素绑定多个样式对象时,可以设置为数组。

<body>
  <div id="app">
    <p :style="[baseStyle, styleObj1]">第一个 p 标签</p>
    <p :style="[baseStyle, styleObj2]">第二个 p 标签</p>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        // 公共样式
        baseStyle: {
          width: '100px',
          height: '100px'
        },
        styleObj1: {
          backgroundColor: 'red'
        },
        styleObj2: {
          backgroundColor: 'blue'
        }
      }
    });
  </script>
</body>

渲染指令


v-for指令

用于遍历数据渲染结构,常用的数组与对象均可遍历,还可以进行值的处理,通过()内声明多个标识符以获得索引或者键。

<body>
  <div id="app">
    <ul>
      <li v-for="item in arr">元素内容为:{{ item }}</li>
      <li v-for="(item, index) in arr">
        元素内容为:{{ item }}, 索引为:{{ index }}
      </li>

      <li v-for="value in obj">元素内容为:{{ value }}</li> 
      <li v-for="(value, key, index) in obj">
        元素内容为: {{ value }}, 键为: {{ key }}, 索引值为: {{ index }}
      </li>
    </ul>

    <ul>
      <!-- 从 1 开始遍历到 5 -->
      <li v-for="(item, index) in 5">
        这是第{{ item }}个元素,索引值为:{{ index }}
      </li>
    </ul>

  </div>
  <script src="lib/vue.js"></script>
  <script>
    new Vue({
      el: '#app',
      data: {
        arr: ['内容1', '内容2', '内容3']
        obj: {
          content1: '内容1',
          content2: '内容2',
          content3: '内容3'
        }
      }
    });
  </script>
</body>

v-for 的默认行为会尝试原地修改元素而不是移动它们,所以想要强制其重新排序元素,应始终指定唯一的 key 属性,可以提高渲染性能并避免问题。

<body>
  <div id="app">
    <ul>
      <li v-for="(item, index) in itemList" :key="item.id">
        输入框{{ item.value }}: <input type="text">
      </li>
    </ul>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        arr: [1, 2, 3],
        itemList: [
          { id: 1, value: 2 },
          { id: 2, value: 3 },
          { id: 3, value: 3 }
        ]
      }
    })
  </script>
</body>

通过 <template> 标签设置模板占位符,可以将部分元素或内容作为整体进行操作,<template> 不是一个真实的元素标签,它只是一个占位符,在 DOM 上是不存在的。

<body>
  <div id="app">
    <template v-for="item in obj">
      <span>{{ item }}</span>
      <br>
    </template>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        obj: {
          content1: '内容1',
          content2: '内容2',
          content3: '内容3'
        }
      }
    })
  </script>
</body>

v-show 指令

v-show 用于控制元素显示与隐藏,适用于显示隐藏频繁切换时使用。
注意:因为v-show 的本质是给元素添加 display:none 样式属性,因此<template> 无法使用 v-show 指令。

<body>
  <div id="app">
    <!-- 布尔值表示显示隐藏 -->
    <p v-show="false">标签内容</p>
    <!-- 布尔值表达式 -->
    <p v-show="22 > 11">标签内容</p>
    <!-- 绑定值 -->
    <p v-show="bool">标签内容</p>
    <!-- v-show 没有效果 -->
    <template v-show='false'>这是内容</template>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: "#app",
      data: {
        bool: true
      }
    });
  </script>
</body>

v-if 指令

v-if 用于根据条件控制元素的创建与移除。

<div>
  <p v-if="false">这个元素不会创建</p>  
  <p v-else-if="true">这个元素会创建</p>  
  <p v-else>这个元素不会创建</p>  
</div>

如果使用 v-if 的元素是同类型元素,则需要绑定不同的 key,原因和 v-for 类似。

<body>
  <div id="app">
    <!-- 绑定 key 确保输入框也创建和移除 -->
    <div v-if="type==='username'" :key="'username'">
      用户名输入框:<input type="text">
    </div>
    <div v-else :key="'email'">
      邮箱输入框:<input type="text">
    </div>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        bool: true,
        type: 'username'
      }
    });
  </script>
</body>

出于性能考虑,应避免将 v-if 与 v-for 应 用于同一标签,因为 v-for 的渲染优先级要高于 v-if,因此在会先遍历生成元素,再执行判断创建或移除,影响渲染效率。可以将 v-if 放在父级,v-for 放在子级,以提高渲染效率。

<body>
  <div id="app">
    <ul v-if="false">
      <li v-for="item in items">{{item}}</li>
    </ul>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
       items: {
         content1: '内容1',
         content2: '内容2',
         content3: '内容3'
       }
      }
    });
  </script>
</body>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,458评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,030评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,879评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,278评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,296评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,019评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,633评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,541评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,068评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,181评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,318评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,991评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,670评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,183评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,302评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,655评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,327评论 2 358

推荐阅读更多精彩内容