Vue事件处理

一、事件的基本使用

1.使用v-on:xxx 或 @xxx 绑定事件,其中 xxx 是事件名;

2. 事件的回调需要配置在methods对象中,最终会在vm上;

3.methods中配置的函数,不要用箭头函数!否则this就不是vm了;

4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;

5.@click="demo" 和 @click="demo($event)" 效果一致,但后者都可以传参;

<div id="root">
    <h2>欢迎来到{{name}}学习</h2>
    <!-- <button v-on:click="showInfo">点我提示信息</button> -->
    <button @click="showInfo1">点我提示信息1(不传参)</button>
    <button @click="showInfo2($event,66)">点我提示信息2(传参)</button>
</div>
<script type="text/javascript" src="../js/vue.js" />
<script type="text/javascript">
    Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

    const vm = new Vue({
        el:'#root',
        data:{
            name:'尚硅谷',
        },
        methods:{
            showInfo1(event){
                // console.log(event.target.innerText)
                // console.log(this) //此处的this是vm
                alert('同学你好!')
            },
            showInfo2(event,number){
                console.log(event,number)
                // console.log(event.target.innerText)
                // console.log(this) //此处的this是vm
                alert('同学你好!!')
            }
        }
    })
</script>

 

二、Vue中事件修饰符

1.prevent:阻止默认事件(常用);

2.stop:阻止事件冒泡(常用);

3.once:事件只会触发一次(常用);

4.capture:使用事件的捕获模式;

5.self:只有event.target是当前操作的元素时才触发事件;

6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

<div id="root">
    <h2>欢迎来到{{name}}学习</h2>
    <!-- 阻止默认事件(常用) -->
    <a href="http://www.atguigu.com" @click.prevent="showInfo">点我提示信息</a>

    <!-- 阻止事件冒泡(常用) -->
    <div class="demo1" @click="showInfo">
        <button @click.stop="showInfo">点我提示信息</button>
        <!-- 修饰符可以连续写 -->
        <!-- <a href="http://www.atguigu.com" @click.prevent.stop="showInfo">点我提示信息</a> -->
    </div>

    <!-- 事件只触发一次(常用) -->
    <button @click.once="showInfo">点我提示信息</button>

    <!-- 使用事件的捕获模式 -->
    <div class="box1" @click.capture="showMsg(1)">
        div1
        <div class="box2" @click="showMsg(2)">
            div2
        </div>
    </div>

    <!-- 只有event.target是当前操作的元素时才触发事件; -->
    <div class="demo1" @click.self="showInfo">
        <button @click="showInfo">点我提示信息</button>
    </div>

    <!-- 事件的默认行为立即执行,无需等待事件回调执行完毕; -->
    <ul @wheel.passive="demo" class="list">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
</div>

<script type="text/javascript" src="../js/vue.js" />
<script type="text/javascript">

    new Vue({
        el:'#root',
        data:{
            name:'尚硅谷'
        },
        methods:{
            showInfo(e){
                alert('同学你好!')
                // console.log(e.target)
            },
            showMsg(msg){
                console.log(msg)
            },
            demo(){
                for (let i = 0; i < 100000; i++) {
                    console.log('#')
                }
                console.log('累坏了')
            }
        }
    })
</script>

 

三、键盘事件

1.Vue中常用的按键别名:

  回车 => enter

  删除 => delete (捕获"删除"和"退格"键)

  退出 => esc

  空格 => space

  换行 => tab(特殊,必须配合keydown去使用)

  上 => up

  下 => down

  左 => left

  右 => right

2. Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)

3. 系统装饰键(用法特殊):ctrl,alt,shift,meta

  (1)配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他按键,事件才被触发。

  (2)配合keydown使用:正常触发事件

4.也可以使用keyCode去指定具体的按键(不推荐)

5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名

<div id="root">
    <h2>欢迎来到{{name}}学习</h2>
    <input type="text" placeholder="按下回车提示输入" @keydown.huiche="showInfo">
</div>
<script type="text/javascript">
    Vue.config.keyCodes.huiche = 13 //定义了一个别名按键

    new Vue({
        el:'#root',
        data:{
            name:'尚硅谷'
        },
        methods: {
            showInfo(e){
                // console.log(e.key,e.keyCode)
                console.log(e.target.value)
            }
        },
    })
</script>

 

四、组件的自定义事件

