vue 指令

发布于:2025-05-16 ⋅ 阅读:(17) ⋅ 点赞:(0)

个人简介

👨‍💻‍个人主页: 魔术师
📖学习方向: 主攻前端方向,正逐渐往全栈发展
🚴个人状态: 研发工程师,现效力于政务服务网事业
🇨🇳人生格言: “心有多大,舞台就有多大。”
📚推荐学习: 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js实战 🍒Three.js 🍇鸿蒙开发
🪧使用备注:仅供学习交流 严禁用于商业用途 ,若发现侵权内容请及时联系作者
📤更新进度:持续更新内容
🤙个人名片:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧

vue 指令目录



4.1 指令的概念

  • 概念:指令(Directives)是 vue 为开发者提供的一套特殊语法。
  • 为啥要学:提高程序员渲染 DOM 的效率。
  • vue 中的指令按照不同的用途可以分为如下 6 大类
    1. 内容渲染指令
    2. 属性绑定指令
    3. 事件绑定指令
    4. 双向绑定指令
    5. 条件渲染指令
    6. 列表渲染指令
  • 注意:指令是 vue 开发中最基础、最常用、最简单的知识点。

4.2 六大类指令

1. 内容渲染指令
  • 内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。
  • 常用的内容渲染指令有如下 3 个:
    1. v-text 填充纯文本
    • 不解析标签
    • 相比插值表达式更加简洁
    1. 插值表达式
    • 表达式:{{}}
    • 优点:大家都遵循同样的规则写代码,代码可读性明显提高了,方便后期的维护。
    • 缺点:没有专门提供事件机制。
    1. v-html 填充HTML片段
    • v-text 指令和插值表达式只能渲染纯文本内容。如果要把包含 HTML 标签的字符串渲染为页面的 HTML 元素,则需要用到 v-html 这个指令
    1. v-pre 填充原始信息
    <!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>Document</title>
    </head>
    
    <body>
      <div id="app">
        <p>------------ v-text ---------------</p>
        <!-- 注意:v-text 很少用,因为它会覆盖元素内默认的内容 -->
        <p v-text="username">名字是:</p>
        <p v-text="gender">性别:</p>
    
        <p>------------ { { } } ---------------</p>
        <!-- 插值表达式 -->
        <!-- 表达式的概念:可以求值的式子,叫做表达式 -->
        <p>名字是:{{ username }}</p>
        <p>性别是:{{ gender }}</p>
        <p>{{ username + '~~~' }}</p>
        <p>{{ username + gender }}</p>
        <p>{{ 123 }}</p>
        <p>{{ true }}</p>
        <p>{{ 1>3 ? '成立' : '不成立' }}</p>
        <p>{{ username.length }}</p>
        <!-- 语句不能写到插值表达式中,里面只能写“表达式” -->
        <!-- <p>{{ let a = 10 }}</p> -->
        <p>{{ username.split('').reverse().join('') }}</p>
    
        <p>--------------- v-html ---------------</p>
        <div v-text="info"></div>
        <div>{{info}}</div>
        <div v-html="info"></div>
      </div>
    
      <script src="./lib/vue-2.6.12.js"></script>
      <script>
        const vm = new Vue({
          el: '#app',
          // 声明数据
          data: {
            username: '汤哥1234',
            gender: '男',
            info: '<h3 style="color:red;">这是一个h3标签</h3>'
          }
        })
      </script>
    </body>
    
    </html>
    
