目录 

一、前言

二、实例 

前提:

1.内容渲染指令

v-text   

{{ }}    插值表达式

扩展一:

v-html

2.属性绑定指令

3. 事件绑定指令

扩展二:

4. 双向绑定指令

案例:利用v-model来实现评论区案例

.lazy

.number

.trim

5. 条件渲染指令

扩展四:

6.列表渲染指令

扩展五:

key 的注意事项


一、前言

本文的主要目的是学习如何在html文件中定义并使用指令。
学习本文前需要掌握html基础,vue指令等。

以下的内容都基于黑马程序员课程资料和菜鸟教程和部分博主来写。

二、实例 

vue 中的指令按照不同的用途可以分为如下 6 大类:

内容渲染指令 ② 属性绑定指令 ③ 事件绑定指令 ④ 双向绑定指令 ⑤ 条件渲染指令 ⑥ 列表渲染指令

前提:

  1. 引入vue.js文件
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>

1.内容渲染指令

内容渲染指令 包括:   v-text   {{ }}   v-html

v-text   

<!DOCTYPE html>
<html>

<head>
    <!-- 标签页的标题 -->
    <title>我的第一个Vue项目</title>
    <!-- 引入vue.js -->
    <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>

<body>
    <div id="app">
        <!--  v-text覆盖了标签中的内容(原有的内容),展示message的值 -->
        <p v-text="message">等待被覆盖的内容</p>
    </div>

    <!-- 页面的js代码 -->
    <script>
        // 新建一个Vue对象
        const vm = new Vue({
            // el是element的缩写,#app是id选择器
            el: '#app',
            // 页面使用的变量需要在data中注册(定义)
            data: {
                message: '把 v-text 覆盖了'
            }
        })
    </script>
</body>

</html>

注意:v-text 指令会覆盖元素内默认的值

{{ }}    插值表达式

vue 提供的 {{ }} 语法,专门用来解决 v-text 会覆盖默认文本内容的问题。这种 {{ }} 语法的专业名称是 插值表达
(英文名为: Mustache )。
<!DOCTYPE html>
<html>

<head>
    <!-- 标签页的标题 -->
    <title>我的第一个Vue项目</title>
    <!-- 引入vue.js -->
    <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>

<body>
    <div id="app">
        <!-- 展示message的值 -->
        {{ message }}
    </div>

    <!-- 页面的js代码 -->
    <script>
        // 新建一个Vue对象
        const vm = new Vue({
            // el是element的缩写,#app是id选择器
            el: '#app',
            // 页面使用的变量需要在data中注册(定义)
            data: {
                message: 'Hello Vue!'
            }
        })
    </script>
</body>

</html>

注意:相对于 v-text 指令来说,插值表达式在开发中更常用一些!因为它不会覆盖元素中默认的文本内容。

扩展一:

<!DOCTYPE html>
<html>

<head>
    <!-- 标签页的标题 -->
    <title>插值表达式</title>
    <!-- 引入vue.js -->
    <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>

<body>
    <div id="app">
      <!-- 在 vue 提供的模板渲染语法中,除了支持绑定简单的数据值之外,还支持 Javascript 表达式的运算 -->
    
        <!-- 利用插值表达式来实现 加法运算 -->
        <p>计算1+2的结果:{{1+2}}</p>
        <hr>
        <!-- 利用插值表达式和三目运算符来实现  简单判断-->
        <p>{{ok?'yes':'no'}}</p>
        <hr>
        <!-- 利用插值表达式和js对象来实现 -->
        <p>{{ tips }} 反转的结果是 : {{ tips.split('').reverse().join('') }}</p>
        <hr>
        <p :title=" 'box' + index ">这是一个div里面有title</p>
    </div>

    <!-- 页面的js代码 -->
    <script>
        // 新建一个Vue对象
        const vm = new Vue({
            // el是element的缩写,#app是id选择器
            el: '#app',
            // 页面使用的变量需要在data中注册(定义)
            data: {
                tips : '请输入用户名',
                photo : './images/vue.jpg',
                index : 3,
            }
        })
    </script>
</body>

</html>

v-html

