Vue3学习之旅–爱上Vue3–Vue3基础语法(一)

续上文:

vue3学习之旅–邂逅vue3-了解认识Vue3

vue3学习之旅–邂逅vue3-了解认识Vue3(二)

methods方法绑定this

问题回顾:

问题一:为什么不能使用箭头函数(官方文档有给出解释)?

问题二:不使用箭头函数的情况下,this到底指向的是什么?(可以作为一道面试题)

image-20210714211627563

不能使用箭头函数的原因?

我们在methods中要使用data返回对象中的数据:

那么这个this是必须有值的,并且应该可以通过this获取到data返回对象中的数据。

那么我们这个this能不能是window呢?

不可以是window,因为window中我们无法获取到data返回对象中的数据;但是如果我们使用箭头函数,那么这个this就会是window了;

为什么是window呢?

这里涉及到箭头函数使用this的查找规则,它会在自己的上层作用于中来查找this;

最终刚好找到的是script作用于中的this,所以就是window;

this到底是如何查找和绑定的呢?

且听下回分解。

this到底指向什么?

事实上Vue的源码当中就是对methods中的所有函数进行了遍历,并且通过bind绑定了this:

image-20210714215745360

image-20210714215847860

image-20210714215927151

当然学过vue2的小伙伴可能觉得有点熟系。看不懂也没关系,以后慢慢我们可以看懂的。此处可以略过。

<!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"></div>
  <script src="../vue3/vue3.js"></script>

  <!-- template 模板写法二  -->
  <!-- 直接在 template标签内书写模板 -->
  <template id="mao">
    <div>
      <h2>{{message}}</h2>
      <h2>{{counter}}</h2>
      <button @click='increment'>+</button>
      <button @click='decrement'>-</button>
      <!-- 验证箭头函数的指向 -->
      <!-- 发现打印出来的对象,的确是window对象 -->
      <button @click='increment'>验证箭头函数的指向</button>
    </div>
  </template>

  <script>
    Vue.createApp({
      template: '#mao',
      // 数据
      data() {
        return {
          message: 'hello Vue3!',
          counter: 0
        }
      },
      // 方法  
      // 问题:为什么我们定义在methods里面的方法,不能使用箭头函数?
      // 使用箭头函数,我们发现这个简单的计数器并不会动
      methods: {
        // 使用箭头函数的问题:

        increment: () => {
          // this === window ? 很明显是不能这样做的
          // window对象里面哪里来的counter属性,就算有,和我的vue实例又有什么关系呢?
          // 写出箭头函数的时候,这个this就指向了window
          console.log(this); // 打印的对象的确是window
          console.log(this === window); // true
          // 那么问题来了:为什么使用箭头函数,this就指向window了
          // 很明显:不难想象,肯定和vue的this绑定规则有关
          // 我们知道:箭头函数是不会绑定this的,箭头函数在哪个作用域中,this就指向那个作用域的对象
          // 那么你可能觉得,我箭头函数当前不就在 methods的作用域里面吗?
          // 其实不然:methods只是在定义对象  methods是什么,是对象啊
          // 什么是作用域: () 肯定是在括号里面啦
          // 所以箭头函数最终找到的this就到了最顶层的window
          this.counter++;
        },
        decrement: () => {
          this.counter--;
          console.log(this);
        }
      }
    }).mount('#app');

    window.name = 'win'
    const fn = function () {
      console.log(this.name);
    }
    fn() // 'win' 实际上执行的是 window.fn()  隐式绑定

    const obj = { name: '毛', fn: fn }
    obj.fn() // '毛'
  </script>
</body>

</html>

补充:vscode代码片段

我们在前面练习Vue的过程中,有些代码片段是需要经常写的,我们再VSCode中我们可以生成一个代码片段,方 便我们快速生成。

VSCode中的代码片段有固定的格式,所以我们一般会借助于一个在线工具来完成。

具体的步骤如下:

  1. 复制自己需要生成代码片段的代码
  2. https://snippet-generator.app/在该网站中生成代码片段;
  3. 在VSCode中配置代码片段
需要生成的代码片段
  <div id="app"></div>
  <template id="my-app">
  </template>
  <script src="../vue3/vue3.js"></script>
  <script>
    const app = Vue.createApp({
      template:'#my-app',
      data(){
        return {
          message:'hello Vue3!'
        }
      }
    }).mount('#app')
  </script>
