美文网首页Vue系列
第七节:Vue指令:v-on事件的绑定与问题

第七节:Vue指令:v-on事件的绑定与问题

作者: 曹老师 | 来源:发表于2022-06-07 00:04 被阅读0次

1.理解Vue事件的绑定方式

1.1 原生行内事件绑定

说明:

  1. vue采用行内事件绑定的方式.
  2. 因此在学习vue事件绑定方式之前,先回顾一下JS的行内事件绑定
  3. 学习中对比vue的行内事件绑定和JS原生行内事件绑定的不同

示例代码如下:

<style>
    .box{
        color:red;
    }
    .wrap{
        color:skyblue;
    }
</style>
<div id="app">
    <h2 id="box" class="box">Hello World</h2>
    <button onclick="changeColor()">点击切换颜色</button>
</div>

<script>   
    let className = "box"
    function changeColor(){
        if(className =='box'){
            box.className = className = "wrap"

        }else{
            box.className = className =  "box"
        }
    }
</script>

注意:

  1. 这种原生绑定事件方式不常用,因为耦合性太高

  2. onclick属性值是函数执行字符串,在点击触发后会把这个字符串强制转为js语句执行

vue采用这种方式绑定事件,
原因在于这种绑定方式比较直观的处理事件的绑定, 省去了大量获取DOM的操作.
不用担心Vue的问题, Vue在采用行内事件绑定,内部肯定做了大量的优化处理

2.v-on(@) 事件的绑定与基本使用

为了让用户和你的应用进行交互,我们可以用 v-on 指令添加一个事件监听器,通过事件监听器触发事件执行程序

2.1 v-on指令的认识和使用

v-on指令说明

  1. v-on指令和其他指令一样,通过v-on绑定事件后,事件属性值将不再是字符串,而是表达式
  2. 因此接班是表达式就可以在引号中做一些基本的操作
<div id="app">
    <h2 class="box">点击次数: {{ count }}</h2>
    <!-- 既然click 的值是表达式,那么我们就可以动态的拿到vue ,data属性中的数据,然后操作-->
    <button v-on:click="count++">暴击</button>
</div>

<script>   

    const vm = new Vue({
        el: "#app",
        data: {
            count: 0

        }
    })
</script>

示例说明:

  1. 通过v-on指令绑定click单机事件
  2. v-on指定绑定事件的属性值是表达式,表达式中可以直接获取vue中的数据
  3. 因此可以是表达式中直接对数据进行修改

通过上面的说明就能理解,每次点击都会修改数据,数据的修改触发vue响应系统,进而改变页面显示

之中直接修改数据一般情况下用的比较少,原因在于:

  1. 通过v-on绑定的事件属性值虽然是表达式,但是只能处理单个表达式逻辑
  2. 如果处理复杂的程序就会有局限性
  3. 同时没发在引号中使用事件对象,来处理事件的细节

因此,通常会选择在表达式中绑定vue的方法,将方法作为事件函数处理

2.2 v-on指定绑定methods方法

调用在 Vue 实例中定义的方法
说明:

  1. 在选项对象属性methods中定义vue示例的方法
  2. 通过方法名将vue办法绑定给事件,作为事件处理函数使用

示例1:修改上一个示例,限制点击次数

<!-- 限定点击次数 -->
<div id="app">
    <h2 class="box">点击次数: {{ count }}</h2>
    <button v-on:click="handleClick">点击</button>
</div>

<script>   
    const vm = new Vue({
        el: "#app",
        data: {
            count: 0
        },
        methods: {
            handleClick(){
                let count = this.count;
                // 限定显示最大点击次数
                this.count = Math.min(++count,5)
            }
        }
    })
</script>

示例2: 翻转消息

<!-- HTML --->
<div id="app-5">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">逆转消息</button>
</div>

<!-- JS --->
<script>
    new Vue({
        el: "#app-5",
        data: {
            message: 'Hello Vue.js'
        },
        methods: {
            reverseMessage: function(){
               this.message = this.message.split('').reverse().join('')
            }
        }
    })
</script>

