vue(二) - 基础指令

229 阅读4分钟

指令的本质就是 HTML 自定义属性, Vue.js 的指令就是以 v- 开头的自定义属性

内容处理

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 设定当前元素的纯文本内容

元素内容整体替换为指定纯文本数据。

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

image.png

v-html 设置当前元素的html文本内容

元素内容整体替换为指定的 HTML 文本

<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: '这是指令设置的新内容'
        content: '<span>span的内容</span>'
      }
    });
  </script>
</body>

image.png

属性绑定

v-bind 指令

v-bind 指令用于动态绑定 HTML 属性。

image.png

简写为:

image.png

与插值表达式类似,v-bind 中也允许使用表达式 (但不允许使用语句)。

<body>
  <div id="app">
    <p v-bind:title="myTitle">p标签的内容</p>
    <p :title="myTitle">p标签的内容</p>

    <!-- num加了引号表示字符串 -->
    <p :class="'num' + 1 + 2 + 3">p标签的内容</p>
    <p :class="prefix + num"></p>

    <!-- <p :class="var a = 1"></p> -->
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        myTitle: '这是title的内容',
        prefix: 'demo',
        num: 10
      }
    });
  </script>
</body>

image.png

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

<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>

image.png

Class 绑定

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

可以使用表达式.

<body>
  <div id="app">
    <p v-bind:class="cls1">标签内容</p>
    <p class="a" :class="cls1">标签内容</p>

    <!-- 下面是错误写法,要注意 -->
    <!-- <p class="a b c" :class="cls1 cls2"></p> -->

    <p :class="cls"></p>

    <p :class="bool ? cls1 : cls2"></p>

  </div>

  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        bool:true,
        cls:"cls1 cls2", //不常用, 不灵活
        cls1:"cls1",
        cls2:"cls2"
      }
    });
  </script>
</body>

image.png

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

  1. 允许在class绑定的时候设置对象结构, 对象中有和值两部分, 表示的是我们要设置的类名, 表示是否生效

image.png

<body>
  <div id="app">
    <p :class="{x:isX, y:isY, z:isZ}"></p>  
  </div>

  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        isX: true,
        isY:true,
        isZ:false
      }
    });
  </script>
</body>

结果: <p class="x y"></p>

  1. 允许在class绑定的时候设置数组, 下图中a和c为固定的类名部分, 中间的大括号是动态绑定的区域,

image.png

<body>
  <div id="app">
    <p :class="['a',classB,{c: isC}]"></p>
  </div>

  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        classB:"b",
        isC:true
      }
    });
  </script>
</body>

结果: <p class="a b c></p>

Style 绑定

style 是 HTML 属性,可以通过 v-bind 进行绑定,并且可以与style 属性共存, 共存时以style绑定的属性为准。

image.png

<body>
  <div id="app">
    <!-- <p v-bind:style="{width: '100px', height: '100px'}"></p> -->
    <p :style="styleObj">标签内容</p>

    <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', //px单位不能去掉
          backgroundColor: 'red',
          'font-size': '30px'
        }
      }
    });
  </script>
</body>

image.png

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

image.png

<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>

image.png

渲染指令

v-for指令

遍历

用于遍历数据渲染结构,常用的数组对象均可遍历。

image.png

v-for="item in arr"  //只取数组或对象的内容
v-for="(item, index) in arr" //获取数组内容和索引
v-for="(value, key, index) in obj" //获取对象内容,键, 索引
<body>
  <div id="app">
    <ul>
      <!-- 获取数组内容 -->
      <li v-for="item in arr">数组元素内容为:{{ item }}</li><br>

      <!-- 获取数组内容和索引 -->
      <li v-for="(item, index) in arr">
        数组元素内容为:{{ item }}, 索引为:{{ index }}
      </li><br>

      <!-- 获取对象内容 -->
      <li v-for="value in obj">对象元素内容为:{{ value }}</li><br>
      
      <!-- 获取对象内容和键, 索引 -->
      <li v-for="(value, key, index) in obj">
        对象元素内容为: {{ value }}, 键为: {{ key }}, 索引值为: {{ 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>

image.png

创建多个标签

也可以用来创建<li>标签

    <ul>
      <li v-for="(item, index) in 5">
        这是第{{ item }}个元素,索引值为:{{ index }}
      </li>
    </ul>

image.png

key属性

使用 v-for 的同时,应始终指定唯一的 key 属性,可以提高渲染性能并避免问题。比如说有多个输入框, 当输入框前面的内容翻转时, 导致提示内容和输入框输入的文本不对应的情况.

key的作用:

  • 避免问题
  • 可以提高渲染效率
  1. 数组中没有重复值时, 可以将key指定为元素的内容.
<body>
  <div id="app">
    <ul>
      <li v-for="item in itemList" :key="item">
        输入框{{ item }}: <input type="text">
      </li>
    </ul>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        arr: [1, 2, 3]
      }
    })
  </script>
</body>
  1. 如果数组中出现重复的值, 最好是用id进行分隔, 并且用id作为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: {
        itemList: [
          {
            id: 1,
            value: 2
          },
          {
            id: 2,
            value:3
          },
          {
            id:3,
            value:3
          }
        ]
      }
    })
  </script>
</body>

模板占位符

通过<template>标签设置模板占位符,可以将部分元素或内容作为整体进行操作。它并不是真正的标签, 不会显示. 不需要设置key. 比如这里是将<span><br>作为一个整体进行操作.

image.png

<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>

image.png

v-show 指令

用于控制元素显示与隐藏,适用于显示隐藏频繁切换时使用。实质是通过display属性来控制元素的显示与隐藏.

image.png

除了直接设置truefalse的值以外, 还有其他方式:

  • 设置一个表达式, 通过表达式的结果是true还是false来判断

  • data中的数据绑定给v-show

<body>
  <div id="app">
    <p v-show="false">标签内容</p>
    
    <p v-show="22 > 11">标签内容</p>

    <p v-show="bool">标签内容</p>

    <template v-show='false'>这是内容</template>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: "#app",
      data: {
        bool: true
      }
    });
  </script>
</body>

注意

  • <template> 无法使用 v-show 指令, 因为v-show 本质是用display, 而<template>不是一个真实的标签。

v-if 指令

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

image.png

<body>
  <div id="app">
    <p v-if="bool">这是标签内容</p>
    <p v-else-if="false">这是第二个p标签</p>
    <p v-else-if="false">这是第三个p标签</p>
    <p v-else>最后一个p标签</p>
  </div>
  <script src="lib/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        bool: false
      }
    });
  </script>
</body>

设置key

给使用 v-if 的同类型元素绑定不同的key

<body>
  <div id="app">
    <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-for和v-if不要同时用

注意

出于性能考虑,应避免将 v-if 与 v-for 应用于同一标签

因为v-for优先级更高, 会先执行v-for, 如果v-if为false就执行了无意义的操作.

<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>