Chapter 03 Vue指令(下)

欢迎大家订阅【Vue2+Vue3】入门到实践专栏,开启你的 Vue 学习之旅!

文章目录


前言

在 Vue.js 中,指令是带有 v- 前缀的特殊属性,不同属性对应不同的功能。通过学习不同的指令,我们能够灵活应对多种业务场景的需求。本章详细讲解了一些基本的 Vue 指令,包括 v-on、v-for、v-bind 以及 v-model 指令。

一、v-on指令

①作用:给元素绑定事件监听器

②语法:

  • v-on:事件名 = "内联语句"
  • v-on:事件名 = "methods中的函数名"
特性 内联语句 methods中的函数名
定义方式 直接在模板中编写表达式或语句 methods中定义函数
适用场景 简单操作 复杂逻辑或多个操作
可读性 可读性较差,逻辑复杂时难以理解 可读性好,更易于维护
维护性 难以维护,逻辑修改需在模板中直接更改 易于维护,逻辑集中处理
复用性 不能复用,通常只适用于当前事件 可复用,一个方法可被多次调用

③简写:v-on:事件名 = @事件名

④v-on调用传参:

通常情况下,可以直接将方法名绑定到事件上,但在某些情况下需要在调用方法时传入参数。

语法: v-on:事件名 = "methodName(parameter)"

⑤修饰符:

修饰符 描述
.stop 调用 event.stopPropagation()
.prevent 调用 event.preventDefault()
.capture 在捕获模式添加事件监听器。
.self 只有事件从元素本身发出才触发处理函数。
. {keyAlias} 只在某些按键下触发处理函数。
.once 最多触发一次处理函数。
.left 只在鼠标左键事件触发处理函数。
.right 只在鼠标右键事件触发处理函数。
.middle 只在鼠标中键事件触发处理函数。
.passive 通过 { passive: true } 附加一个 DOM 事件。

⑥常用的监听事件:

事件 描述
click 点击事件
dblclick 双击事件
mouseenter 鼠标进入元素时触发
mouseleave 鼠标离开元素时触发
keydown 按键按下事件
keyup 按键松开事件
input 输入框内容变化时触发
change 表单元素内容变化后触发
submit 提交表单时触发
focus 输入框获得焦点时触发
blur 输入框失去焦点时触发
scroll 元素滚动时触发
resize 窗口或元素大小改变时触发
transitionend CSS 过渡结束时触发
animationend CSS 动画结束时触发
contextmenu 右键点击事件

【示例一】

语法1:v-on:事件名 = "内联语句"

内联语句(Inline Statement)是指在某个上下文环境中直接书写的、可以立即执行的代码表达式。这种写法通常不需要额外的命名或定义,而是在特定条件下直接被调用。在Vue.js等框架中,可以快速实现事件处理逻辑,适合于简单的场景和快速开发。

html 复制代码
<body>
  <div id="app">
    <!-- 减号按钮,点击时通过v-on:click指令绑定点击事件,触发count--,count的值减1 -->
    <button v-on:click="count--">-</button>
    <span>{{count}}</span>
    <!-- 加号按钮,点击时通过v-on:click指令绑定点击事件,触发count++,count的值加1 -->
    <button v-on:click="count++">+</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        /* count初始值为100 */
        count:100
      }
    })
  </script>
</body>

运行结果:



v-on:事件名可以简写成@事件名

html 复制代码
<div id="app">
    <button @click="count--">-</button>
    <span>{{count}}</span>
    <button @click="count++">+</button>
  </div>

【示例二】

语法2:v-on:事件名 = "methods中的函数名"

html 复制代码
<body>
  <div id="app">
    <button @click="fn">切换显示隐藏</button>
    <h1 v-show="isShow">Hello World</h1>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        isShow:true
      },
      methods:{/* 定义了Vue实例的方法fn,功能是切换isShow的值(如果为true则变为false,反之亦然) */
        fn(){
          /* this关键字指向当前的Vue实例app,用于访问组件的属性、数据和方法 */
          this.isShow=!this.isShow
        }
      }
    })
  </script>
</body>

运行结果:

【示例三】

v-on参数调用: v-on:事件名 = "methodName(parameter)"

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>v-on调用参数</title>
  <style>
    .box {
      border: 3px solid #000000;
      border-radius: 10px;
      padding: 20px;
      margin: 20px;
      width: 150px;
    }
    h3 {
      margin: 10px 0 20px 0;
    }
    p {
      margin: 20px;
    }
  </style>
</head>
<body>
  <div id="app">
    <div class="box">
      <h3>饮料自动售货机</h3>
      <!-- 调用buy方法并传入相应的价格参数 -->
      <button @click="buy(5)">可乐5元</button>
      <button @click="buy(10)">咖啡10元</button>
    </div>
    <p>用户余额:{{money}}</p>
  </div>

  <script src="./vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        /* 初始金额为100 */
        money:100
      },
      methods:{
        buy(price){
          /* this关键字确保我们访问的是Vue实例中的money属性,而不是全局的变量 */
          this.money-=price
        }
      }
    })
  </script>
</body>
</html>

运行结果:

点击"可乐5元"按钮,余额减5,剩余95元:

再点击"咖啡10元"按钮,余额减10,剩余85元:

二、v-for指令

①作用:基于原始数据多次渲染元素或模板块。

②遍历数组的语法:v-for = "(item, index) in 数组"

  • 参数item:表示当前遍历到的元素,它会依次被赋值为数组中的每个元素
  • 参数index:表示当前元素在数组中的索引(位置),从 0 开始递增