示例说明:

  1. 通过示例,当按钮绑定button被点击时,就会触发methods属性中的的方法,
  2. 在方法中修改数据, 当数据被修改时触发响应系统, 响应系统触发视图的重新渲染,

注意.

methods中方法,不能和data的数据重名,因为data中的数据和methods中的方法都会在Vue初始化时成为Vue示例的属性或方法

2.3 事件绑定的简写方式
<!-- 完整语法 -->
<button v-on:click="reverseMessage">逆转消息</button>

<!-- 缩写 -->
<button @click="reverseMessage">逆转消息</button>

3. 关于函数内的this指向问题

3.1 普通函数this

方法内this默认指向实例对象,就可以通过实例对象处理很多操作

<div id="app">
    <!-- 绑定事件触发Vue方法 -->
    <button @click="reversed">按钮</button>
</div>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            msg: "Hello Vue"
        },
        methods: {
            reversed() {
                console.log(this) // 实例对象
            }
        }
    })
</script>

点击结果

image
3.2 箭头函数中this

如果改为箭头函数为如下写法:

{
    reversed:() =>  {
        console.log(this) // 实例对象
    }
}

那么我们就将实例中的方法换成箭头函数

<div id="app">
    <!-- 绑定事件触发Vue方法 -->
    <button @click="reversed">按钮</button>
</div>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            msg: "Hello Vue"
        },
        methods: {
            reversed:()=> {
                console.log(this) // 实例对象
            }
        }
    })

</script>

点击结果:

image

4. methods方法中不推荐使用箭头函数

其实在上一小节中了解方法的不同写法会导致this的不同, 那么就来罗列一下不推荐使用箭头函数的原因

4.1 methods不推荐使用箭头函数

不推荐使用功能箭头函数说明:
1.vue是以数据作为驱动的,数据的变化将会触发vue响应系统,同时更改页面的渲染结果,

  1. vue以数据为驱动,也就是说我们在未来的操作中将大量操作数据,
  2. 数据被处理为Vue 实例vm上的属性,那么我们就需要大量的通过vm对象来调用数据
  3. 甚至methods的中的方法也会挂在在vm对象上的,
  4. 因此箭头函数会影响我们对于数据和方法的获取,因为箭头函数thiswindow

也正式因为这些原因,我们不推荐方法使用箭头函数,因为这样会丢失this指向, 那么我们就不能利用this 来获取数据和其他方法了.

看下面的例子

<div id="app">
    <button @click="handleClick">非箭头函数中this</button>
    <button @click="handleClickTwo">箭头函数中的this</button>
</div>

<script>   

    const vm = new Vue({
        el: "#app",
        data: {
            msg: "hello"
        },
        methods: {
            handleClick(){
                console.log(this)  // vue实例化对象
            },
            handleClickTwo: () => {
                console.log(this) // window 对象

            },
        }
    })
</script>

这样我们就会发现如果我们使用普通函数, 那么要获取数据就很简单

handleClick(){
    console.log(this)  // vue实例化对象
    // 利用this 获取数据
    console.log(this.msg)  // 获取数据
},

总结:

methods属性中方法函数中如果不需要操作Vue实例上的属性和方法, 可以使用箭头函数,

但是一般不推荐使用箭头函数, 原因

  1. 一是因为我们随时可能需要在方法中获取Vue实例的其他数据或其他方法,
  2. 二是统一的编码风格,总不至于有的用箭头函数,有的不用吧,
4.2 关于Vue方法里使用箭头函数误区

但是我们需要避免一个误区:

我们推荐不使用箭头函数是methods的方法, 不是说真个Vue项目里都不能使用箭头函数,

比如我们如果在方法里还有函数,在函数中需要使用vue实例化对象我们这个时候用箭头函数会比非箭头函数要

例如

<div id="app">
    <button @click="handleClick">查看this</button>
</div>

