(六)Vue和React的编码方式对比----事件与事件对象

第五篇讲组件和组件通信的时候使用过点击事件,在日常开发中我们会用到各种各样的事件,总不能我们只写纯静态页面吧,如果那样为什么我们不直接一个img把设计图放上去呢。咳咳。

本篇主要讲Vue和React的事件和事件对象。从此以后,用户就可以与我们的页面进行交互了。

一、React中的事件

了解React之前,我们需要了解什么是事件。事件是用户在某种事物上的某种行为操作,ok,很好,成功把事件扩充到了这么多字。简单的来说用户的鼠标移动、点击,键盘按下、抬起等都是事件。

有些细心地童靴可能已经发现,React中事件的绑定书写方式与原生JS一样,都是直接onClick,所以React的事件就与JS原生一样吗?当然~不一样,React并不是将 click事件直接绑定在 dom 上面,而是采用事件冒泡的形式,一路冒到 document 上面,这个思路借鉴事件委托机制。这个有机会后边再讲。

1、实现一个简单的事件

我们先简单的写一个事件让大家感受一下,下面我举个栗子。

import React, { Component } from 'react'

export default class Home extends Component {
    constructor() {
        super()
        this.state = {
            msg:'我是按钮,我被点了'
        }
    }
    buttonClick(){
        console.log(this.state.msg)
    }
    render() {
        return (
            <div>
                <div>Home</div>
                <button onClick={this.buttonClick}>按钮</button>
            </div>
        )
    }
}

在之前说过React组件有两种,有状态和无状态,无状态因为没有state一般用于静态展示,所以在这个例子中我们是用的事状态组件,也就是类组件。函数组件本身就不擅长做交互,没必要难为它...

让我们点击运行一下,诶嘿,报错了

state没找到,怎么会呢,上次说的使用state中的数据就是this.state.属性,我们console一下this看看咋回事(我演的真好)

我们会发现this是undefined,为什么呢?原因是类的方法默认是不绑定this的,说到底还是this指向问题,没有绑定自然就没有了。既然没有,那我们就绑一个! 

2.this指向问题解决方法1,bind()

让我们稍加改造一下代码

import React, { Component } from 'react'

export default class Home extends Component {
    constructor() {
        super()
        this.state = {
            msg:'我是按钮,我被点了'
        }
        this.buttonClick = this.buttonClick.bind(this)
    }
    buttonClick(){
        console.log(this.state.msg)
    }
    render() {
        return (
            <div>
                <div>Home</div>
                <button onClick={this.buttonClick}>按钮</button>
            </div>
        )
    }
}

我们也仅仅是在this.state下面增加了一句this.buttonClick = this.buttonClick.bind(this)就解决这个问题,需要注意,这两个buttonClick名字要一样的。

不过这种写法好像不太好看(代码太多,懒),有没有别的方法呢,当然有,往下看。

import React, { Component } from 'react'

export default class Home extends Component {
    constructor() {
        super()
        this.state = {
            msg:'我是按钮,我被点了'
        }
    }
    buttonClick(){
        console.log(this.state.msg)
    }
    render() {
        return (
            <div>
                <div>Home</div>
                <button onClick={this.buttonClick.bind(this)}>按钮</button>
            </div>
        )
    }
}

这次我们将bind(this)写在了onclick中,也是同样的效果,好像方便了很多,那有没有其他的呢,毕竟又得童靴之前并没有很经常的用bind,还有以下两种方式 

3.this指向问题解决方法2,匿名函数+箭头函数

这个方法我们还是在onclick上做手脚,写了一个匿名箭头函数,大家都知道箭头函数是没有this的,它会往上找,所以在这种写法中,this会直接上升到render中,这样他就有this了,也就不会报错了。

import React, { Component } from 'react'

export default class Home extends Component {
    constructor() {
        super()
        this.state = {
            msg:'我是按钮,我被点了'
        }
    }
    buttonClick(){
        console.log(this.state.msg)
    }
    render() {
        return (
            <div>
                <div>Home</div>
                <button onClick={()=>{this.buttonClick()}}>按钮</button>
            </div>
        )
    }
}

4.this指向问题解决方法3,属性初始化器语法

折腾够了onclick,我们来折腾一下函数本身,这种方法还是实验性的,但是支持的还不错

import React, { Component } from 'react'