vscode–> 设置 --> 用户代码片段

image-20210714221840644

选择我们需要生成的文件类型

image-20210714222153482

将需要生成的代码片段拷贝到上面的那个网站

image-20210714222233650

在html.json 中进行配置

image-20210714222323614

保存,就ok

接下来直接使用prefix的属性值,敲出来 前缀然后回车,自动生成模板骨架。

模板语法

React的开发模式:

  1. React使用的jsx,所以对应的代码都是编写的类似于js的一种语法;
  2. 之后通过Babel将jsx编译成 React.createElement 函数调用

Vue也支持jsx的开发模式(后续有时间也会讲到)

  1. 但是大多数情况下,使用基于HTML的模板语法;
  2. 在模板中,允许开发者以声明式的方式将DOM和底层组件实例的数据绑定在一起;
  3. 在底层的实现中,Vue将模板编译成虚拟DOM渲染函数,这个我会在后续给大家讲到;

所以,对于学习Vue来说,学习模板语法是非常重要的。

Mustache双大括号语法

如果我们希望把数据显示到模板(template)中,使用最多的语法是 “Mustache”语法 (双大括号) 的文本插值。

  1. 并且我们前端提到过,data返回的对象是有添加到Vue的响应式系统中;
  2. 当data中的数据发生改变时,对应的内容也会发生更新。
  3. 当然,Mustache中不仅仅可以是data中的属性,也可以是一个JavaScript的表达式。
<div id="app"></div>
  <template id="my-app">
    <!-- 插值表达式的基本使用 -->
    <!-- 直接获取一个实例数据 -->
    <h2>{{message}}</h2>
    <!-- 也可以使用表达式 -->
    <h2>{{age * 10}}</h2>
    <h2>{{age / 10}}</h2>
    <!-- 也可以使用数据的方法 比如字符串的切割-->
    <!-- 字符串的切割 然后反转 -->
    <h2>{{message.split('').reverse().join('')}}</h2>
    <!-- 调用函数 -->
    <h2>{{getReverseMessage()}}</h2>
    <!-- 还可以使用计算属性,暂时不讲 -->

    <!-- 使用三元运算符 -->
    <h2>{{isShow? '哈哈' : '呵呵'}}</h2>
    <!-- 同一个标签也可以使用多个插值表达式 -->
    <h2>{{name}} {{message}}</h2>
  </template>
  <script src="../vue3/vue3.js"></script>
  <script>
    Vue.createApp({
      template: '#my-app',
      data() {
        return {
          message: 'hello Vue3!',
          name: '毛毛',
          age: 22,
          isShow:true
        }
      },
      methods: {
        getReverseMessage() {
          return this.message.split('').reverse().join('');
        }
      },
    }).mount('#app')
  </script>

image-20210714225551729

另外这种用法是错误的:

    <!-- 以下为错误用法 -->
    <!-- 1. 在插值表达式中定义变量,这是赋值语句,不是表达式 -->
    <h2>{{const a = '10'}}</h2>
    <!-- 使用if语句等 -->
    <h2>{{if(isShow) {return '哈哈哈'}}}</h2>

Vue指令

v-once指令

v-once用于指定元素或者组件只渲染一次:

  1. 当数据发生变化时,元素或者组件以及其所有的子元素将视为静态内容并且跳过;

  2. 该指令可以用于性能优化;

    <!-- v-once指令:该指令修饰的元素或者组件只会渲染一次-->
    <h2 v-once>{{counter}}</h2>
    <h2>{{counter}}</h2>
    <button @click='increment'>+</button><br>

如果是子节点,也是只会渲染一次:

    <!-- 如果是子节点,一样也只渲染一次 -->
    <div v-once>
      <h2>{{counter}}</h2>
      <button @click='increment'>+</button><br>
    </div>