<script>   

    const vm = new Vue({
        el: "#app",
        data: {
            msg: "hello"
        },
        methods: {
            handleClick(){
                console.log(this)  // vue实例化对象

                // 延迟修改数据
                // 1.方法内使用普通函数,查看普通函数中this
                setTimeout(function(){
                    console.log(this)  // window 对象

                    // 这个是有要修改数据,还的使用vm
                    vm.msg = "wrod"
                }, 1000)

                // 2.方法内使用箭头函数, 查看函数内this
                setTimeout(() => {
                    console.log(this) // vue实例对象

                    // 这个是有修改数据,依然可以使用this
                    this.msg = "wuwei"

                }, 2000)
            },

        }
    })
</script>

通过示例就能看出,用不用箭头函数,完全看自己的需求, 而不是说不推荐使用箭头函数,就整个Vue项目中一个箭头函数都不用了,

要关注一下是哪里不推荐使用箭头函数.

因此:

Vue中是不是用箭头函数,完全看你自身的情况,千万不要听人说Vue不推荐使用箭头函数,就整个Vue项目中一个箭头函数都不用, 用不用,看this

5. 关于方法的事件对象

在调用方法的时候有两种情况,一种是不加括号,一种加括号

<!--不加括号 -->
<button @click="reversed">点击</button>

<!--加括号 -->
<button @click="reversed()">点击</button>
<button @click="reversed(12345)">点击</button>

那么很明显使用加括号的方式是为了传递参数给事件函数,

那么我们就来看看不同的事件绑定方式对于事件对象的影响

5.1 不加括号

不加括号的情况下,默认第一个形参就是事件对象

<div id="app">
    <!-- 不加括号绑定事件 -->
    <button @click="reversed">点击</button>
</div>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            msg: "Hello Vue"
        },
        methods: {
            reversed:(ev)=> {
                console.log(ev) // 事件对象
            }
        }
    })

</script>

页面点击结果:

image
5.2 加括号

如果加括号无论你传不传实参,形参默认就是要接受你传递的实参

<div id="app">
    <!-- 加括号未传参 -->
    <button @click="reversed()">点击</button>

    <!-- 加括号传参 -->
    <button @click="reversed(123)">点击2</button>
</div>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            msg: "Hello Vue"
        },
        methods: {
            reversed:(ev)=> {
                console.log(ev) // 事件对象
            }
        }
    })

</script>

点击后的结果

image

事件绑定加括号说明

  1. 通过示例发现,加括号没有传参是,事件函数的第一个形参是undefined因为没有接受到实参

  2. 如果加括号绑定事件, 事件执行传递了实参,那么事件函数的第一个形参就是传递过来的实参

那么问题来了,如果我需要传参时如何获取事件对象呢

5.3 绑定事件手动传递事件对象

如果加括号就需要手动的传递事件对象

<div id="app">
    <!-- 手动传递事件对象,此时$event就是事件对象 -->
    <button @click="reversed($event,123)">点击</button>

</div>

<script>
    const vm = new Vue({
        el:"#app",
        data:{
            msg:"Hello Vue"
        },
        methods: {
            reversed(ev,num){
                console.log(ev) // 事件对象
                console.log(num) // 123
            }
        }
    })

</script>

点击结果

image
5.4 默认事件对象的变量

同时还发现: 无论加不加括号,传不传参数,在函数里变量event默认是事件对象, 所以不要定义同名变量将其覆盖就可以了

<div id="app">
    <!-- 手动传递事件对象,此时$event就是事件对象 -->
    <button @click="reversed($event,123)">点击</button>

</div>

<script>
    const vm = new Vue({
        el:"#app",
        data:{
            msg:"Hello Vue"
        },
        methods: {
            reversed(ev,num){
                console.log(event);

            }
        }
    })

</script>

点击显示结果

image

总结:

  1. 方法写在methods属性中
  2. 事件函数不需要传参不加括号, 需要传参加括号
  3. 事件函数无括号,默认第一个参数是事件对象
  4. 事件函数有括号,需要手动传递事件对象
  5. 无论事件函数有无括号,event变量都是事件对象,前提不能有同名变量覆盖

相关文章

网友评论

    本文标题:第七节:Vue指令:v-on事件的绑定与问题

    本文链接:https://www.haomeiwen.com/subject/phsdmrtx.html