export default class Home extends Component {
    constructor() {
        super()
        this.state = {
            msg:'我是按钮,我被点了'
        }
    }
    buttonClick = () => {
        console.log(this.state.msg)
    }
    render() {
        return (
            <div>
                <div>Home</div>
                <button onClick={this.buttonClick}>按钮</button>
            </div>
        )
    }
}

其实还是利用剪头函数解决这个问题,但是这是实验性的,看好多博主也不是很推荐。 

二、React事件对象--event

学过原生JS的肯定不陌生,事件对象event,其实就是事件的各种信息,而且React的事件对象是经过React合成的,没有兼容问题,还是很方便

import React, { Component } from 'react'

export default class Home extends Component {
    constructor() {
        super()
        this.state = {
            msg:'我是按钮,我被点了'
        }
    }
    buttonClick(e){
        console.log(e)
    }
    render() {
        return (
            <div>
                <div>Home</div>
                <button onClick={(e)=>{this.buttonClick(e)}}>按钮</button>
            </div>
        )
    }
}

 事件对象常用的功能就是通过data-*拿取一些数据,或者阻止事件冒泡或默认事件,在React中不能通过return false来阻止默认事件

import React, { Component } from 'react'

export default class Home extends Component {
    constructor() {
        super()
        this.state = {
            msg:'我是按钮,我被点了'
        }
    }
    buttonClick(e){
        // 阻止默认事件
        e.preventDefault();
        // 阻止事件冒泡
        e.stopPropagation();
    }
    render() {
        return (
            <div>
                <div>Home</div>
                <button onClick={(e)=>{this.buttonClick(e)}}>按钮</button>
            </div>
        )
    }
}

三、Vue中的事件

相对来说Vue的事件更为简单,毕竟使用数据时,并没有React一样遇到报错的情况,this也是很明确的管用了。绑定事件时与React不太相同,但是也是不难理解,v-on:click也可以简写为@click,毕竟谁愿意多敲四次键盘呢。

<template>
	<div>
		<div>Home</div>
		<button v-on:click="buttonClick">按钮</button>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				msg: '我是vue按钮,我被点击了'
			}
		},
		methods: {
			buttonClick() {
				console.log(this.msg)
			}
		}
	}
</script>

<style>
</style>

四、Vue事件对象--$event

Vue的事件对象是特殊的,必须写为$event,就算偷懒写event都会报错。不过Vue的事件都自带事件对象,不写$event直接在函数中使用e也不会报错,可以不写但是不能写错。

<template>
	<div>
		<div>Home</div>
		<button v-on:click="buttonClick($event)">按钮</button>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				msg: '我是vue按钮,我被点击了'
			}
		},
		methods: {
			buttonClick(e) {
				console.log(e)
			}
		}
	}
</script>

<style>
</style>

既然事件对象是特殊的,有自己的关键字,那么如果我想阻止事件冒泡是不是也可以这么做 

<template>
	<div @click="boxClick">
		<div>Home</div>
		<button v-on:click="buttonClick($event)">按钮</button>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				msg: '我是vue按钮,我被点击了'
			}
		},
		methods: {
			buttonClick(e) {
				console.log(this.msg)
				e.stopPropagation()
			},
			boxClick() {
				console.log('冒泡了')
			}
		}
	}
</script>

<style>
</style>

从结果看很成功,说明$event虽然有那么一丝与众不同,但是基本能做的还是可以做到的。不过在Vue中我们并不经常使用这种方式,因为....(字母太多了)

 

五、Vue事件修饰符 

欢迎来到Vue为我们懒人准备的功能,事件修饰符。还是以上边代码作为例子,我们去阻止冒泡到最外层div。

<template>
	<div @click="boxClick">
		<div>Home</div>
		<button @click.stop="buttonClick($event)">按钮</button>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				msg: '我是vue按钮,我被点击了'
			}
		},
		methods: {
			buttonClick(e) {
				console.log(this.msg)
			},
			boxClick() {
				console.log('冒泡了')
			}
		}
	}
</script>

<style>
</style>

灰常简单,只需要在@click后添加一个.stop即可阻止事件冒泡,对于我这种能少敲少背单词就偷懒的人还是很友好的。

除了stop,还有很多常用的修饰符如下

.stop                阻止事件冒泡

.prevent           阻止默认事件

.capture           捕获冒泡,当有冒泡时,会优先触发

.self                  事件绑定到自身,只有自身才能触发

.once                事件只触发一次

.native              父组件给子组件绑定一个原生事件,子组件变为一个HTML标签

                        经常用ElementUI的同学应该常见这个 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值