Vue绑定事件,双向数据绑定,只是循环没那么简单

mac2025-01-10  11

v-on对象处理

<p @mouseover = "doTish" @mouseout = "doThat"> 对象形式 </p> <p v-on="{ mouseover: doTish, mouseout: doThat }"> 对象形式 </p>

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app" > <p v-on="{ mouseover: doTish, mouseout: doThat }">对象形式</p> </div> <script> var vm = new Vue({ el:"#app", methods:{ doTish(){ event.target.style.color = "red"; }, doThat(){ event.target.style.color = "#0f0"; }, }, }) </script> </body> </html>

v-on:keyup监听按键触发常见的按键别名:

'.enter' '.tab' '.delete'(捕获“删除”和“退格”键) '.esc' '.space' '.up' '.down' '.left' '.right'

按键序号网址查询:'http://www.cnblogs.com/wuhua1/p/6686237.html'

Vue.config.keyCodes.f1 = 112

<!-- Ctrl Click --> <div @click.ctrl="doSomething">Do something</div>

<!-- 有且只有 Ctrl 被按下的时候才触发 --> <button @click.ctrl.exact="onCtrlClick">A</button>

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app" > <!--鼠标点击 ctrl 才能触发--> <p @click.ctrl.exact ="doTish">对象形式</p> </div> <script> var vm = new Vue({ el:"#app", methods:{ doTish(){ event.target.style.color = "red"; }, }, }) </script> </body> </html>

事件修饰符

'.stop' -- 阻止事件冒泡 '.prevent' -- 阻止默认事件 '.capture' -- 添加事件侦听器时使用事件捕获模式 '.self' --只当事件在该元素本身(比如不是子元素)触发时触发回调 '.once' --事件只触发一次 'native' -- 给组件绑定点击事件

阻止事件冒泡

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> <style> .inner{ width: 200px; height: 200px; background-color: darkseagreen; } </style> </head> <body> <div class="inner" id="app" @click="divClick"> <input type="button" value="点击" @click.stop="inputClick"> </div> <script> var vm = new Vue({ el:'#app', // data 负责输出理数据的 data:{ }, // methods 负责处理调用方法的 methods:{ divClick(){ console.log("最外层div") }, inputClick(){ console.log("最内层div") } } }) </script> </body> </html>

实现捕获触发事件的机制 -- capture

冒泡是从向外依次触发,使用capture,就变成了从先显示外面,在显示里面

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> <style> .inner{ width: 200px; height: 200px; background-color: darkseagreen; } </style> </head> <body> <div class="inner" id="app" @click.capture="divClick"> <input type="button" value="点击" @click="inputClick"> </div> <script> var vm = new Vue({ el:'#app', // data 负责输出理数据的 data:{}, // methods 负责处理调用方法的 methods:{ divClick(){ console.log("最外层div") }, inputClick(){ console.log("最内层div") } } }) </script> </body> </html>

打印结果最外层div最内层div

只会阻止自己身上冒泡行为 -- self只会阻止自己身上冒泡行为 ,当有多层嵌套的时候,只会阻止有self 冒泡行为

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> <style> .inner{ width: 200px; height: 200px; background-color: darkseagreen; } </style> </head> <body> <div id="app"> <div class="outer" @click="div2Handler"> <div class="inner" @click.self="div1Handler"> <input type="button" value="戳他" @click="btnHandler"> </div> </div> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: {}, methods: { div1Handler() { console.log('这是触发了 inner div 的点击事件') }, btnHandler() { console.log('这是触发了 btn 按钮 的点击事件') }, div2Handler() { console.log('这是触发了 outer div 的点击事件') } } }); </script> </body> </html>

这是触发了 btn 按钮 的点击事件这是触发了 outer div 的点击事件

阻止默认事件 -- prevent1.例如a标签默认事件就是点击跳转页面,为了阻止a标签的默认事件触发我们绑定的事件,可以使用prevent2.图片的默认事件禁止拖拽,如果想给图片设置拖拽效果的话记得做阻止默认行为

<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> <a href="www.baidu.com" @click.prevent.once="linkClick">百度</a> </div> <script> var vm = new Vue({ el:'#app', // data 负责输出理数据的 data:{}, // methods 负责处理调用方法的 methods:{ linkClick:function () { alert(1) } } }) </script> </body> </html>

只触发一次默认行为1.只触一次规定的默认行为2.下面的案例第二次点击就会跳转页面

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> <a href="www.baidu.com" @click.prevent.once="linkClick">百度</a> </div> <script> var vm = new Vue({ el:'#app', // data 负责输出理数据的 data:{}, // methods 负责处理调用方法的 methods:{ linkClick:function () { alert(1) } } }) </script> </body> </html>

阻止事件冒泡 -- stop

事件冒泡从里向外阻止事件冒泡使用stop

v-on -- 方法处理器和内联处理器两者区别写法上,带不带括号

没有括号不支持传参但只带event由于带括号支持传参,但必须$evnet 当参数传入才有evet事件

方法处理器内联处理器

v-model 双向数据绑定

修饰符<input type="text" v-model.lazy="name" /> .lazy :失去焦点同步一次 .number :格式化数字 .trim : 去除首尾空格

checked -- 多选框(用数组接收)

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> 爱好 <br> 足球<input name="text" v-model="msg" type="checkbox" value="foot"> 篮球<input name="text" v-model="msg" type="checkbox" value="bask"> {{msg}} </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { msg:[] }, }); </script> </body> </html>

select --下拉

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> <select v-model="selected"> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select> <span>Selected: {{ selected }}</span> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { selected: 'A', options: [ { text: 'One', value: 'A' }, { text: 'Two', value: 'B' }, { text: 'Three', value: 'C' } ] }, }); </script> </body> </html>

<input v-model.lazy ="msg" > <input type="text" v-on:input="inputHandle" />

v-for -- 循环

支持循环数组|对象|数字|字符串,Array | Object | number | string

数组使用

<p v-for="item,index in items">{{item}}--{{index}}</p>

循环对象

<p v-for="(value,key,index) in items">{{value}}-{{key}}-{{index}}</p> <p v-for="item in 3">{{item}}</p>

对象重新渲染

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> <input v-model="msg.title" type="submit" @click="changeMsg"> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { msg:{}, }, methods:{ changeMsg(){ this.msg.title = "改变" } } }); </script> </body> </html>