v-text 指令和 插值表达式 只能渲染 纯文本内容 。如果要把 包含 HTML 标签的字符串 渲染为页面的 HTML 元素,
则需要用到 v-html 这个指令:
<!DOCTYPE html>
<html>

<head>
    <!-- 标签页的标题 -->
    <title>我的第一个Vue项目</title>
    <!-- 引入vue.js -->
    <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>

<body>
    <div id="app">
      <!-- 展示html中的 h1 属性 -->
       <p v-html="discription"></p>
    </div>

    <!-- 页面的js代码 -->
    <script>
        // 新建一个Vue对象
        const vm = new Vue({
            // el是element的缩写,#app是id选择器
            el: '#app',
            // 页面使用的变量需要在data中注册(定义)
            data: {
              discription : '<h1>我是h1标签</h1>'
            }
        })
    </script>
</body>

</html>

2.属性绑定指令

属性绑定指令 包括:  v-bind

vue规定 v-bind: 指令可以简写为  :  

<!DOCTYPE html>
<html lang="en">
<head>
    <title>v-bind指令</title>
</head>
<body>
    <div id="app">
        <!--vue规定 v-bind: 指令可以简写为  :  -->
        <input type="text" v-bind:placeholder="tips" >
        <!-- 下面的input 没有使用v-bind 来使用,而是使用 placeholder 来实现· -->
        <input type="text" placeholder="密码">
        <hr>
        <!-- 使用v-bind来实现 图片效果 src路径地址中添加photo变量-->
        <!-- 这里使用v-bind 的简写  : -->
        <img :src="photo" alt=""> 
        
    </div>
    <script src="./js/vue.js"></script>
    <script>
      const vm =  new Vue({
            el : '#app',
            data : {
                tips : '请输入用户名',
                photo : './images/vue.jpg',
                
            }
        })
    </script>
</body>
</html> 

3. 事件绑定指令

事件绑定指令 包括:  v-on

vue 提供了 v-on 事件绑定指令,用来辅助我们为 DOM 元素绑定事件监听。

v-on: 指令可以简写为  @

通过 v-on 绑定的事件处理函数,需要 在 methods 节点 中进行声明:
绑定事件并传参
<!DOCTYPE html>
<html lang="en">
<head>
    <title>v-on指令</title>
</head>
<body>
    <div id="app">
        <p>{{num}}</p>
        <!-- 在绑定事件处理函数,可以使用()来传递参数 -->
        <!-- v-on: 指令可以简写为 @  -->
        <button v-on:click="add(2)">+2</button>
        <button @click="sub">-1</button>
    </div>
    <script src="./js/vue.js"></script>
    <script>
        const vm =  new Vue({
            el : '#app',
            data : {
               
                num : 0
                
            },
            //methods 的作用定义事件的处理函数
            methods:{
                // add:function(){
                //     this.num++;
                // }
                //简写
                add (n){
                    //this.num += n; 
                    this.num += n; 
                },
                sub(){
                    this.num--;
                }
            }
        })
    </script>
</body>
</html>
注意:原生 DOM 对象有 onclick oninput onkeyup 等原生事件,替换为 vue 的事件绑定形式后,
分别为: v-on:click v-on:input v-on:keyup

扩展二:

事件参数对象  :  $event
在原生的 DOM 事件绑定中,可以在事件处理函数的形参处,接收事件参数对象 event。同理,在 v-on 指令 (简写为 @ )所绑定的事件处理函数中, 同样可以接收到事件参数对象 event ,示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件对象$event</title>
</head>
<body>
    <div id="app">
        <p>{{count}}</p>
        <!-- Vue提供了内置变量,$event,它是原生dom的事件对象 -->
        <!-- 通过count的叠加来分别button的颜色 -->
        <button @click="add(1,$event)" >+1</button>
    </div>
    <script src="./js/vue.js"></script>
    <script>
        const vm = new Vue({
            el : '#app',
            data : {
                count : 0,
            },
           methods:{
            add (n,e){  // 接收事件参数对象  event 简写为 e
                this.count += n;
                console.log(e);
               
                //判断this.count 的值
                if(this.count %2 == 0){
                    e.target.style.backgroundColor = 'green';
                }else{
                    e.target.style.backgroundColor = 'red';
                }
            }
           }
        })
    </script>