2. 属性绑定指令
  • 语法:v-bind:属性名=“表达式”
  • 简写::属性名=“表达式”
  • 作用:标签的属性与vue表达式动态绑定
  • 注意:在实际开发中,v-bind: 指令特别常用,因此,vue 提供了简化的写法 :
    <!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>Document</title>
    </head>
    
    <body>
      <div id="app">
        <!-- v-bind: 是属性绑定指令,专门为元素属性动态绑定属性值 -->
        <!-- v-bind:属性名="表达式" -->
        <!-- 注意:在实际开发中,v-bind: 指令特别常用,因此,vue 提供了简化的写法 : -->
        <input type="text" :placeholder="info">
        <img :src="url" alt="">
        <h3 :title="txt + '~~~~'">xxxxxxxxxxx</h3>
        <input :type="password" placeholder="v-bind: 是属性绑定指令">
      </div>
    
      <script src="./lib/vue-2.6.12.js"></script>
      <script>
        const vm = new Vue({
          el: '#app',
          data: {
            info: 'abcdefg',
            // 图片的 url 地址
            url: 'https://img0.baidu.com/it/u=3280618160,1318135601&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
            txt: '这是h3的标题',
            password: 'password'
          }
        })
      </script>
    </body>
    
    </html>
    
3. 事件绑定指令
  • 语法:

    1. v-on:事件名="methods中的函数(实参)"
    2. v-on:事件名="methods中的函数"
  • 简写: @事件名="methods中的函数"

  • 作用:给DOM元素绑定事件

  • 事件对象

    1. 无参数,直接用形参接收
    2. 有参数,手动传入 $event 对象
  • $event:$event 是 vue 提供的特殊变量,用来表示原生的事件参数对象 event。$event 可以解决事件参数对象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>Document</title>
    </head>
    
    <body>
      <div id="app">
        <h3>count是:{{ count }}</h3>
        <!-- 当绑定事件的时候,用小括号传参了 -->
        <!-- 则传递的参数,会把默认的事件对象 event 给覆盖掉 -->
        <!-- $event 是 vue 内置的特殊变量,它就是事件对象 event -->
        <button @click="add(2, $event)">+N</button>
      </div>
    
      <script src="./lib/vue-2.6.12.js"></script>
      <script>
        const vm = new Vue({
          el: '#app',
          data: {
            count: 0
          },
          methods: {
            // 绑定事件,必然会有事件对象 event
            add (n, e) {
              console.log(n, e.target);
              // e.target 是事件的触发源
              // 记住:e.target 是原生的 DOM 对象
              e.target.style.backgroundColor = 'red'
    
              this.count += n
    
              // 在 add 函数中,调用 show 函数
              this.show()
            },
            show () {
              console.log('触发了 methods 中的 show 函数')
            }
          },
        })
      </script>
    </body>
    
    </html>
    
  • 事件修饰符

    • 语法:@事件名.修饰符名
    • 常用的 5 个事件修饰符如下:
      image.png
    <!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>Document</title>
      <style>
        .outer {
          padding: 100px 50px;
          background-color: orange;
        }
    
        .inner {
          padding: 50px;
          background-color: cyan;
        }
      </style>
    </head>
    
    <body>
      <div id="app">
        <!-- @事件名.prevent="处理函数" -->
        <a href="https://juejin.cn/editor/drafts/7075957234605244447" @click.prevent="show">去掘金网站</a>
    
        <div class="outer" @click="handler2">
          <!-- @事件名.stop="处理函数" -->
          <div class="inner" @click.stop="handler1">内部的 div</div>
        </div>
      </div>
    
      <script src="./lib/vue-2.6.12.js"></script>
      <script>
        const vm = new Vue({
          el: '#app',
          methods: {
            show () {
              console.log('点击了 a 链接')
            },
            handler1 () {
              console.log('点击了内部的盒子')
            },
            handler2 () {
              console.log('点击了外部的盒子')
            }
          },
        })
      </script>
    </body>
    
    </html>
    
  • 按键修饰符

    • 在监听键盘事件时,我们经常需要判断详细的按键。此时,可以为键盘相关的事件添加按键修饰符
    • 回车键触发 @keyup.enter
    • 取消键触发 @keyup.esc
<!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>Document</title>
</head>

