一.事件处理器
1.什么是事件处理?
在 Vue 中,事件处理指的是将特定的DOM事件与对应的处理函数进行绑定,当事件触发时,相应的处理函数将被执行,从而实现对用户交互操作的响应。
Vue 通过
v-on
指令(或简写符号@
)来绑定事件处理函数到DOM元素上
2.事件冒泡
事件冒泡(Event Bubbling)是指在DOM结构中,当一个元素上的事件被触发时,该事件将会向父元素(包括祖先元素)逐级传播,直到根节点。这样设计的目的是为了简化事件的处理和管理。
具体来说,当一个元素触发某个事件时,比如点击事件(click),该事件首先在触发元素上被执行,然后事件会依次在其父元素上执行,再在父元素的父元素上执行,一直向上直到根节点。这种向上传播的过程就是事件冒泡
2.1基础代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script> <!-- 1.导入vue在线依赖--> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <title>事件处理器</title> <style type="text/css"> .a{ background-color: aqua; width: 400px; height: 400px; } .b{ background-color: red; width: 300px; height: 300px; } .c{ background-color: yellow; width: 200px; height: 200px; } .d{ background-color: green; width: 100px; height: 100px; } </style> </head> <body> <div id="app"> <div class="a" @click="fun1"> <div class="b" @click="fun2"> <div class="c" @click="fun3"> <div class="d" @click="fun4"> </div> </div> </div> </div> </div> <!-- 构建vue实例,绑定实例 --> <script type="text/javascript"> new Vue({ el:"#app", data(){ return { msg:'刘兵要上百星王者' , }; },methods:{ fun1(){ alert("fun1") }, fun2(){ alert("fun2") }, fun3(){ alert("fun3") }, fun4(){ alert("fun4") }, } }); </script> </body> </html>
效果图
这一次点击一个颜色就会弹出所有个下拉框
2.2解决办法(.stop)
效果图展示
这一次点击一个颜色就会弹出一个下拉框
3.限制次数点击(.once)
3.1代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script> <!-- 1.导入vue在线依赖--> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <title>事件处理器</title> </head> <bod <input :value="msg" /> <button @click="clickMe">吱吱吱吱</button> </div> <!-- 构建vue实例,绑定实例 --> <script type="text/javascript"> new Vue({ el:"#app", data(){ return { msg:'刘兵要上百星王者' , }; },methods:{ clickMe(){ console.log(this.msg) } } }); </script> </body> </html>
效果图
3.2修改代码
效果图
4.事件修饰符
事件修饰符
Vue通过由点(.)表示的指令后缀来调用修饰符,
.stop
.prevent
.capture
.self
.once
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>
<!-- click 事件只能点击一次 -->
<a v-on:click.once="doThis"></a>
二.表单的综合案例
1.取值,和绑定值
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <title>表单的综合案例</title> </head> <body> <div id="app"> 姓名:<input v-model="form.name" /><br /> 密码:<input v-model="form.password" type="password" /><br /> 性别: <div v-for="sex in sexList"> <input type="radio" name="sex" v-model="form.sex" :value="sex.id" />{{sex.name}} </div> 籍贯: <select name="address" v-model="form.address"> <option value="">请选择</option> <option v-for="addr in addressList" :value="addr.id">{{addr.name}}</option> </select><br /> 爱好: <span v-for="hobby in hobbyList"> <input type="checkbox" v-model="form.hobbies" :value="hobby.id" />{{hobby.name}} </span><br /> 个人简介:<textarea v-model="form.intro" rows="5"></textarea><br /> 同意:<input type="checkbox" v-model="form.agree" /><br /> <button v-if="form.agree" @click="submitForm">提交</button> </div> <script type="text/javascript"> new Vue({ el: '#app', data() { return { sexList: [ {id: 1, name: '男'}, {id: 2, name: '女'}, {id: 3, name: '保密'} ], hobbyList: [ {id: 1, name: '王者'}, {id: 2, name: '吃鸡'}, {id: 3, name: 'cf'}, {id: 4, name: '部落冲突'} ], addressList: [ {id: 1, name: '北京'}, {id: 2, name: '上海'}, {id: 3, name: '广州'}, {id: 4, name: '深圳'} ], form: { name: '刘兵', password: 'wssb', sex: 1, address: '', hobbies: [], intro: '', agree: false } }; }, methods: { submitForm() { console.log(this.form); alert('提交成功'); } } }); </script> </body> </html>
2.展示效果
三.组件通信(主讲自定义事件)
1.组件通信共包括
- Props & Events(父组件向子组件通信):父组件通过props将数据传递给子组件,子组件通过events触发父组件的方法来实现通信。
- 自定义事件(子组件向父组件通信):子组件通过$emit触发自定义事件并传递数据,父组件通过监听子组件的自定义事件来接收数据。
- 中央事件总线(非父子组件通信):创建一个新的Vue实例作为中央事件总线,任何组件都可以通过该实例的emit和on方法进行通信。
- Vuex(大规模应用状态管理):Vuex是Vue官方提供的状态管理库,用于管理共享状态,可在多个组件之间进行通信。
自定义组件
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script> <!-- 1.导入vue在线依赖--> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <title>父传子通信</title> <!-- 2.定义vue所管理的边界(有且只有一个根节点) --> </head> <body> <!-- 2.定义vue所管理的边界(有且只有一个根节点) --> <div id="lz"> <p>自定义组件</p> <my-button>刘兵是狗</my-button> </div> <!-- 构建vue实例,绑定实例 --> <script type="text/javascript"> new Vue({ el:"#lz", components:{ 'my-button':{ template:'<button>刘兵是狗</button>' } }, data(){ return { msg:'刘兵要上百星王者' , }; }, methods:{ function:{ fun1(){ alert(fun1) } } } }) </script> </body> </html>
效果图
2.父传子通信
代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script> <!-- 1.导入vue在线依赖--> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <title>父传子通信</title> <!-- 2.定义vue所管理的边界(有且只有一个根节点) --> </head> <body> <!-- 2.定义vue所管理的边界(有且只有一个根节点) --> <div id="lz"> <p>自定义组件</p> <my-button>刘兵是狗</my-button> <h1>----------------------------</h1> <p>组件通信---父传子</p> <my-button m='lb'>刘兵是狗</my-button> <p>组件通信---父传子(2)</p> <my-button m='nb' n="10">刘兵是狗</my-button> </div> <!-- 构建vue实例,绑定实例 --> <script type="text/javascript"> new Vue({ el:"#lz", components:{ 'my-button':{ template:'<button @click="onclikMe">被点击了{{m}}who{{n}}次</button>', props:['m','n'], data:function(){ return {n:1} }, methods:{ onclikMe(){ this.n++; } } } }, data(){ return { msg:'刘兵要上百星王者' , }; }, methods:{ function:{ fun1(){ alert(fun1) } } } }) </script> </body> </html>
代码分析
Vue实例中的
components
选项定义了一个名为my-button
的自定义组件。这个组件有一个template模板,包含一个按钮元素,按钮上显示了父组件传递过来的属性m
和n
的值。组件还定义了一个data函数,返回一个对象,包含一个属性n
,初始化为1。组件还定义了一个方法onclikMe
,用于处理按钮的点击事件,每次点击时将n
的值加1
3.子传父通信
代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script> <!-- 导入vue在线依赖 --> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <title>子传父通信</title> </head> <body> <div id="lz"> <p>组件通信---子传父</p> <my-button m='lb' @xxx='getParam'>刘兵是狗</my-button> </div> <script type="text/javascript"> Vue.component('my-button', { template: '<button @click="onclickMe">被点击了{{ m }}</button>', props: ['m'], methods: { onclickMe() { let name = "刘兵土狗"; let book = "如何才能成为舔狗"; let price = "1688"; this.$emit('xxx', name, book, price); } } }); new Vue({ el: "#lz", methods: { getParam(a, b, c) { console.log(a, b, c); } } }); </script> </body> </html>
分析
- 在
my-button
组件的methods
选项中,定义了onclickMe
方法。当按钮被点击时,该方法将设置name
为"刘兵土狗",book
为"如何才能成为舔狗",price
为"1688",然后通过this.$emit
方法触发名为xxx
的自定义事件,并传递这三个参数。- 在Vue实例的
methods
选项中,定义了一个名为getParam
的方法。该方法用于处理子组件传递的参数,并在控制台打印输出这三个参数的值。总结:这段代码演示了子组件向父组件传递数据的通信方式。通过自定义组件
my-button
,当按钮被点击时,子组件会通过this.$emit
方法触发一个自定义事件xxx
,并向父组件传递参数name
、book
和price
。父组件通过监听这个自定义事件@xxx
,在事件处理函数getParam
中获取传递的参数进行相应的处理。输出结果通过调用console.log()
方法在浏览器控制台中显示。
效果展示