03: vuejs 事件、模板、过滤器
目录:Vue其他篇
目录:
1.1 事件 返回顶部
1、说明
1. 绑定事件的两种方法:
<button @click="showMsg">按钮</button>
<button v-on:click="test('123', true, color, $event)">新的按钮</button> <!-- $event 传递事件对象 -->
2. 回调函数在vue的methods属性中定义,如果参数集合()没有定义,回调函数有一个默认参数 this
3. 作用域是vue实例化对象,所以在回调函数中,可以通过this访问vue上的数据
4. 所以methods中定义的方法,可以在methods,以及computed等方法中使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <button @click="showMsg">按钮</button> <button v-on:click="test('123', true, color, $event)">新的按钮</button> <!-- $event 传递事件对象 --> </div> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> // 定义vue实例化对象 var app = new Vue({ el: '#app', data: { color: 'red' }, // 回调函数定义在methods属性中 methods: { // 每一个属性代表一个方法 showMsg: function() { console.log(this ,arguments) }, // 定义回调函数 test: function() { console.log(this, arguments) // arguments = ["123", true, "red", MouseEvent] } } }) </script> </body> </html>
2、事件冒泡和默认行为
事件冒泡:当内存外层都绑定 如 点击事件时,只让最内层事件执行
默认行为:如 a 标签点击默认会跳转到 href 地址中,然其点击后不跳转
一次触发:<button @click.once="print"> 只触发一次 </button>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件冒泡和默认行为</title> <script src="js/vue.js"></script> <script> window.onload=function(){ let vm=new Vue({ el:'#itany', methods:{ show(){ console.log(111); // e.stopPropagation(); }, print(){ console.log(222); }, write(){ console.log(333); }, study(){ console.log(444); // e.preventDefault(); } } }); } </script> </head> <body> <div id="itany"> <div @click="write"> <p @click="print"> <!-- <button @click="show($event)">点我</button> --> <button @click.stop="show">点我</button> </p> </div> <hr> <!-- <a href="#" @click="study($event)">俺是链接</a> --> <a href="#" @click.prevent="study">俺是链接</a> </div> </body> </html>
3、事件修饰符(监控enter、up、down等键盘)
1. 绑定键盘事件的时候,经常会判断按键,通过 e.keyCode
2. 事件修饰符语法 v-on:keyup.修饰符=”回调函数()”,表示,当按下的键是修饰符的时候才会触发
3. 在vue中常见的有9个 esc, tab, space, enter, delete, up,down,left,right
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <input type="text" @keyup.enter="showValue"> <h1>{{msg}}</h1> </div> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> // 定义vue实例化对象 var app = new Vue({ el: "#app", data: { msg: '' }, methods: { showValue: function(e) { // console.log(e.target.value) // 判断点击回车键 // if (e.keyCode === 13) { // // 作用域是vue实例化对象 // this.msg = e.target.value // } console.log(1111); this.msg = e.target.value; // e.target.value 获取的是输入框的值 } } }) </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>键盘事件</title> <script src="js/vue.js"></script> <script> /** * 自定义键位别名 */ Vue.config.keyCodes={ a:65, f1:112 } window.onload=function(){ let vm=new Vue({ el:'#itany', methods:{ show(e){ console.log(e.keyCode); if(e.keyCode==13){ console.log('您按了回车'); } }, print(){ // console.log('您按了回车'); // console.log('您按了方向键上'); console.log('11111'); } } }); } </script> </head> <body> <div id="itany"> <!-- 键盘事件:@keydown、@keypress、@keyup --> <!-- 用户名:<input type="text" @keydown="show($event)"> --> <!-- 简化按键的判断 --> <!-- 用户名:<input type="text" @keydown="show($event)"> --> <!-- 用户名:<input type="text" @keydown.13="print"> --> <!-- 用户名:<input type="text" @keydown.enter="print"> --> <!-- 用户名:<input type="text" @keydown.up="print"> --> 用户名:<input type="text" @keydown.f1="print"> <!-- 事件修饰符 --> <button @click.once="print">只触发一次</button> </div> </body> </html>
4、事件修饰符
.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。
<template> <button @click="submit()" :disabled="isDisable">点击</button> </template> <script> export default { name: 'TestButton', data: function () { return { isDisable: false } }, methods: { submit() { this.isDisable = true setTimeout(() => { this.isDisable = false }, 1000) } }, } </script>
5、事件绑定常用方法
'''一:鼠标事件''' # click 当用户点击某个对象时调用的事件句柄。 # contextmenu 在用户点击鼠标右键打开上下文菜单时触发 # dblclick 当用户双击某个对象时调用的事件句柄。 # mousedown 鼠标按钮被按下。 # mouseenter 当鼠标指针移动到元素上时触发。 # mouseleave 当鼠标指针移出元素时触发 # mousemove 鼠标被移动。 # mouseover 鼠标移到某元素之上。 # mouseout 鼠标从某元素移开。 # mouseup 鼠标按键被松开。 '''二:键盘事件''' # keydown 某个键盘按键被按下。 # keypress 某个键盘按键被按下并松开。 # keyup 某个键盘按键被松开。
1.2 模板 返回顶部
1、简介
Vue.js使用基于HTML的模板语法,可以将DOM绑定到Vue实例中的数据
模板就是{{}},用来进行数据绑定,显示在页面中,也称为Mustache语法
2、数据绑定的方式
a.双向绑定
v-model
b.单向绑定
方式1:使用两对大括号{{}},可能会出现闪烁的问题,可以使用v-cloak解决
方式2:使用v-text、v-html
3、其他指令
v-once 数据只绑定一次
v-pre 不编译,直接原样显示
官网指令: https://cn.vuejs.org/v2/api/#v-once
1.3 自定义过滤器 返回顶部
1、说明
1. 在vue升级之后,vue不建议使用过滤器,而是用插值表达式,或者动态数据绑定替换
2. 使用过滤器的目的是为了在组件间复用处理数据的业务逻辑
3. Vue类中存在一个静态方法filter方法,用来定义过滤器
2、使用过滤器(过滤器定义必须在实例化vue对象前)
1. 语法 {{数据 | 过滤器名称 参数1 参数2 参数3 | 过滤器2 参数2}}
2. 可以使用多个过滤器,前一个过滤器的输出将作为后一个过滤器的输入
3. 2.0版本的改动 {{数据 | 过滤器(参数1, 参数2)}} (2.0版本对过滤器的传参做了改动)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <p> price: 数据 currency: 过滤器名称 ¥和3:表示传递的参数 </p> <h1>{{price | currency('¥', 3)}}</h1> </div> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> /** * 自定义过滤器 * currency 过滤器名称 * @price 价格 * @sign 价格标志 * @len 小数位保留的长度 **/ Vue.filter('currency', function(price, sign, len) { // 从第二个开始才是传递的参数 price = Math.abs(price); // 保证是正数 sign = sign || '¥'; // 默认为人命币标志 len = len || 2; // 默认保留两位小数 var arr = String(parseInt(price)).split(''); // arr = ["1", "2", "3", "4", "5", "6", "7", "8", "9"] for (var i = arr.length - 3; i > 0; i -= 3) { // 添加了成员后面的位置变了,所以从后向前遍历,首位不能添加 arr.splice(i, 0, ',') // i(插入的索引位置);0(删除0个字符串); ','(添加的符合) } // for循环后 arr = [1, 2, ',', 3, 4, 5, ',', 6, 7, 8] return sign + arr.join('') + (price - parseInt(price)).toFixed(len).slice(1) // 转化成小数 原数字减去整数 保留len位小数,去掉整数部分 // toFixed(len) 保留len位小数(得到结果是字符串) // 0.23456.toFixed(3) = "0.235" "'0.235'.slice(1) = ".235" }); new Vue({ el: '#app', data: { price: 1234567891.1234567, msg: 'a hot day' } }) </script> </body> </html>
1.4 过度 返回顶部
1、说明
1. 在元素切换状态的时候(例如:元素的显隐),我们可以为元素添加动画
2. Transition属性:Vue会根据属性值自动创建三个css类,例如 transition=“demo”
demo-transition: 定义过渡的
demo-enter 进入样式
demo-leave 移出样式
3. 注意:2.0类的名称变了
.demo-transition => .demo-enter-active, .demo-leave-active
.demo-enter => .demo-enter
.demo-leave => .demo-leave-to
Transition属性 变成了 transition组件了,通过name定义过渡名称
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .demo { width: 100px; height: 100px; margin-top: 20px; background: green; } /*定义过渡*/ .demo-enter-active, .demo-leave-active { transition: all 1s; } /*定义进场动画和出场动画*/ .demo-enter, .demo-leave-to { width: 0; height: 0; opacity: 0; } </style> </head> <body> <div id="app"> <button v-on:click="toggle">切换显隐</button> <transition name="demo"> <div class="demo" transition="demo" v-if="isShow">这是内容</div> </transition> </div> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> // 定义vue实例化对象 var app = new Vue({ el: '#app', data: { isShow: true }, methods: { toggle: function() { // 切换isShow this.isShow = !this.isShow; } } }) </script> </body> </html>
1.5 支付宝注册 返回顶部
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> * { margin: 0; padding: 0; list-style: none; } body { background: #ccc; } #app { width: 800px; margin: 50px auto; border: 1px solid #ccc; background: #fff; height: 600px; padding-top: 80px; } label { margin-left: 100px; margin-right: 20px; } input { padding: 8px 15px; width: 300px; } ul { width: 330px; margin-left: 176px; border: 2px solid #ccc; margin-top: -1px; } ul li { padding: 0 15px; height: 26px; line-height: 26px; } ul li:hover, ul li.hover { background: #efefef; } </style> </head> <body> <div id="app"> <label>账户名</label> <input type="text" v-model="msg" @keydown.up="showPrevLi" @keyup.down="showNextLi" @keyup.enter="chooseLi" > <!-- ul的显示与msg有关 --> <ul v-show="msg"> <li v-for="item in dealMail" v-on:click="chooseCurrentLi">{{dealMsg}}@{{item}}.<template v-if="item == 189">cn</template><template v-else>com</template></li> </ul> </div> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> // 创建vue实例化对象 var app = new Vue({ el: '#app', data: { // 定义绑定的数据 msg: '', num: -1, isFirst: true, // 是否是第一次 email: ['qq', 163, 126, 189, 'sina', 'hotmail', 'gmail', 'sohu', '21cn'] }, // 动态数据绑定 computed: { dealMsg: function(vue) { // 处理msg, 截取@符号之前的 if (this.msg.indexOf('@') >= 0){ // 是否存在@ // 截取@符号之前的,不包括@, slice, substring, substr, 哪个参数表示长度,出现负数,第一个参数大于第二个参数怎么办,李鹏涛 return this.msg.slice(0, this.msg.indexOf('@')) } return this.msg // 否则返回msg }, // 过滤mail集合 dealMail: function() { if (this.msg.indexOf('@') > 0) { // 判断是否包含@, 包含@,根据@符号后面的内容过滤 var str = this.msg.slice(this.msg.indexOf('@') + 1); // 截取@后面的内容 var result = []; // 过滤email集合 for (var i = 0; i < this.email.length; i++) { // 遍历email找到符号条件的 var mail = this.email[i] + (this.email[i] == 189 ? '.c' : '.co'); // 每一个成员要带上后缀,例如sina => sina.co if (mail.indexOf(str) === 0) { // 什么成员符合条件:以str开头, result.push(this.email[i]) // 存储这个成员 } } return result; // 返回过滤的结果 }else { return this.email // 不包含,直接返回email } } }, // 定义事件回调函数 methods: { chooseCurrentLi: function(e) { // 点击li,然后选中li var val = e.target.innerHTML; // 获取li的内容 this.msg = val; // 更新msg }, // 点击向上键,显示前一个li showPrevLi: function(e) { e.preventDefault(e); // 阻止默认行为 if (this.isFirst) { // 如果是第一次,不用减了 this.isFirst = false; // 这次过去了,就不是第一次了 } else { this.num--; } this.changeCurrentLiStyle(); // 更新li的样式 }, // 点击向下键,显示后一个li showNextLi: function() { this.num++; // 更改num this.changeCurrentLiStyle(); // 更新li的样式 this.isFirst = false; // 第一次已经过去了 }, getNum: function(len) { // 获取num对应的li的索引值 // 对于任意一个数(正数和负数) // 对len取余之后,保证在-len到len之间 // var num = this.num % len; // // 此时加上len,保证是0到2*len之间,一定是正数了 // num += len; // // 此时再取余,就保证是0到len之间了 // num %= len return (this.num % len + len) % len; }, // 改变当前li的样式 changeCurrentLiStyle: function() { var lis = this.$el.getElementsByTagName('li'); // 获取所有的li if (lis.length === 0) { // 判断li是否存在 return; } var num = this.getNum(lis.length); // 获取索引值 for (var i = 0; i < lis.length; i++) { // 排他法设置类 lis[i].className = ''; } lis[num].className = 'hover'; // 当前li选中 }, // 点击enter键,显示当前li chooseLi: function() { var lis = this.$el.getElementsByTagName('li'); // 获取对应的li if (lis.length === 0) { // 判断li是否存在 return; } var num = this.getNum(lis.length); // 获取索引值 var value = lis[num].innerHTML; // 获取li的值 this.msg = value; } } }) </script> </body> </html>
作者:学无止境
出处:https://www.cnblogs.com/xiaonq
生活不只是眼前的苟且,还有诗和远方。