<body>
  <div id="app">
    <!-- .enter 能保证,只有摁下的是 enter 键的时候,才触发后面的函数 -->
    <!-- 摁下 esc 清空文本框 -->
    <!-- 1. 绑定 keyup 事件,并监听 esc 按键 -->
    <!-- 2. 声明事件处理函数 -->
    <!-- 3. 通过 e.target.value = '' 来清空文本框的值 -->
    <input type="text" @keyup.enter="submit" @keyup.esc="clear">
  </div>

  <script src="./lib/vue-2.6.12.js"></script>
  <script>
    const vm = new Vue({
      el: '#app',
      methods: {
        submit (e) {
          console.log('触发了 submit 函数')
          console.log(e.target.value)
        },
        clear (e) {
          console.log('触发了 esc 函数')
          e.target.value = ''
        }
      },
    })
  </script>
</body>

</html>
4. 双向绑定指令
  • vue 提供了 v-model 双向数据绑定指令,用来辅助开发者在不操作 DOM 的前提下,快速获取表单的数据

  • 语法: v-model="vue数据变量"

  • 作用:把标签的 value 属性 与 vue变量 双向绑定

  • v-model 指令的修饰符

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

    image.png

    <!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>Document</title>
    </head>
    
    <body>
      <div id="app">
        <h3>count是:{{count}}</h3>
        <button @click="count += 1">+1</button>
    
        <hr>
    
        <!-- 分析思路: -->
        <!-- 1. 为 input 绑定 input 事件 -->
        <!-- 2. 在处理函数中,通过 e.target.value 获取到变化过后的新值 -->
        <!-- 3. 把新值,调用 parseInt 转换为 数值 -->
        <!-- 4. 把转换得到的数值,赋值给 this.count -->
        <!-- 注意: change 在文本框失去焦点时候触发;input 在每次值变化的时候触发 -->
        <input type="text" :value="count" @input="getValue">
    
        <hr>
    
        <!-- v-model 是双向数据绑定指令,它有两个作用: -->
        <!-- 1. data 数据的变化,会被自动渲染到当前的元素中 -->
        <!-- 2. 当前元素值的变化,会被自动更新到 data 中 -->
        <input type="text" v-model.number="count">
    
        <hr>
        <!-- v-model 指令,可以让当前元素的值,和 data 中的数据,进行双向数据绑定 -->
        <!-- .lazy 表示,文本框触发 change 事件的时候,才会把数据更新到 data -->
        <input type="text" v-model.lazy.trim="msg">
    
        <hr>
        <!-- 切记:v-model 指令,只能结合表单元素一起使用;不能结合普通标签一起使用 -->
        <!-- input  type=text/password/email/radio/checkbox -->
        <!-- select -->
        <!-- textarea -->
        <!-- <div v-model="msg"></div> -->
      </div>
    
      <script src="./lib/vue-2.6.12.js"></script>
      <script>
        // 3. vm 实例就是 ViewModel
        const vm = new Vue({
          // 2. el 所指定的区域,就是 View 视图
          el: '#app',
          // 1. Model 数据源
          data: {
            count: 0,
            msg: 'abc'
          },
          methods: {
            getValue(e) {
              // console.log(typeof e.target.value)
              this.count = parseInt(e.target.value)
            }
          },
        })
      </script>
    </body>
    
    </html>
    
