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>