vue的原生DOM事件、绑定组件、自定义事件

本文详细介绍了Vue中如何通过v-on绑定DOM原生事件,自定义事件的使用以及父子组件间的通信,包括$event的作用、native修饰符的应用和自定义事件与原生事件的优先级。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1- 绑定的是HTML当中的button元素,通过v-on进行事件的绑定

在这里的事件对象是 $event ,与其他实参的顺序可以任意变换

<button @click="EventClick('传递的实参',$event)">Vue中的DOM原生事件</button>
EventClick(a,b){
// ! event这个事件对象是默认的,在进行事件绑定的时候不管你传还是不传递$event,都是有event这个事件对象,并且这个event的事件对象名称是固定的,不能随意的改变,只能是 event
// console.log("EventClick",event)

console.log(a,b)  // a或者b接收实参传递的$event,看$event的位置
}

2- 直接给自定义组件绑定点击事件( @click="ChildClick" ) 事件并不会触发

需要给click增加native修饰符 native:本地的

@click.native 时事件会变为原生事件,会将事件绑定到子组件的根元素上,这时点击子组件的所有元素都会触发事件,因为产生了冒泡

<Child @click.native="ChildClick($event,'传递的实参')"/>
ChildClick(event,arg){
// event传不传都有
console.log("ChildClick",event,arg)
}

3- v-on监听自定义事件

        父组件中, 利用v-on进行事件的监听操作,可以不传递参数,也可以不加(),那么回调函数中的event就是默认的事件对象

        toParent是自定义事件,自定义事件实现了子组件与父组件的通讯

        给子组件绑定自定义事件,如果有传参,那么()接受参数的名字必须是$event,此时$event不再是时间对象,而是变成了传进来的参数内容,回调函数中的事件对象可以不传递,默认为event,并且名字不可改变

        如果加上 .native事件修饰符,就会变为原生事件,即便子组件中有$emit自定义事件操作,但是父组件中的事件仍旧会以“vue的原生事件”为优先,原生事件的优先级高于自定义事件

        注意:事件绑定的名称必须是click,才会是原生事件,自己定义的名称不生效

<CustomChild @toParent="toParentEvent($event)"/>
toParentEvent(a){
// 这里的形参(event)是子组件传过来的参数,而不是event事件对象
// 如果传递参数,$event不再是事件对象,而是变成了eventArguments参数内容

// event事件对象可以直接获得
console.log("toParentEvent",event,a)
}

父组件 src->App.vue

<template>
<!-- 1-视图层 -->
  <div class="todo-container">
    <div class="todo-wrap">
      <Header  ref="head"/>
      <List 
      :todos="todos" 
      :deleteTodo="deleteTodo"
      :updataTodo="updataTodo"
      />
      <Footer :todos="todos" :updataAll="updataAll" :deleteAll="deleteAll"/>

      <!-- 绑定的是HTML当中的button元素,通过v-on进行事件的绑定 -->
      <!-- 在这里的事件对象是 $event ,与其他实参的顺序可以任意变换 -->
      <button @click="EventClick('传递的实参',$event)">Vue中的DOM原生事件</button>

      <!-- 直接给自定义组件绑定点击事件( @click="ChildClick" )并没有触发 -->
      <!-- 需要给click增加native修饰符 native:本地的 -->
      <!-- @click.native 时事件会变为原生事件,会将事件绑定到子组件的根元素上,这时点击子组件的所有元素都会触发事件,因为产生了冒泡 -->
      <Child @click.native="ChildClick($event,'传递的实参')"/>

      <!-- v-on也可以监听事件 -->
      <!-- 父组件中, 利用v-on进行事件的监听操作,可以不传递参数,也可以不加(),那么回调函数中的event就是默认的事件对象 -->
      <!-- toParent是自定义事件,自定义事件实现了子组件与父组件的通讯 -->
      <CustomChild @toParent="toParentEvent($event)"/>
    </div>
  </div>
</template>

<script>
// 2-逻辑层
import Header from "@/components/Header"
import Footer from "@/components/Footer"
import List from "@/components/List"
import Child from "@/components/Child"
import CustomChild from "@/components/CustomChild"
export default {
  name: "App",
  data(){
    return {
      // 拿到localStorage的todos,把字符串转为对象
      // 因为一开始todos是没有值的,为null,所以需要设置为空数组
      todos:JSON.parse(localStorage.getItem("todos")) || [],
    }
  },
  components:{
    Header,
    Footer,
    List,
    Child,
    CustomChild
  },
  methods:{
    toParentEvent(a){
      // 这里的形参(event)是子组件传过来的参数,而不是event事件对象
      // 如果传递参数,$event不再是事件对象,而是变成了eventArguments参数内容

      // event事件对象可以直接获得
      console.log("toParentEvent",event,a)
    },
    EventClick(a,b){
      // ! event这个事件对象是默认的,在进行事件绑定的时候不管你传还是不传递,都是有event这个事件对象,并且这个event的事件对象名称是固定的,不能随意的改变,只能是 event
      // console.log("EventClick",event)

      console.log(a,b)  // a或者b接收实参传递的$event,看$event的位置
    },
    ChildClick(event,arg){
      // event传不传都有
      console.log("ChildClick",event,arg)
    },



    // 添加数据
    addTodo(todo){
      this.todos.unshift(todo)
    },
    // 删除数据
    deleteTodo(index){
      this.todos.splice(index, 1)
    },
    // 修改数据
    updataTodo(index){
      this.todos[index].isOver=!this.todos[index].isOver
    },
    // 点击全部更改所有按钮
    updataAll(val){
      this.todos.forEach(item=>(item.isOver=val))
    },
    // 清除已完成任务
    deleteAll(){
      // 设置一个新数组,将原来isOver为true的元素过滤掉
      this.todos=this.todos.filter(item=>item.isOver===false)
    }
  },
  watch:{
    todos:{
      handler(newVal, oldVal){
        // 监听todos,把他转为字符串,存储到localStorage
        localStorage.setItem("todos",JSON.stringify(newVal));
      },
      immediate:true,
      deep:true
    }
  },
  mounted(){
    this.$refs.head.$on("addTodo",this.addTodo)
  },
  beforeDestroy(){
    //  如果撤离销毁了组件,取消监听
    this.$refs.head.$off("addTodo")
  }
};
</script>

子组件 src->components->CustomChild.vue

template里使用emit可以不加this,第一个参数是监听函数的名字,第二个参数是传递过去的参数

<template>
  <div>
    <!-- 子组件发射事件,父组件监听事件 -->
    <!-- 子组件中,通过 $emit 向父组件进行一个事件的发射,叫eventName,并且附带上自定义的参数叫 eventArguments -->
    <!-- toParent是自定义事件,他也可以写成click,但是他和原生事件是不同的,是自定义事件 -->
    <button @click="$emit('toParent','CustomChild的emit事件')">子组件向父组件发射事件</button>
  </div>
</template>

<script>
export default {
    name:"CustomChild"
}
</script>

<style>

</style>

子组件 src->components->Child.vue

<template>
  <div>
    <h1>子组件</h1>
    <p>子组件的内容</p>
  </div>
</template>

<script>
export default {
    name:"Child"
}
</script>

<style>

</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值