<div id="app"></div>
  <template id="my-app">
    <!-- v-once指令:该指令修饰的元素或者组件只会渲染一次-->
    <h2 v-once>{{counter}}</h2>
    <h2>{{counter}}</h2>
    <button @click='increment'>+</button><br>
    <!-- 如果是子节点,一样也只渲染一次 -->
    <div v-once>
      <h2>{{counter}}</h2>
      <button @click='increment'>+</button><br>
    </div>
  </template>
  <script src="../vue3/vue3.js"></script>
  <script>
    Vue.createApp({
      template: '#my-app',
      data() {
        return {
          counter: 100
        }
      },
      methods: {
        increment() {
          this.counter++;
        }
      },
    }).mount('#app')
  </script>

v-text 指令

用于更新元素的 textContent:

也就是用于更新元素的文本内容。

    <template id="my-app">
      <!-- v-text指令 -->
      <h2 v-text='message'></h2>
      <!-- 等价于 -->
      <h3>{{message}}</h3>
      <!-- 但是插值表达式更加灵活 -->
    </template>

v-html指令

默认情况下,如果我们展示的内容本身是 html 的,那么vue并不会对其进行特殊的解析。

如果我们希望这个内容被Vue可以解析出来,那么可以使用 v-html 来展示;

<div id="app"></div>
  <template id="my-app">
    <div>{{message}}</div>
    <!-- v-html -->
    <div v-html='message'></div>
  </template>
  <script src="../vue3/vue3.js"></script>
  <script>
    Vue.createApp({
      template: '#my-app',
      data() {
        return {
          message: '<div style="color:red">毛毛</div>'
        }
      }
    }).mount('#app')
  </script>

image-20210714231448442

v-pre 指令

  1. v-pre用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签
  2. 跳过不需要编译的节点,加快编译的速度;
    <!-- 如果我们希望有些内容不希望被解析,可以使用这个指令 -->
    <h2 v-pre>{{message}}</h2>

v-cloak 指令

这个指令保持在元素上直到关联组件实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到组件实 例准备完毕。

  <style>
    [v-cloak]{
      display: none;
    }
  </style>

    <!-- v-cloak指令,隐藏未解析完的Mustache 标签(插值表达式),直到解析完毕 -->
    <h2 v-cloak>{{message}}</h2>

这个h2标签在vue解析完全之前,不会显示。

以下的指令都为常用的指令,是本次学习的重点!

v-bind的绑定属性

1. 基本使用

前面讲的一系列指令,主要是将值插入到模板内容中。

但是,除了内容需要动态来决定外,某些属性我们也希望动态来绑定。

比如:

  1. 动态绑定a元素的href属性;
  2. 动态绑定img元素的src属性;

绑定属性我们使用v-bind:

缩写::

预期:any (with argument) | Object (without argument)

参数:attrOrProp (optional)

修饰符:.camel - 将 kebab-case attribute 名转换为 camelCase。

用法:动态地绑定一个或多个 attribute,或一个组件 prop 到表达式。

2. 绑定基本属性

v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值(这个学到组件时再介绍);

在开发中,有哪些属性需要动态进行绑定呢?

还是有很多的,比如图片的链接src、网站的链接href、动态绑定一些类、样式等等