</body>
</html>

事件修饰符  :.prevent  .stop  .capture  .once .self
在事件处理函数中调用 event.preventDefault() event.stopPropagation() 是非常常见的需求。因此, vue 提供了 事件修饰符 的概念,来辅助我们更方便的 对事件的触发进行控制 。常用的 5 个事件修饰符如下:
  • .stop - 阻止冒泡
  • .prevent - 阻止默认事件
  • .capture - 阻止捕获
  • .self - 只监听触发该元素的事件
  • .once - 只触发一次
  • .left - 左键事件
  • .right - 右键事件
  • .middle - 中间滚轮事件
以下展示我们经常在 事件处理函数中调用 . pervent    和   .stop
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件修饰符 .prevent 和 .stop</title>
    <style>
        .stop{
            height: 100px; 
            background-color:lightblue;
             line-height:100px;
            padding-left: 200px;
        }
    </style>
</head>
<body>
    <div id="app">
        <div>
            <!-- @click.prevent  阻止页面跳转 -->
            <a href="http://www.baidu.com" @click.prevent="show">百度</a>
        </div>
        <hr>
        
        <div class="stop" @click="divHandler">
            <!-- @click.stop  阻止事件冒泡-->
            <button @click.stop="btnHandler">按钮</button>
        </div>

    </div>
    <script src="./js/vue.js"></script>
    <script>
        const vm = new Vue({
            el : '#app',
            data : {

            },
            methods : {
                show (e){
                    //e.preventDefault(); //阻止页面跳转
                    console.log('点击了 <a> 链接');
                },
                divHandler(){
                    console.log('div-Handler');
                },
                btnHandler(){
                    console.log('btn-Handler');
                }
            }
        })
    </script>
</body>
</html>

按键修饰符
在监听 键盘事件 时,我们经常需要 判断详细的按键 。此时,可以为 键盘相关的事件 添加 按键修饰符 ,例如:
​​​​<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>按键修饰符</title>
</head>
<body>
    <div id="app">
        <!-- @keyup.enter @keyup.esc-->
        清空内容:<input type="text" @keyup.esc="clearInput" @keyup.enter="commitAjax">
    </div>
    <script src="./js/vue.js"></script>
    <script>
        const vm = new Vue({
            el : '#app',
            data : {

            },
            methods : {
                clearInput(e){
                    e.target.value = '';
                    console.log('触发了clearInput方法清空内容·');
                    alert('触发了clearInput方法清空内容,是否清空?');
                    
                },
                commitAjax(){
                    console.log('触发了commitAjax方法发送内容·');
                    alert('触发了commitAjax方法发送内容·');
                }
            }
        })
    </script>
</body>
</html>
注意: 以上仅仅使用了两个键盘事件,分别使 Esc 和Enter 按键。