5. 条件渲染指令
  • 条件渲染指令用来辅助开发者按需控制 DOM 的显示与隐藏。条件渲染指令有如下两个,分别是:

    • v-if
    • v-show
  • 语法:

    • v-show="vue变量"
    • v-if="vue变量"
  • 原理:

    • v-show 用的display:none隐藏 (频繁切换使用)
    • v-if(不频繁): 动态创建和移除元素插入或移除节点
  • v-if 和 v-show 的区别

    1. 实现原理不同:
    • v-if 指令会动态地创建或移除 DOM 元素,从而控制元素在页面上的显示与隐藏;
    • v-show 指令会动态为元素添加或移除 style=“display: none;” 样式,从而控制元素的显示与隐藏;
    1. 性能消耗不同:
    • v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。
    • 如果需要非常频繁地切换,则使用 v-show 较好
    • 如果在运行时条件很少改变,则使用 v-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>Document</title>
    </head>
    
    <body>
      <div id="app">
        <button @click="flag = !flag">Toggle</button>
        <p v-if="!flag">这是被 v-if 控制的元素</p>
        <p v-show="flag">这是被 v-show 控制的元素</p>
      </div>
    
      <script src="./lib/vue-2.6.12.js"></script>
      <script>
        const vm = new Vue({
          el: '#app',
          data: {
            // 如果 falg 为 true,则展示被控制的元素
            // 如果 falg 为 false,则隐藏被控制的元素
            flag: false
          }
        })
      </script>
    </body>
    
    </html>
    
    
  • v-else

    • v-if 可以单独使用,或配合 v-else 指令一起使用:
    • 注意:v-else 指令必须配合 v-if 指令一起使用,否则它将不会被识别!
  • v-else-if

    • v-else-if 指令,顾名思义,充当 v-if 的“else-if 块”,可以连续使用:
    • 注意:v-else-if 指令必须配合 v-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>Document</title>
    </head>
    
    <body>
      <div id="app">
        <!-- 条件成立,展示 v-if 控制的元素 -->
        <!-- 条件不成立,展示 v-else 控制的元素 -->
        <p v-if="flag">条件成立</p>
        <p v-else>条件不成立</p>
    
        <hr>
        <h3 v-if="age>=18">成年人,可以抽烟喝酒烫头</h3>
        <h1 v-else>未成年,漫画 + 娃哈哈</h1>
    
        <hr>
    
        <p v-if="score === 'A'">优秀</p>
        <p v-else-if="score === 'B'">良好</p>
        <p v-else-if="score === 'C'">一般</p>
        <p v-else></p>
    
    
      </div>
    
      <script src="./lib/vue-2.6.12.js"></script>
      <script>
        const vm = new Vue({
          el: '#app',
          data: {
            flag: true,
            age: 18,
            // A -> 优秀
            // B -> 良好
            // C -> 一般
            // D -> 差
            score: 'A'
          }
        })
    
      </script>
    </body>
    
    </html>
    