v-bind有一个对应的语法糖(😃,也就是简写方式。

在开发中,我们通常会使用语法糖的形式,因为这样更加简洁。

image-20210715113152269

<div id="app"></div>
    <!-- 在vue2.x template模板中只能有一个根元素 -->
    <!-- 但是在vue3中 是允许template中有多个根元素 -->
    <template id="my-app">
      <!-- 使用v-bind 动态绑定实例里面的属性 -->
      <img v-bind:src="imgUrl" alt="">
      <a v-bind:href="url2">百度</a><br>
      <!-- v-bind 提供了一个语法糖的写法,在需要绑定的标签属性前面加上 : -->
      <a :href="url">我的博客</a>
    </template>
    <script src="../vue3/vue3.js"></script>
    <script>
      Vue.createApp({
        template:'#my-app',
        data(){
          return {
            message:'hello Vue3!',
            imgUrl: 'https://gitee.com/mao0826/picture/raw/master/images/image-20210714225551729.png',
            url: 'https://blog.csdn.net/weixin_45747310/article/details/118691744',
            url2: 'https://blog.csdn.net/weixin_45747310/article/details/118683938'
          }
        }
      }).mount('#app')
    </script>
3. 绑定class属性

介绍

在开发中,有时候我们的元素class也是动态的,比如:

  1. 当数据为某个状态时,字体显示红色.
  2. 当数据另一个状态时,字体显示黑色.

绑定class的两种方式:

  1. 对象语法
  2. 数组语法
对象语法

我们可以传给 :class (v-bind:class 的简写) 一个对象,以动态地切换 class。

<style>
    .active {
      color: red;
    }

    .bgColor {
      background-color: aquamarine;
    }

    .default {
      font-size: 40px;
    }
  </style>


<div id="app"></div>
  <template id="my-app">
    <!-- v-bind指令动态绑定class属性 -->
    <!-- 对象语法: :class={'active':boolean} -->
    <!-- boolean 布尔值可以直接指定,也可以使用vue实例的属性来指定 -->
    <!-- 如果布尔值为true,则绑定这个class属性,false则不绑定 -->
    <!-- 引号可以加,也可以不加 -->
    <h2 :class="{'bgColor':true,active:isActive}">哈哈哈哈,{{message}}</h2>
    <button @click='toggle'>文字颜色切换</button>
    <!-- 默认的class和动态的class结合 -->
    <h3 class='default' :class='{active:isActive}'>你好!</h3>
    <!-- 将对象放到一个单独的属性中 -->
    <h2 :class='classNameObj'>vue3 good good </h2>
    <!-- 将返回的对象放到一个方法中,调用方法拿到返回值也可以 -->
    <!-- 计算属性当然也是可以的 -->
    <h2 :class='getClass()'>通过方法拿到的对象</h2>
  </template>
  <script src="../vue3/vue3.js"></script>
  <script>
    Vue.createApp({
      template: '#my-app',
      data() {
        return {
          message: 'hello Vue3!',
          isActive: true,
          // 一般在定义属性存放数据的时候,不会嵌套的引用其他属性的值
          // 比如  classNameObj = {active:isActive} 这种写法是不被允许的
          classNameObj: {
            active: true,
            bgColor: true
          }
        }
      },
      methods: {
        toggle() {
          this.isActive = !this.isActive;
        },
        getClass() {
          return {
            active: true,
            bgColor: true
          };
        }
      },
    }).mount('#app')
  </script>

image-20210715113532678

image-20210715113544817

数组语法

我们可以把一个数组传给 :class,以应用一个 class 列表

<style>
    .active {
      color: red;
    }

    .bgColor {
      background-color: aquamarine;
    }

    .default {
      font-size: 40px;
    }
  </style>
</head>

<body>
  <div id="app"></div>
  <template id="my-app">
    <!-- 数组语法 -->
    <!-- 数组里面的元素,都会合并在一起,绑在标签的class属性上,权重一样的时候,后面覆盖区前面的 -->
    <h2 :class="['default','bgColor']">呵呵额和</h2>
    <!-- 数组里面的元素可以使用三元运算符 -->
    <h3 :class="['bgColor',isActive?'active':'']">{{message}}</h3>
    <!-- 三目运算符很明显,可读性不是很好,所以我们可以在数组红嵌套对象写法 -->
    <h2 :class="['bgColor',{'active':isActive}]">{{message}}</h2>
  </template>
  <script src="../vue3/vue3.js"></script>
  <script>
    Vue.createApp({
      template: '#my-app',
      data() {
        return {
          message: 'hello Vue3!',
          isActive: true,
          // 一般在定义属性存放数据的时候,不会嵌套的引用其他属性的值
          // 比如  classNameObj = {active:isActive} 这种写法是不被允许的
          classNameObj: {
            active: true,
            bgColor: true
          }
        }
      },
      methods: {
        toggle() {
          this.isActive = !this.isActive;
        },
        getClass() {
          return {
            active: true,
            bgColor: true
          };
        }
      },
    }).mount('#app')
  </script>

image-20210715113823162

4. 绑定style

介绍:我们可以利用v-bind:style来绑定一些CSS内联样式。

因为:某些样式我们需要根据数据动态来决定。比如文字的颜色,大小,行间距,行高等。

CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名

绑定class有两种方式:

  1. 对象语法
  2. 数组语法
对象语法
  1. 不动态绑定时

    <!-- 没有动态绑定时: -->
    <h2 style="color: aquamarine;">{{message}}</h2>
    
  2. 动态绑定style

    <div id="app"></div>
      <template id="my-app">
        <!-- 没有动态绑定时: -->
        <h2 style="color: aquamarine;">{{message}}</h2>
        <!-- 动态绑定style,对象语法 -->
        <!-- 1. 对象形式书写时,key可以不需要加引号,但是如果值是我们写的一个定值(常量),那么值必须加单引号 -->
        <h2 :style="{color: '#ccc'}">1111111111111111111111</h2>
        <!-- 如果值不加单引号,则值会被vue看成书写,会去从实例中找 -->
        <h2 :style="{color: myOrange}">222222222222222</h2>
        <!-- 此外,如果键名是多个单词的组合,不加单引号则遵循驼峰命名, -->
        <h3 :style="{backgroundColor: '#aadacc'}">3333333333333333</h3>
        <!-- 否则使用 - 连接时,则必须使用引号 -->
        <h3 :style="{'background-color': '#dddacc'}">4444444444444444</h3>
        <!-- 也可以进行值的拼接,将动态绑定的属性值与一个常量进行拼接 -->
        <h2 :style="{fontSize:myFontSize + 'px'}">555555555555555555</h2>
        <!-- 如果属性名和定义在实例中的属性值同名,则可以吃采取简写模式 -->
        <h2 :style="{backgroundColor,fontSize}">666666666666</h2>
        <!-- 直接绑定对象当然也肯定是允许的啦 -->
        <h2 :style="myStyle">7777777777777</h2>
        <!-- 绑定函数或者计算属性返回的对象 -->
        <h2 :style="getStyle()">8888888888888</h2>
      </template>
      <script src="../vue3/vue3.js"></script>
      <script>
        Vue.createApp({
          template: '#my-app',
          data() {
            return {
              message: 'hello Vue3!',
              myOrange: 'orange',
              myFontSize: 30,
              backgroundColor: '#aedcfa',
              fontSize: '40px',
              myStyle: {
                color: '#eae',
                fontSize: '30px',
                backgroundColor: '#ccc'
              }
            }
          },
          methods: {
            getStyle(){
              return {
                color: '#eaa',
                fontSize: '40px',
                backgroundColor: '#bdc'
              }
            }
          },
        }).mount('#app')
      </script>
    

    image-20210715114606815

数组语法

style 的数组语法可以将多个样式对象应用到同一个元素上

<div id="app"></div>
  <template id="my-app">
    <!-- 数组语法的使用:一般我们会在数组中放多个对象,然后多个对象会都绑定到style上,自动合并 -->
    <h2 :style="[style1,style2]">111111111111111111111</h2>
  </template>
  <script src="../vue3/vue3.js"></script>
  <script>
    Vue.createApp({
      template: '#my-app',
      data() {
        return {
          message: 'hello Vue3!',
          style1: { color: 'red', fontSize: '30px' },
          style2: { backgroundColor: '#ccc' }
        }
      }
    }).mount('#app')
  </script>

image-20210715114636438

5. 动态绑定属性

在某些情况下,我们属性的名称可能也不是固定的:

  1. 前端我们无论绑定src、href、class、style,属性名称都是固定的;
  2. 如果属性名称不是固定的,我们可以使用 :[属性名]=“值” 的格式来定义;
  3. 这种绑定的方式,我们称之为动态绑定属性;
<style>
    .active {
      color: aquamarine;
    }
  </style>

  <div id="app"></div>
  <template id="my-app">
    <!-- 属性名动态绑定到name,name具体是什么值,绑定的就是什么属性,
      然后在通过value绑定这个动态的属性应该具有的值 -->
    <div :[name]="value">111111111111111</div>
  </template>
  <script src="../vue3/vue3.js"></script>
  <script>
    Vue.createApp({
      template: '#my-app',
      data() {
        return {
          message: 'hello Vue3!',
          name: 'class',
          value: 'active'
        }
      }
    }).mount('#app')
  </script>

image-20210715114706276

6. 绑定一个对象

如果我们希望将一个对象的所有属性,绑定到元素上的所有属性,应该怎么做呢?

非常简单,我们可以直接使用 v-bind 绑定一个 对象

例如:info对象会被拆解成div的各个属性

<div id="app"></div>
  <template id="my-app">
    <!-- 当我们将动态的将一个对象上的所有属性都绑定给一个标签元素时 -->
    <!-- 我们可以直接用 v-bind='对象' -->
    <div v-bind="info">{{message}}</div>
    <!-- 也可以使用语法糖,但是貌似看起来有点怪,不是很建议使用 -->
    <div :="info">{{message}}</div>
    <!-- 这种绑定方式会将绑定的对象的属性全都解构到这个元素上,成为这个元素的属性 -->
  </template>
  <script src="../vue3/vue3.js"></script>
  <script>
    Vue.createApp({
      template: '#my-app',
      data() {
        return {
          message: 'hello Vue3!',
          info: {
            name: '哈哈',
            style: 'color:red',
            age: 22,
            data: '你好!'
          }
        }
      }
    }).mount('#app')
  </script>

image-20210715114815454

v-on指令 绑定事件

前面我们绑定了元素的内容和属性,在前端开发中另外一个非常重要的特性就是交互。

在前端开发中,我们需要经常和用户进行各种各样的交互:

这个时候,我们就必须监听用户发生的事件,比如点击、拖拽、键盘事件等等

在Vue中如何监听事件呢?使用v-on指令

接下来我们来看一下v-on的用法:

v-on的使用:

缩写:@

预期:Function | Inline Statement | Object

参数:event

(事件)修饰符:

  1. .stop - 调用 event.stopPropagation()。
  2. .prevent - 调用 event.preventDefault()
  3. .capture - 添加事件侦听器时使用 capture 模式
  4. .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调
  5. .{keyAlias} - 仅当事件是从特定键触发时才触发回调
  6. .once - 只触发一次回调。
  7. .left - 只当点击鼠标左键时触发
  8. .right - 只当点击鼠标右键时触发。
  9. .middle - 只当点击鼠标中键时触发
  10. .passive - { passive: true } 模式添加侦听器

用法:绑定事件监听

基本使用

我们可以使用v-on来监听一下点击的事件:

    <!-- v-on指令,绑定监听的事件 v-on:监听的事件 = "methods里面定义的函数" -->
    <button v-on:click="btnClick1">按钮1</button><br>

image-20210715115310402

v-on:click可以写成@click,是它的语法糖写法:

<button @click="btnClick1">按钮1</button><br>

当然,我们也可以绑定其他的事件:

<!-- 监听鼠标移动的方法 -->
<div v-on:mousemove="btn2Move">鼠标在移动事件</div>

image-20210715115512649

如果我们希望一个元素绑定多个事件,这个时候可以传入一个对象:

    <button @="{'click':btnClick1,'mousemove':btn2Move}" @click="btnClick2">绑定多个事件,两个点击事件都会生效</button>

image-20210715115611372

**基本使用总览:**大家多多尝试

<style>
    .dd{
      width: 200px;
      height: 200px;
      background-color: aquamarine;
    }
  </style>

<div id="app"></div>
  <template id="my-app">
    <!-- v-on指令,绑定监听的事件 v-on:监听的事件 = "methods里面定义的函数" -->
    <button v-on:click="btnClick1">按钮1</button><br>
    <!-- 监听鼠标移动的方法 -->
    <div class="dd" v-on:mousemove="btn2Move">鼠标在移动事件</div>
    <!-- 语法糖的写法 -->
    <button @click="btnClick2">按钮2</button><br>
    <!-- 绑定一个表达式 -->
    <button @click="counter++">点击数字加一</button> <span style="color: blueviolet;">{{counter}}</span>
    <!-- 同时绑定多个事件的时候,我们一般采用对象的形式 -->
    <!-- 同一个事件不能在对象里面多次绑定,不然后面的会覆盖前面的 -->
    <!-- 因为在对象中,同名属性会被后面定义的覆盖 -->
    <button v-on="{'click':btnClick1,'click':btnClick2}">只有第二个点击事件生效</button><br>
    <!-- 将同一个事件分开绑定,会同时生效 -->
    <button @="{'click':btnClick1,'mousemove':btn2Move}" @click="btnClick2">绑定多个事件,两个点击事件都会生效</button>
  </template>
  <script src="../vue3/vue3.js"></script>
  <script>
    Vue.createApp({
      template: '#my-app',
      data() {
        return {
          message: 'hello Vue3!',
          counter: 0
        }
      },
      methods: {
        btnClick1() {
          console.log('btn1 发生了点击');
        },
        btn2Move(){
          console.log('鼠标移动');
        },
        btnClick2() {
          console.log('btn2 发生了点击');
        },
      },
    }).mount('#app')
  </script>

image-20210715115941888

v-on参数传递

当通过methods中定义方法,以供@click调用时,需要注意参数问题:

  1. 如果该方法不需要额外参数,那么方法后的()可以不添加

    <!-- 绑定事件,直接绑定事件处理函数名,不带括号,也会默认传递一个触发的事件参数 -->
    <button @click="btnClick">按钮</button>
    

    image-20210715120320150

  2. 如果方法本身中有一个参数,那么会默认将原生事件event参数传递进去

    <button @click="btnClick">按钮</button>
    
  3. 如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件。

    <!-- vue中,使用 $event 来获取事件参数 -->
    <button @click="btnClick2($event,'你好!')">按钮</button>
    

    image-20210715120339775

  4. 如果事件处理函数带括号了,不传递参数,默认是接收不到 event事件的

    <!-- 注意,绑定函数时如果带括号,却不传递参数,那么事件参数也是拿不到的-->
    <button @click="btnClick3()">按钮</button>
    

    image-20210715120438940

总览:

<div id="app"></div>
  <template id="my-app">
    <!-- 绑定事件,直接绑定事件处理函数名,不带括号,也会默认传递一个触发的事件参数 -->
    <button @click="btnClick">按钮</button>
    <!-- 点击按钮的时候,还需传递其他参数时,需要书写的时候带上函数的括号,并传递参数 -->
    <!-- vue中,使用 $event 来获取事件参数 -->
    <button @click="btnClick2($event,'你好!')">按钮</button>
    <!-- 注意,绑定函数时如果带括号,却不传递参数,那么事件参数也是拿不到的-->
    <button @click="btnClick3()">按钮</button>
  </template>
  <script src="../vue3/vue3.js"></script>
  <script>
    Vue.createApp({
      template: '#my-app',
      data() {
        return {
          message: 'hello Vue3!'
        }
      },
      methods: {
        btnClick(event) {
          console.log(event);
        },
        btnClick2(event,data) {
          console.log(event);
          console.log(data);
        },
        btnClick3(event) {
          console.log(event);
        }
      },
    }).mount('#app')
  </script>
v-on 事件修饰符

v-on支持修饰符,修饰符相当于对事件进行了一些特殊的处理:

  1. .stop - 调用 event.stopPropagation()。
  2. .prevent - 调用 event.preventDefault()
  3. .capture - 添加事件侦听器时使用 capture 模式
  4. .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调
  5. .{keyAlias} - 仅当事件是从特定键触发时才触发回调
  6. .once - 只触发一次回调。
  7. .left - 只当点击鼠标左键时触发
  8. .right - 只当点击鼠标右键时触发。
  9. .middle - 只当点击鼠标中键时触发
  10. .passive - { passive: true } 模式添加侦听器

例如:.stop的使用如下:

<div id="app"></div>
  <template id="my-app">
    <div @click="divClick">
      <button @click="btnClick1">按钮1 不阻止冒泡</button>
      <button @click="btnClick2">按钮2 使用js提供的方法阻止冒泡</button>
      <button @click.stop="btnClick3">按钮3 使用事件修饰符阻止冒泡</button>
    </div>
  </template>
  <script src="../vue3/vue3.js"></script>
  <script>
    Vue.createApp({
      template: '#my-app',
      data() {
        return {
          message: 'hello Vue3!'
        }
      },
      methods: {
        btnClick1() {
          console.log('btn 111111111')
        },
        btnClick2(event) {
          // 阻止冒泡
          event.stopPropagation()
          console.log('btn 222222222')
        },
        btnClick3() {
          console.log('btn 33333333')
        },
        divClick(){
          console.log('div 44444444');
        }
      }
    }).mount('#app')
  </script>

image-20210715121004503

image-20210715121026449

事件修饰符的其他使用可以自行练习。emmm,具体的细节我会再出一个博客专门讲解修饰符以及相关案例。

今日分享结束!冲冲冲

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