Vue指令

53 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情

Vue指令

Vue提供了一种非常简便的方式来控制和操作DOM,那就是Vue指令,Vue提供了各式各样的指令,我们先来了解比较常用的几个指令。

v-cloak

在刚才我们使用了 {{}} 符号来取出data中定义的数据,这一符号称为 插值表达式 ,然而这种方式取出数据有一个弊端,当网络出现波动时,页面上会将插值表达式显示出来而非显示真正的数据:

这显然会给用户造成不好的体验,为此,我们可以使用v-cloak指令来解决这一问题:

<!DOCTYPE html>
<html lang="en">
<head>
</head>
<style>
    [v-cloak] {
        display: none;
    }
</style>
<body>
    <div id="app">
        <p v-cloak>{{msg}}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el:'#app',
            data:{
                msg:"Hello Vue!"
            }
        });
    </script>
</body>
</html>

若如此做,则在msg数据被取到之前,v-cloak修饰的DOM元素将会被隐藏,这样便解决了插值表达式的闪烁问题。

v-text & v-html

这两个指令都是用于显示数据的:

<p v-text="msg"></p>
<p v-html="msg"></p>

它们在显示效果上没有什么不同:

但这两个指令之间还是有一定区别的。

首先v-text和v-html指令都不存在闪烁问题,其次它们是将数据直接覆盖到DOM上,所以DOM原先的数据就会消失;

但是v-html指令还能够将数据中的标签进行解析,而v-text不能:

<div>
  <p v-text="msg"></p>
  <p v-html="msg"></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  var app = new Vue({
    el:'#app',
    data:{
      msg:"<h1>Hello Vue!</h1>"
    }
  });
</script>

显示效果:

v-bind

有时候v-text和v-html指令都不能满足我们的需求,比如提供一个按钮的提示信息,这个时候我们可以借助v-bind指令:

<div id="app">
  <input type="button" v-bind:title="msg" value="按钮"/>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  var app = new Vue({
    el:'#app',
    data:{
      msg:"这是一个按钮"
    }
  });
</script>

效果如下:

v-bind指令用于绑定DOM属性,也就是说,只要是DOM的属性,它都能够直接进行绑定,比如input框的value属性:

<input type="button" v-bind:title="msg" v-bind:value="msg"/>

效果如下:

v-bind也能够绑定样式:

<style>
  .red {
    color: red;
  }
  .thin {
    font-weight: 200;
  }
</style>
<body>
  <div id="app">
    <h1 v-text="msg" v-bind:class="['red','thin']"></h1>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        msg: 'Hello Vue!'
      },
    });
  </script>

通过v-bind进行样式绑定时,有几种方式,这便是其中的一种,通过数组绑定,注意数组中的样式名必须用引号包含。

我们还可以通过对象进行绑定:

<div id="app">
  <h1 v-text="msg" v-bind:class="{red:true,thin:true}"></h1>
</div>

但这种方式的样式名后面必须跟上 :true 或 :false ,所以我们可以通过在data中定义一个flag进行动态设置:

<div id="app">
  <h1 v-text="msg" v-bind:class="{red:flag,thin:flag}"></h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  var app = new Vue({
    el: '#app',
    data: {
      msg: 'Hello Vue!',
      flag: true
    },
  });
</script>

此时flag就能够控制样式是否进行显示。

v-bind指令可以简写为 : ,例如:

<input type="button" :title="msg" :value="msg"/>

v-for

该指令用于循环操作:

<div id="app">
  <p v-for="item in array">
    {{item}}
  </p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  var app = new Vue({
    el: '#app',
    data: {
      array: [1, 2, 3, 4, 5]
    },
  });
</script>

v-for指令语法为 item(为数组中的每一项取一个名字) in list(待遍历的数组名) ,然后item就是数组中的每一个元素,效果如下:

有时候我们需要获得当前元素的索引值,可以这样写:

<p v-for="(item,index) in array">
  {{index}} ---- {{item}}
</p>

对于较为复杂的数组,v-for当然也能够轻松进行遍历:

<div id="app">
  <p v-for="(user,index) in array">
    索引值:{{index}}--id:{{user.id}}--name:{{user.name}}--age:{{user.age}}
  </p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  var app = new Vue({
    el: '#app',
    data: {
      array:[
        {id:1,name:'张三',age:20},
        {id:2,name:'李四',age:21},
        {id:3,name:'王五',age:22},
      ]
    },
  });
</script>

效果如下:

v-for指令还能够遍历对象:

<div id="app">
  <p v-for="(value,key,index) in user">
    索引:{{index}}---{{key}}:{{value}}
  </p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  var app = new Vue({
    el: '#app',
    data: {
      user: { id: 1, name: '张三', age: 20 }
    }
  });
</script>

效果如下:

在使用v-for指令时需要注意一点,在Vue2.2.0之后的版本,当在组件中使用v-for时,必须携带key属性,有必要解释一下它的作用。

当Vue用v-for正在更新已经渲染过的元素列表时,默认使用的是 就地复用 策略,如果数据项的顺序被改变,Vue将简单复用此处每个元素,而不是移动DOM中的元素来匹配顺序;为了给Vue一个提示,以便Vue能够跟踪每个节点的身份,从而复用和重新排序现有的元素,我们需要为每项提供一个唯一属性key:

<div id="app">
  <div>
    <label>id:</label>
    <input type="text" v-model="id">
    <label>name:</label>
    <input type="text" v-model="name">
    <input type="button" value="添加" @click="add">
  </div>
  <p v-for="user in array">
    <input type="checkbox">
    {{user.id}}--{{user.name}}
  </p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  var app = new Vue({
    el: '#app',
    data: {
      id: '',
      name: '',
      array: [
        { id: 1, name: '张三' },
        { id: 2, name: '李四' },
        { id: 3, name: '王五' }
      ]
    },
    methods: {
      add() {
        this.array.unshift({ id: this.id, name: this.name });
      }
    },
  });
</script>

该页面用于实现数据的添加操作,效果如下:

当上方填入数据并点击添加时会将数据在下面的列表中展示,然而这段程序有些许问题:

当选中3号数据,并添加4号数据时,结果如下:

选中的数据被修改为了2号,这就是没有指定key的后果,我们只需在遍历的时候为key设置一个唯一的属性即可:

<p v-for="user in array" :key="user.id">
  <input type="checkbox">
  {{user.id}}--{{user.name}}
</p>

需要注意key只能设置string或者number类型的值。

v-if & v-show

这两个指令均用于控制DOM的显示与隐藏:

<div id="app">
  <p v-if="flag">v-if</p>
  <p v-show="flag">v-show</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  var app = new Vue({
    el: '#app',
    data: {
      flag: true
    }
  });
</script>

效果如下:

咋一看,两者好像没有什么区别,但是查看源代码:

当我们将flag设置为false时,v-if指令会直接将DOM元素删除掉,而v-show指令只是将display属性置为none,隐藏了DOM。

v-on

该指令用于事件绑定,比如:

<div id="app">
  <input type="button" value="按钮" v-on:click="show"/>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  var app = new Vue({
    el:'#app',
    data:{
    },
    methods: {
      show(){
        alert("点击了按钮");
      }
    }
  });
</script>

通过v-on可以绑定事件,并在v-on后面指定需要绑定的事件,click即为点击事件,其值为需要触发的函数名,该函数必须写在Vue实例的methods属性中。

若是想要绑定其它事件,例如鼠标移除入事件:

  <input type="button" value="按钮" v-on:mouseover="show"/>

v-click也可以简写为 @ :

  <input type="button" value="按钮" @click="show"/>