6. 列表渲染指令
  • vue 提供了 v-for 列表渲染指令,用来辅助开发者基于一个数组来循环渲染一个列表结构。v-for 指令需要使

  • 用 item in list 形式的特殊语法,其中:

    • list 是待循环的数组
    • item 是被循环的每一项
  • v-for 中的索引

  • v-for 指令还支持一个可选的第二个参数,即当前项的索引。

    • 语法格式为 (item, index) in list
    • 注意:v-for 指令中的 item 项和 index 索引都是形参,可以根据需要进行重命名。例如 (user, i) in userlist
    <!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>Document</title>
      <style>
        table {
          width: 600px;
          border-collapse: collapse;
        }
    
        td,
        th {
          border: 1px solid #efefef;
          line-height: 35px;
          font-size: 12px;
          text-align: center;
        }
      </style>
    </head>
    
    <body>
      <div id="app">
        <table>
          <thead>
            <tr>
              <th>id</th>
              <th>name</th>
              <th>age</th>
              <th>index</th>
            </tr>
          </thead>
          <tbody>
            <!-- 如果需要基于数组中的数据, -->
            <!-- 循环在页面上,渲染出 UI 结构相似的元素 -->
            <!-- 此时,要能够想起来使用 v-for 指令 -->
            <!-- 语法: -->
            <!-- v-for="数组中的每一项 in 数组" -->
            <!-- v-for="item in 数组" -->
            <!-- 技巧:要循环生成哪个 DOM 元素,就在它身上添加 v-for 指令 -->
    
            <!-- v-for 最完整的语法格式: -->
            <!-- v-for="(item, index) in 数组" -->
    
            <!-- 注意:只要用到了 v-for 指令,推荐大家都要加上 key 属性的绑定 -->
            <!-- 建议把 id 当作 key 的值 -->
            <!-- key 的值必须是“数字”或“字符串”,key 的值不能是对象或其他类型 -->
            <tr v-for="(item, index) in list" :key="item.id">
              <td>{{ item.id }}</td>
              <td>{{ item.name }}</td>
              <td>{{ item.age }}</td>
              <td>索引是:{{ index }}</td>
            </tr>
          </tbody>
        </table>
      </div>
     
      <script src="./lib/vue-2.6.12.js"></script>
      <script>
        const vm = new Vue({
          el: '#app',
          data: {
            // 用户的数组
            list: [
              { id: 1, name: '老汤', age: 35 },
              { id: 2, name: '狗哥', age: 34 },
              { id: 3, name: '小彬彬', age: 18 },
              { id: 4, name: '杨耀', age: 20 }
            ]
          }
        })
      </script>
    </body>
    
    </html>
    
  • 使用 key 维护列表的状态

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

    1. key 的值只能是字符串或数字类型
    2. key 的值必须具有唯一性(即:key 的值不能重复)
    3. 建议把数据项 id 属性的值作为 key 的值(因为 id 属性的值具有唯一性)
    4. 使用 index 的值当作 key 的值没有任何意义(因为 index 的值不具有唯一性)
    5. 建议使用 v-for 指令时一定要指定 key 的值(既提升性能、又防止列表状态紊乱)
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    
    <style>
      li {
        list-style: none;
      }
    </style>
    
    <body>
      <!-- 在页面中声明一个将要被 vue 所控制的 DOM 区域 -->
      <div id="app">
    
        <!-- 添加用户的区域 -->
        <div>
          <input type="text" v-model="name">
          <button @click="addNewUser">添加</button>
        </div>
    
        <!-- 用户列表区域 -->
        <ul>
          <!-- 建议:今后只要用到了 v-for,尽量都绑定一个 key 值 -->
          <!-- key 值的类型:数字或字符串 -->
          <!-- key 的值必须具有唯一性 -->
          <!-- 不要把 index 索引当作 key 的值,因为 index 索引不具有唯一性 -->
          <!-- 记住:那索引值当作 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: '张三疯' },
              { id: 2, name: '桑三炮' },
              { id: 3, name: '倪大野' }
            ],
            // 输入的用户名
            name: '',
            // 下一个可用的 id 值
            nextId: 4
          },
          methods: {
            // 点击了添加按钮
            addNewUser () {
              if (this.name === '') {
                this.userlist.unshift({ id: this.nextId, name: '禽兽' })
                this.name = ''
                this.nextId++
              } else {
                this.userlist.unshift({ id: this.nextId, name: this.name })
                this.name = ''
                this.nextId++
              }
    
            }
          },
        })
      </script>
    </body>
    
    </html>
    

4.3 自定义指令

image.png

1. 什么是自定义指令
  • vue 官方提供了 v-text、v-for、v-model、v-if 等常用的指令。
  • 除此之外 vue 还允许开发者自定义指令。
2. 自定义指令的分类
  • vue 中的自定义指令分为两类,分别是:
    • 私有自定义指令
    • 全局自定义指令
3. 私有自定义指令
  • 在每个 vue 组件中,可以在 directives 节点下声明私有自定义指令。示例代码如下:

image.png

directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
} }
}
4. 使用自定义指令
  • 在使用自定义指令时,需要加上 v- 前缀。示例代码如下:

image.png

5. 为自定义指令动态绑定参数值
  • 在 template 结构中使用自定义指令时,可以通过等号(=)的方式,为当前指令动态绑定参数值

image.png

6. 通过 binding 获取指令的参数值
  • 在声明自定义指令时,可以通过形参中的第二个参数,来接收指令的参数值:

image.png

7. update 函数
  • bind 函数只调用 1 次:当指令第一次绑定到元素时调用,当 DOM 更新时 bind 函数不会被触发。
  • update 函数会在每次 DOM 更新时被调用。示例代码如下:

image.png

8. 函数简写
  • 如果 bind 和update 函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式:

image.png

9. 全局自定义指令
  • 全局共享的自定义指令需要通过“Vue.directive()”进行声明,示例代码如下:

image.png


网站公告

今日签到

点亮在社区的每一天
去签到