1. 一种组件间通讯的方式,适用于:子组件 ===> 父组件

2. 使用场景:A是父组件、B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中

3. 绑定自定义事件

    a. 第一种方式:在父组件中:

<Demo @myevent="test"/><Demo v-on:myevent="test"/>

    b. 第二种方式:在父组件中

<Demo ref="xxx"/>
......
mounted(){
   this.$refs.xxx.$on('myevent',this.test)
}

    c. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法

4. 触发自定义事件

this.$emit('myevent',数据)

5. 解绑自定义事件

this.$off('myevent')

6. 组件上也可以绑定原生DOM事件,需要使用native修饰符

7. 注意:通过 this.$refs.xxx.$on('myevent',回调)绑定自定义事件时,

   回调要么配置在methods中,要么用箭头函数,否则this指向会出问题

 

父组件的代码:

<template>
    <div class="app">
        <h1>{{msg}},学生姓名是:{{studentName}}</h1>

        <!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 -->
        <School :getSchoolName="getSchoolName"/>

        <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on) -->
        <!-- <Student @myevent="getStudentName" @demo="m1"/> -->

        <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用ref) -->
        <Student ref="student" @click.native="show"/>
    </div>
</template>

<script>
    import Student from './components/Student'
    import School from './components/School'

    export default {
        name:'App',
        components:{School,Student},
        data() {
            return {
                msg:'你好啊!',
                studentName:''
            }
        },
        methods: {
            getSchoolName(name){
                console.log('App收到了学校名:',name)
            },
            getStudentName(name,...params){
                console.log('App收到了学生名:',name,params)
                this.studentName = name
            },
            m1(){
                console.log('demo事件被触发了!')
            },
            show(){
                alert(123)
            }
        },
        mounted() {
            this.$refs.student.$on('myevent',this.getStudentName) //绑定自定义事件
            // this.$refs.student.$once('myevent',this.getStudentName) //绑定自定义事件(一次性)
        },
    }
</script>

<style scoped>
    .app{
        background-color: gray;
        padding: 5px;
    }
</style>

子组件的代码:

<template>
    <div class="student">
        <h2>学生姓名:{{name}}</h2>
        <h2>学生性别:{{sex}}</h2>
        <h2>当前求和为:{{number}}</h2>
        <button @click="add">点我number++</button>
        <button @click="sendStudentlName">把学生名给App</button>
        <button @click="unbind">解绑atguigu事件</button>
        <button @click="death">销毁当前Student组件的实例(vc)</button>
    </div>
</template>

<script>
    export default {
        name:'Student',
        data() {
            return {
                name:'张三',
                sex:'',
                number:0
            }
        },
        methods: {
            add(){
                console.log('add回调被调用了')
                this.number++
            },
            sendStudentlName(){
                //触发Student组件实例身上的atguigu事件
                this.$emit('myevent',this.name,666,888,900)
                // this.$emit('demo')
                // this.$emit('click')
            },
            unbind(){
                this.$off('myevent') //解绑一个自定义事件
                // this.$off(['myevent','demo']) //解绑多个自定义事件
                // this.$off() //解绑所有的自定义事件
            },
            death(){
                this.$destroy() //销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效。
            }
        },
    }
</script>

<style lang="less" scoped>
    .student{
        background-color: pink;
        padding: 5px;
        margin-top: 30px;
    }
</style>

 

 

五、全局事件总线(GlobalEventBus)

1. 一种组件间通讯方式,适用于任意组件通信

2. 安装全局事件总线

   new Vue({
       ......
       beforeCreate() {
           Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
       },
       ......
   }) 

3. 使用事件总线

    a. 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.$bus.$on('xxxx',this.demo)
      }

    b. 提供数据:this.$bus.$emit('xxx',数据)

4. 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件

 

六、消息订阅与发布

1. 一种组件间通信的方式,适用于任意组件通信

2. 使用步骤:

    a. 安装pubsub: npm i pubsu-js

    b. 引入:import pubsub from 'pubsub-js'

    c. 接收数据:A组件想接收数据,则在A组件中订阅信息,订阅的回调留在A组件自身

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
      }

    d. 提供数据:pubsub.publish( 'xxx' , 数据 )

    f. 最好在beforeDestroy钩子中,用 pubsub.unsubscribe(pid) 取消订阅;

 

posted @ 2023-12-23 16:00  喻聪  阅读(27)  评论(0编辑  收藏  举报