【Vue.js】Vue.js中的事件处理、过滤器、过渡和动画、组件的生命
【Vue.js】Vue.js中的事件处理、过滤器、过渡和动画、组件的生命
【Vue.js】Vue.js中的事件处理、过滤器、过渡和动画、组件的生命周期及组件之间的通信事件绑定监听
- v-on:xxx=“func”
- @xxx=“func”
- @xxx=“func(参数)”
参数
- 默认事件形参:event
- 隐含属性对象:
$event
(在原生事件中,$event
是事件对象,在自定义事件中,$event是传递过来的数据)
事件修饰符
- .prevent:阻止事件的默认行为 event.preventDefault()
- .stop:停止事件冒泡 event.stopPropagation()
按键修饰符
- .keycode:操作的是某个keycode值的键
- .enter:操作的是enter键
- .tab:操作的是tab键
- .delete:操作的是“删除”和“退格”键
- .esc:操作的是ESC键
- .space:操作的是空格键
- .up:键抬起
- .down:键按下
- .left:操作的是左箭头
- .right:操作是是右箭头
示例代码
## DealEvents.vue <template> <div> <button @click="clickBtn('撩课', $event)">点我</button> <h3>事件修饰符</h3> <a href="http://www.itlike.com" @click.prevent="aClick">撩课</a> <div style="width: 100px; height: 100px; background-color:red;" @click="divClick"> <button @click.stop="btnClick">点我</button> </div> <h3>按键修饰符</h3> <input type="text" @keyup.enter="dealKey"> </div> </template> <script> export default { name: "DealEvents", methods:{ clickBtn(args, event){ console.log(args); console.log(event); }, aClick(){ alert(0); }, btnClick(){ alert('点击了里面的按钮'); }, divClick(){ alert('点击了父标签'); }, dealKey(event){ console.log(event['keyCode']); } } } </script> <style scoped> </style>
## App.vue <template> <div id="app"> <DealEvents /> </div> </template> <script> import DealEvents from './components/DealEvents' export default { name: 'app', components: { DealEvents } } </script> <style> </style>
概念
- 对要显示的数据进行特定格式化后再显示
- 并没有改变原本的数据, 而是产生新的对应的数据
定义过滤器
- 全局定义
// 注册全局过滤器 Vue.filter('totalMonetFormat', (value)=>{ return '¥' + Number(value).toFixed(3); });
- 局部定义
filters: { moneyFormat(value) { return '¥' + Number(value).toFixed(2); }, timeFormat(value, format='YYYY-MM-DD HH:mm:ss'){ return moment(value).format(format); } }
使用过滤器
<template> <div> <h3>格式化人民币</h3> <p>局部过滤:{{money | moneyFormat}}</p> <p>局部过滤:{{page | moneyFormat}}</p> <p>全局过滤:{{money | totalMonetFormat}}</p> <p>全局过滤:{{page | totalMonetFormat}}</p> <p>------------------------------------------------</p> <h3>格式化日期</h3> <p>{{time | timeFormat}}</p> <p>{{time | timeFormat('YYYY-MM-DD')}}</p> <p>{{time | timeFormat('HH:mm:ss')}}</p> </div> </template>
示例代码
## main.js import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false; // 注册全局过滤器 Vue.filter('wholeMoneyFormat', (value)=>{ return '¥' + Number(value).toFixed(4); }); new Vue({ render: h => h(App), }).$mount('#app');
## LkFilters.vue <template> <div> <h3>格式化人民币</h3> <p>{{money | moneyFormat}}</p> <p>{{page | moneyFormat}}</p> <p>---------------------------------------------</p> <p>{{money | wholeMoneyFormat}}</p> <p>{{page | wholeMoneyFormat}}</p> <h3>格式化日期</h3> <p>{{time | timeFormat}}</p> <p>{{time | timeFormat('YYYY-MM-DD')}}</p> <p>{{time | timeFormat('HH:mm:ss')}}</p> </div> </template> <script> import moment from 'moment' export default { name: "LkFilters", data(){ return { money: 22345, page: 189.4345, time: new Date() } }, mounted(){ setInterval(()=>{ this.time = new Date() }, 1000) }, // 局部过滤器 filters: { moneyFormat(value){ return '¥' + Number(value).toFixed(2); }, timeFormat(value, format='YYYY-MM-DD HH:mm:ss'){ return moment(value).format(format); } } } </script> <style scoped> </style>
## App.vue <template> <div id="app"> <LkFilters /> </div> </template> <script> import LkFilters from './components/LkFilters' export default { name: 'app', components: { LkFilters } } </script> <style> </style>
概念
- vue通过操作 css 的 trasition 或 animation可以给特定的目标元素添加/移除特定的 class
过渡的相关类名
- xxx-enter/xxx-leave-to:指定隐藏时的样式
- xxx-enter-active: 指定显示的 transition
- xxx-leave-active: 指定隐藏的 transition
操作步骤
- 在目标元素外包裹
<transition name="xxx">
- 定义class样式:指定过渡样式(transition),指定隐藏时的样式(opacity/其它)
示例代码
## TransitionAndAnimate.vue <template> <div> <button @click="show = !show">切换</button> <transition name="fade"> <div class="box" v-if="show">撩课学院</div> </transition> </div> </template> <script> export default { name: "TransitionAndAnimate", data(){ return { show: false } } } </script> <style scoped> .box{ width: 200px; height: 200px; background-color: red; color: #fff; font-size: 20px; display: flex; justify-content: center; align-items: center; } .fade-enter, .fade-leave-to{ opacity: 0; transform: translateX(200px) scale(3); } .fade-enter-active, .fade-leave-active{ transition: all 2s ease-in-out; } </style>
## TransitionAndAnimateTwo.vue <template> <div> <button @click="flag = !flag">切换</button> <p></p> <transition name="bounce"> <img v-if="flag" :src="pic" </transition> </div> </template> <script> import pic from '@/assets/img_02.jpg' export default { name: "TransitionAndAnimateTwo", data() { return { pic: pic, flag: false } } } </script> <style scoped> .bounce-enter-active { animation: bounce 1s; } .bounce-leave-active { animation: bounce 1s reverse; } @keyframes bounce { 0% { transform: scale(0); } 25% { transform: scale(0.2); } 50% { transform: scale(0.4); } 75% { transform: scale(0.6); } 100% { transform: scale(1); } } </style>
## TransitionAndAnimateThree.vue <template> <div> <button @click="flag = !flag">切换</button> <p></p> <transition enter-active-class="animated rollIn" leave-active-class="animated rollOut" :duration="{ enter: 1000, leave: 500 }" > <img v-if="flag" :src="pic" </transition> </div> </template> <script> import pic from '@/assets/img_02.jpg' import animate from 'animate.css' export default { name: "TransitionAndAnimateThree", data() { return { pic: pic, flag: false } } } </script> <style scoped> </style>
## App.vue <template> <div id="app"> <TransitionAndAnimate /> <TransitionAndAnimateTwo /> <TransitionAndAnimateThree /> </div> </template> <script> import TransitionAndAnimate from './components/TransitionAndAnimate' import TransitionAndAnimateTwo from './components/TransitionAndAnimateTwo' import TransitionAndAnimateThree from './components/TransitionAndAnimateThree' export default { name: 'app', components: { TransitionAndAnimate, TransitionAndAnimateTwo, TransitionAndAnimateThree } } </script> <style> </style>
生命周期图示
钩子函数
- 初始化显示
- beforeCreate()
- created()
- beforeMount()
- mounted()
- 更新状态
- beforeUpdate()
- updated()
- 销毁 vue 实例
- beforeDestory()
- destoryed()
常用的生命周期方法
- created()/mounted():发送ajax请求,启动定时器等异步任务
- beforeDestory():收尾操作,比如: 清除定时器、数据缓存
示例代码
## LifeCycle.vue <template> <div> <p v-if="isShow">{{str1}}</p> <p v-else>{{str2}}</p> <button @click="destory">销毁</button> </div> </template> <script> export default { name: "LifeCycle", beforeCreate(){ console.log('1:beforeCreate()'); }, data(){ return { isShow: false, str1: '撩课学院', str2: 'itLike.com' } }, methods:{ destory(){ this.$destroy(); } }, created() { console.log('2:created()'); }, beforeMount() { console.log('3:beforeMount()'); }, mounted() { console.log('4:mounted()'); // 定时器 this.intervalId = setInterval(()=>{ console.log('+++++++++++---++++++++++'); this.isShow = !this.isShow; }, 1000); }, beforeUpdate() { console.log('5:beforeUpdate()'); }, updated() { console.log('6:updated()'); }, beforeDestroy() { console.log('7:beforeDestroy()'); // 清除定时器 clearInterval(this.intervalId); }, destroyed() { console.log('8:destroyed()'); } } </script> <style scoped> </style>
## App.vue <template> <div id="app"> <LifeCycle /> </div> </template> <script> import LifeCycle from './components/LifeCircle' export default { name: 'app', components: { LifeCycle } } </script> <style> </style>
通信基本原则
- 不要在子组件中直接修改父组件的状态数据
- 数据和处理数据的函数应该在同一模块内
组件通信常用方式
- props
- 自定义事件
- 消息订阅与发布
- vuex
组件通信方式1:props
- 在组件内声明所有的 props:
- 只指定名称:
props: ['name', 'age', 'logDog']
- 指定名称和类型
props: { name: String, age: Number, logDog: Function }
- 指定名称、类型、必要性、默认值
props: { name: {type: String, required: true, default:xxx}, }
- 使用注意
- 此方式用于父组件向子组件传递数据
- 所有标签属性都会成为组件对象的属性,模板页面可以直接引用
- 存在缺陷:
(1)如果需要向非子后代传递数据必须多层逐层传递
(2)兄弟组件间也不能直接 props 通信, 必须借助父组件才可以
代码示例
## PropsComponent.vue <template> <div> <h4>姓名:{{name}}</h4> <h4>年龄:{{age}}</h4> <p>{{person}}</p> <button @click="logPerson('大撩撩', 60)">调用方法</button> </div> </template> <script> export default { name: "PropsComponent", // props: ['name', 'age'] /* props: { name: String, age: Number, person: Object, logPerson: Function } */ props: { name: {type: String, required: true, default: '撩课'}, age: {type: Number, required: true, default: 20}, person: Object, logPerson: Function } } </script> <style scoped> </style>
App.vue <template> <div id="app"> <PropsComponent :age=25 :person="p" :log-person="logPerson" /> </div> </template> <script> import PropsComponent from './components/PropsComponent' export default { name: 'app', data(){ return { p: { name: '张三丰', age: 600 } } }, components: { PropsComponent }, methods: { logPerson(name, age){ alert(`姓名:${name}, 年龄:${age}`); } } } </script> <style> .word{ width: 300px; height: 200px; background-color: red; color: #fff; display: flex; justify-content: center; align-items: center; } </style>
组件通信方式2:自定义事件
- 绑定事件监听:
<button @click="btnClick">删除父标签P</button> this.$emit('btnClick', {name: '小撩', age: 25, sex:'女'});
- 触发事件:
<CustomEvents @btnClick="deleteP"/> deleteP(args){ console.log(args); this.$refs.word.remove(); }
- 指定名称、类型、必要性、默认值:
props: { name: {type: String, required: true, default:xxx}, }
- 使用注意
- 此方式只用于子组件向父组件发送消息或数据
- 隔代组件或兄弟组件间通信此种方式不合适
代码示例
## CustomEvents.vue <template> <div> <button @click="btnClick">删除父组件的P标签</button> </div> </template> <script> export default { name: "CustomEvents", methods: { btnClick(){ // 告诉父组件,我点击了按钮 this.$emit('btnClick', {name: '哈哈哈', sex:'男'}); } } } </script> <style scoped> </style>
## App.vue <template> <div id="app"> <CustomEvents @btnClick="deleteP"/> <p ref="word" class="word">我是即将被删除的</p> </div> </template> <script> import CustomEvents from './components/CustomEvents' export default { name: 'app', data(){ return { } }, components: { CustomEvents }, methods: { deleteP(args){ console.log(args); this.$refs.word.remove(); } } } </script> <style> .word{ width: 300px; height: 200px; background-color: red; color: #fff; display: flex; justify-content: center; align-items: center; } </style>
组件通信方式3:PubSub 发布订阅
- 安装:
>> npm install --save pubsub-js
- 引入:
import PubSub from ‘pubsub-js’
- 界面操作:
// 发布删除P标签消息 PubSub.publish("delete-p", {name:"大撩撩", sex:"女", age: 45}); // 订阅关闭弹窗事件,参数event指"delete-p" PubSub.subscribe("delete-p", (event, data) => { console.log(data); // 删除P标签 this.deleteP(); });
- 此方式可实现任意关系的组件间通信,交换数据
【Vue.js】Vue.js中的事件处理、过滤器、过渡和动画、组件的生命相关教程
-
微软预览word_如何解决Microsoft Word中的打印问题
微软预览word_如何解决Microsoft Word中的打印问题 微软预览word ( Basic Checks ) First, it’s a good idea to do some basic hardware checks to ensure everything is hooked up as it should be. 首先,最好进行一些基本的硬件检查,以确保一切都按预期
-
【Git 使用笔记】第四部分:git在公司中的开发流程
【Git 使用笔记】第四部分:git在公司中的开发流程 为什么80%的码农都做不了架构师? 先声明几个变量 仓管A:主分支,只有master分支 仓管B:开发分支,只有各个业务开发分支 仓管B fork 于 A 如下图 为了保证 代码的稳定性,只有 仓管B中的某个分支测试完毕
-
框架源码专题:Spring的事件监听、发布机制
框架源码专题:Spring的事件监听、发布机制 文章目录 1.Spring内置事件 2.自定义事件 3.事件监听器 4.事件发布 publishEvent 4.Spring事件原理 Spring内置事件是Spring在内部帮我们写好的事件,在使用时,不需要重写他们,只需在容器中注入重写后的监听器即可
-
4.6嵌入式开发中的c语言(上)
4.6嵌入式开发中的c语言(上) 文章目录 数据类型 c语言位操作 变位 清0 左移 右移 判断条件 嵌入式中~位取反 range范围 delay延时可以用for循环,delay一个固定时间 技术教程图 这是错误永远出字节四不了循环体到255归0 在做通讯协议,包头 包尾 校验位 不
-
事件冒泡、事件委托和事件捕获
事件冒泡、事件委托和事件捕获 事件冒泡会从当前触发的事件目标一级一级往上传递,依次触发,直到document为止。 事件捕获会从document开始触发,一级一级往下传递,依次触发,直到真正事件目标为止。 事件委托依靠的就是事件冒泡和捕获的机制。 一个很简单的
-
【LeetCode每日一题】[简单]501. 二叉搜索树中的众数
【LeetCode每日一题】[简单]501. 二叉搜索树中的众数 【LeetCode每日一题】[简单]501. 二叉搜索树中的众数 501. 二叉搜索树中的众数 题目来源 算法思想:树,中序遍历 题目: /** * Definition for a binary tree node. * public class TreeNode { * int val;
-
浅析STL算法中的堆排序
浅析STL算法中的堆排序 堆结构简述 了解过数据结构的人,应该对堆结构不陌生,堆的底层是使用数组来实现的,但却保持了二叉树的特性。堆分为两种,最大堆和最小堆,以最大堆为例,最大堆保持了根结点大于两个左右两个孩子,同时所有子树一次类推。由于堆底层
-
Vue.js - Echarts的简单封装应用
Vue.js - Echarts的简单封装应用 @Author: 雨 雨 @Date: 2020-09-24T15:44:54+08:00 @Email: [emailprotected] @Last modified by: S_Y template div class=container div style=width:100%;height:500px; class=echarts :id=id/div /div/templatescriptimpor