【示例】

html 复制代码
<body>

  <div id="app">
    <h3>水果店</h3>
    <ul>
      <!-- v-for 指令用于循环遍历 list 的数据属性 -->
      <li v-for="(item,index) in list">{{item}}</li>
    </ul>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        list: ['西瓜', '苹果', '鸭梨']
      }
    })
  </script>
</body>

运行结果:

③key属性:

在使用v-for渲染列表时,Vue会根据每个项目的key值来追踪节点的身份。这个机制使得Vue在更新虚拟DOM时能够准确地从旧的节点中找到对应的节点,从而进行最小化的更新,进一步提高性能,并确保组件的状态在更新过程中得到保持。

  • key 的值只能是字符串数字类型
  • key 的值必须具有唯一性
  • 推荐使用 id 作为 key(唯一),不推荐使用 index 作为 key(会变化,不对应)
html 复制代码
<body>

  <div id="app">
    <h3>我的书架</h3>
    <ul>
      <!-- 通过将 item.id 作为 key,Vue 可以识别每本书的唯一性 -->
      <li v-for="(item,index) in booksList" :key="item.id">
        <span>{{item.name}}</span>
        <span>{{item.author}}</span>
        <button @click="del(item.id)">删除</button>
      </li>
    </ul>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        booksList: [
          { id: 1, name: '《红楼梦》', author: '曹雪芹' },
          { id: 2, name: '《西游记》', author: '吴承恩' },
          { id: 3, name: '《水浒传》', author: '施耐庵' },
          { id: 4, name: '《三国演义》', author: '罗贯中' }
        ]
      },
      methods: {
        /* del(id):根据传入的 id 删除对应的书籍

           filter:一个数组方法,用于创建一个新数组,该数组包含所有通过指定测试的元素。
           该方法不会改变原始数组,而是返回一个新的数组。
           
           item => item.id !== id:一个 箭头函数 (arrow function),被用作 filter 方法中的回调函数;
           其中item.id !== id是一个条件表达式,它检查当前书籍的 id 是否不等于传入的 id;
           如果两者不相等,则返回 true,条件满足,当前的 item 被保留在新数组中;
           如果两者相等,则返回 false,条件不满足,这样当前的 item 不会出现在新数组中。
           */
        del(id){
          this.booksList = this.booksList.filter(item => item.id !== id);  
        }
      },
    })
  </script>
</body>

运行结果:

删除《红楼梦》后:

三、v-bind指令

①作用:动态地设置html的标签属性,允许根据 Vue 实例中的数据动态地更新和渲染元素的属性。

②语法: v-bind:属性名="表达式"

③简写::属性名="表达式

【示例】

html 复制代码
<body>
  <div id="app">
    <!-- 使用 v-bind 指令将 imgUrl 变量的值绑定到 <img> 元素的 src 属性上,使其动态显示 
         当 imgUrl 的值改变时,图片的源地址也会自动更新-->
    <img v-bind:src="imgUrl" alt="">
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        imgUrl:'./imgs/Vue图片.png'
      }
    })

  </script>
</body>

运行结果:

v-bind:属性名="表达式"可以简写为:属性名="表达式

html 复制代码
<img :src="imgUrl" alt="">

【案例】

根据所学内容实现图片切换。

核心思路分析:

① 数组存储图片路径 → [ 图片1, 图片2, 图片3, ... ]

② 准备下标 index,数组[下标] → v-bind 设置 src 展示图片 → 修改下标切换图片

html 复制代码
<body>
  <div id="app">
    <!-- 
    v-show="index>0": 控制按钮的显示或隐藏。当index>0时(表示不是在第一张图片),按钮会显示;否则,按钮会隐藏
    @click="index--": 当用户点击此按钮时,index 的值会-1,切换到前一张图片
    -->
    <button v-show="index>0" @click="index--">上一页</button>
    <div>
      <!-- list[index] 获取当前显示的图片路径 -->
      <img v-bind:src="list[index]" alt="">
    </div>
    <!-- 
    v-show="index<list.length-1": 控制按钮的显示或隐藏。当index<list.length-1时(表示不是在最后一张图片),按钮会显示;否则,按钮会隐藏
    @click="index++": 当用户点击此按钮时,index 的值会+ 1,切换到下一张图片。 
    -->
    <button v-show="index<list.length-1" @click="index++">下一页</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        index:0,
        list: [
          './imgs/photo01.jpg',
          './imgs/photo02.jpg',
          './imgs/photo03.jpg',
          './imgs/photo04.jpg',
          './imgs/photo05.jpg',
          './imgs/photo06.jpg',
          './imgs/photo07.jpg',
          './imgs/photo08.jpg'
        ]
      }
    })
  </script>
</body>

运行结果:

第一张图片:

点击下一页后切换到第二张图片:

最后一张图片:

相关推荐
前端小小王25 分钟前
React Hooks
前端·javascript·react.js
迷途小码农零零发35 分钟前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀1 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
旭东怪1 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
ekskef_sef3 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端
sunshine6413 小时前
【CSS】实现tag选中对钩样式
前端·css·css3
真滴book理喻4 小时前
Vue(四)
前端·javascript·vue.js
蜜獾云4 小时前
npm淘宝镜像
前端·npm·node.js
dz88i84 小时前
修改npm镜像源
前端·npm·node.js
Jiaberrr4 小时前
解锁 GitBook 的奥秘:从入门到精通之旅
前端·gitbook