怎么保证不在计划内的值也被重新渲染1.调用Vue的静态方法:set2.调用实例上的方法 :$set3.给计划内的对象重新赋值:vm.object = {key:'新的'}4.添加指定属性重新构建赋值:Object.assign()

第一种解决方法 -- set/$set <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> <input v-model="msg.title" type="submit" @click="changeMsg"> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { msg:{}, }, methods:{ changeMsg(){ Vue.set(this.msg, 'title', '新的' ) } } }); </script> </body> </html>

$set ($set 是实例方法因此也是this在内部直接调用) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> <input v-model="msg.title" type="submit" @click="changeMsg"> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { msg:{}, }, methods:{ changeMsg(){ this.$set(this.msg, 'title', '新的' ) } } }); </script> </body> </html>

给计划内的对象重新赋值

vm.object = {key:'新的'} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> <input v-model="msg.title" type="submit" @click="changeMsg"> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { msg:{}, }, methods:{ changeMsg(){ this.msg = {title:"新的"} } } }); </script> </body> </html>

Object.assign({},this.object,{key,value}) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> <input v-model="msg.title" type="submit" @click="changeMsg"> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { msg:{}, }, methods:{ changeMsg(){ this.msg = Object.assign({}, { title: '新的', }) } } }); </script> </body> </html>

数组重新渲染

'push()' 'pop()' 'shift()' 'unshift()' 'splice()' 'sort()' 'reverse()' filter(), concat() 和 slice() ,map() 依旧支持set/$set splice是个好方法会常用

解决vm.items[indexOfItem] = newValue不能被渲染的问题

使用方法set 是Vue静态方法,通过Vue调用使用Vue.set( array, indexOfItem, newValue)

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--导入Vue cdn 的网址--> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> <p v-for="i in msg">{{i}}</p> <input v-model="pushArray"> <button @click="changeMsg">提交</button> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { pushArray:'', msg:['我是', '测试', '数据'], }, methods:{ changeMsg(){ Vue.set(this.msg, 0, this.pushArray); } } }); </script> </body> </html>

splice 是一个好方法

v-for 为什么要配合v-bind:key

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> </head> <body> <div id="app"> <div> <label>Id: <input type="text" v-model="id"> </label> <label>Name: <input type="text" v-model="name"> </label> <input type="button" value="添加" @click="add"> </div> <!-- 注意: v-for 循环的时候,key 属性只能使用 number或者string --> <!-- 注意: key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值 --> <!-- 在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果 v-for 有问题,必须 在使用 v-for 的同时,指定 唯一的 字符串/数字 类型 :key 值 --> <p v-for="item in list" :key="item.id"> <input type="checkbox">{{item.id}} --- {{item.name}} </p> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { id: '', name: '', list: [ { id: 1, name: '李斯' }, { id: 2, name: '嬴政' }, { id: 3, name: '赵高' }, { id: 4, name: '韩非' }, { id: 5, name: '荀子' } ] }, methods: { add() { // 添加方法 this.list.unshift({ id: this.id, name: this.name }) } } }); </script> </body> </html>

若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理。

请点赞!因为你们的赞同/鼓励是我写作的最大动力!

欢迎关注达达的简书!

这是一个有质量,有态度的博客

程序员哆啦A梦 认证博客专家 博客专家 简书万粉优秀创作 掘金优秀作者 我是程序员哆啦A梦,蓝胖子,简书万粉优秀创作者,掘金优秀作者、博客专家,云+社区社区活跃作者,致力于打造一系列能够帮助程序员提高的优质文章。网站@http://www.dadaqianduan.cn
最新回复(0)