全部的按键别名:

  • .enter
  • .tab
  • .delete (捕获 "删除" 和 "退格" 键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

系统修饰键:

  • .ctrl
  • .alt
  • .shift
  • .meta

鼠标按钮修饰符:

  • .left
  • .right
  • .middle

4. 双向绑定指令

双向绑定指令 包括:  v-model

vue 提供了 v-model 双向数据绑定 指令,用来辅助开发者在 不操作 DOM 的前提下, 快速获取表单的数据
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-model 指令</title>
</head>
<body>
    <div id="app">
        <p>{{username}}</p>
        <!-- 只有表单(input textarea select )才能有意义使用v-model -->
        <!-- v-model双向绑定指令 -->
        双向绑定指令:<input type="text" v-model="username"> 
        <hr>
        <!-- v-bind单向绑定指令 -->
        单向绑定指令:<input type="text" :value="username">
        <hr>
        <select name="" id="" v-model="city">
            <option value="">请选择您的城市</option>
            <option value="1">北京</option>
            <option value="2">上海</option>
            <option value="3">广州</option>
        </select>
        
    </div>
    <script src="./js/vue.js"></script>
    <script>
        const vm = new Vue({
            el : '#app',
            data : {
                username : 'v-model',
                city : '',
            },
            methods : {
                
                
            }
        })
    </script>
</body>
</html>

案例:利用v-model来实现评论区案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-model指令来实现评论区</title>
    <style>
        *{
            list-style: none;
        }
        textarea{
            resize: none;
            outline: none;
        }
    </style>
</head>
<body>
    <div id="app">
        <textarea name="" id="" cols="30" rows="10" v-model="msg" pa>{{msg}}</textarea>
        <button @click="change()">发表评论</button>
        <button @click="change2()">删除评论</button>
        <button @click="del()">指定删除</button>

        <ul>
            <li v-for="(item, index) in list" @click="del(index)" style="cursor: pointer;">
                {{ item }} ------------------------- <button>删除</button>
            </li>
        </ul>
    </div>
    <script src="./js/vue.js"></script>
    <script>
        const vm = new Vue({
            el : '#app',
            data:{
                msg: '',
                list : ['第一条评论','第2条评论']
            },
            methods:{
                change(){
                    this.list.push(this.msg)
                   
                },
                change2 (){
                    this.list.shift(this.msg)
                },
                del(a){
                    this.list.splice(a,1)
                }
            }
        })
    </script>
</body>
</html>

以上案例 别较真!!!

扩展三:
v-model 修饰符: 为了方便对用户输入的内容进行处理 ,vue 为 v-model 指令提供了 3 个修饰符,分别是:

.lazy

在默认情况下, v-model 在 input 事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步

.number

如果想自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个修饰符 number 给 v-model 来处理输入值

.trim

如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-model 修饰符</title>
</head>
<body>
    <div id="app">
        <!-- v-model.number 自动将用户输入值转为数值类型-->
        v-model.number<input type="text" v-model.number="n1"> + <input type="text" v-model.number="n2"> = <span>{{ n1 + n2 }}</span>
        <hr>
        <!-- v-model.trim 自动过滤用户的首尾空白字符-->
        v-model.trim<input type="text" v-model.trim="username"> 
        <button @click="showName">获取用户名</button>
        <hr>
        <!-- v-model.lazy 在change时并不会实时更新input  -->
        v-model.lazy<input type="text" v-model.lazy="username">
    </div>
    <script src="./js/vue.js"></script>
    <script>
        const vm = new Vue({
            el : '#app',
            data : {
                username : 'zys',
                n1 : 1,
                n2 : 2
            },
            methods : {
                showName() {
                    alert(`用户名是:"${this.username}"`);
                }
            }
        })
    </script>
</body>
</html>

5. 条件渲染指令

条件渲染指令 包括:  v-if  v-show

条件渲染指令用来辅助开发者按需控制 DOM 的显示与隐藏

v-if 可以单独使用,或配合 v-else 指令一起使用
v-else-if 指令,顾名思义,充当 v-if 的“else-if 块”,可以连续使用
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>条件渲染指令</title>
</head>
<body>
    <div id="app">
        <!-- v-if的原理是 : 每次动态创建或移除元素,实现元素的显示隐藏
             如果刚进入页面的时候,某些元素不需要被展示,后期也不需要用 用v-if性能更好 -->
        <p v-if="flag">这是被v-if控制的元素</p>
        <!-- v-show原理是 添加或移除display: none 样式,来实现元素的显示隐藏
             如果频繁的切换元素的显示状态,用v-show -->
        <p v-show="flag">这是被v-show控制的元素</p>

        <hr>
        <div v-if=" type === 'A' ">优</div>
        <div v-else-if=" type === 'B' ">良</div>
        <div v-else-if=" type === 'C' ">及格</div>
        <div v-else>差</div>
    </div>
    <script src="./js/vue.js"></script>
    <script>
        const vm = new Vue({
            el : '#app',
            data : {
                //如果 flag 为 true,则显示被控制的元素,为false则隐藏被控制元素
                flag : true,
                type : 'A'
            },
            methods : {
                
            }
        })
    </script>
</body>
</html>
注意:v-else-if 指令 必须配合 v-if 指令一起使用,否则它将不会被识别!

扩展四:

v-if 和 v-show 的区别
实现原理不同:
v-if 指令会动态地创建或移除 DOM 元素,从而控制元素在页面上的显示与隐藏;
 v-show 指令会动态为元素添加或移除 style="display: none;" 样式,从而控制元素的显示与隐藏;
性能消耗不同:
v-if 有更高的 切换开销 ,而 v-show 有更高的 初始渲染开销 。因此:
如果需要 非常频繁地切换 ,则使用 v-show 较好
如果在 运行时条件很少改变 ,则使用 v-if 较好

6.列表渲染指令

列表渲染指令 包括: v-for

vue 提供了 v-for 列表渲染指令,用来辅助开发者 基于一个数组来循环渲染一个列表结构 。v-for 指令需要使
item in list  形式的特殊语法,其中:
items 是 待循环的数组 ,  list 是 被循环的每一项

简单的v-for 循环:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>简单的v-for 循环</title>
</head>
<body>
    <div id="app">
        <ul>
            <!-- item 是待循环的数组 , list 是被循环的每一项 -->
            <li v-for="item in list">
                {{ item }}
            </li>
        </ul>
        
    </div>
    <script src="./js/vue.js"></script>
    <script>
        const vm = new Vue({
            el : '#app',
            data:{
                list : ['123','234','456','999']
            },
        })
    </script>
</body>
</html>

扩展五:

v-for 中的索引
v-for 指令还支持一个 可选的 第二个参数,即 当前项的索引 。语法格式为 ( item , index ) in items ,示例代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>v-for 循环</title>
</head>
<body>
    <div id="app">
        <ul>
            <!-- index是选的第二个参数,即当前项的索引
                 items 是待循环的数组 , 
                 list 是被循环的每一项 -->
            <li v-for="(item,index) in list">
                索引是:{{ index }}
                姓名是:{{ item.name }}
            </li>
        </ul>
        
    </div>
    <script src="./js/vue.js"></script>
    <script>
        const vm = new Vue({
            el : '#app',
            data:{
                list : [
                    { id: 1, name: '张三' },
                    { id: 2, name: '李四' },
                    { id: 3, name: '王五' },
                    { id: 4, name: '张三' },
            ]
            },
        })
    </script>
</body>
</html>
注意:v-for 指令中的 item 项 index 索引 都是形参,可以根据需要进行 重命名 。例如 ( user , i ) in userlist

使用 key 维护列表的状态
列表的数据变化 时,默认情况下,vue 会 尽可能的复用 已存在的 DOM 元素,从而 提升渲染的性能 。但这种 默认的性能优化策略,会导致 有状态的列表无法被正确更新
为了给 vue 一个提示,以便它能跟踪每个节点的身份, 从而在 保证 有状态的列表被正确更新 的前提下, 提升渲 染的性能 。此时,需要为每项提供一个 唯一的 key 属性
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>v-for中的key</title>
</head>

<body>
  <!-- 在页面中声明一个将要被 vue 所控制的 DOM 区域 -->
  <div id="app">

    <!-- 添加用户的区域 -->
    <div>
      <input type="text" v-model="name">
      <button @click="addNewUser">添加</button>
    </div>

    <!-- 用户列表区域 -->
    <ul>
      <!-- :key 是来作用;于表单 来及时更新数据 -->
      <li v-for="(user, index) in userlist" :key="user.id">
        <input type="checkbox" />
        姓名:{{user.name}}
      </li>
    </ul>
  </div>

  <script src="./lib/vue-2.6.12.js"></script>
  <script>
    const vm = new Vue({
      el: '#app',
      data: {
        // 用户列表
        userlist: [
          { id: 1, name: 'zs' },
          { id: 2, name: 'ls' }
        ],
        // 输入的用户名
        name: '',
        // 下一个可用的 id 值
        nextId: 3
      },
      methods: {
        // 点击了添加按钮
        addNewUser() { 
          this.userlist.unshift({ id: this.nextId, name: this.name })   //push为最后添加   unshift前面添加
          this.name = ''
          this.nextId++
        }
      },
    })
  </script>
</body>

</html>

key 的注意事项

key 的值只能是字符串数字类型

key 的值必须具有唯一性(即:key 的值不能重复)

建议把数据项 id 属性的值作为 key 的值(因为 id 属性的值具有唯一性)

使用 index 的值当作 key 的值没有任何意义(因为 index 的值不具有唯一性)

建议使用 v-for 指令时一定要指定 key 的值(既提升性能、又防止列表状态紊乱)

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