【Vue.js】Vue.js中的事件处理、过滤器、过渡和动画、组件的生命周期及组件之间的通信
时间:2022-07-25
本文章向大家介绍【Vue.js】Vue.js中的事件处理、过滤器、过渡和动画、组件的生命周期及组件之间的通信,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1、事件处理
事件绑定监听
- v-on:xxx=“func”
- @xxx=“func”
- @xxx=“func(参数)”
参数
- 默认事件形参: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>
2、过滤器
概念
- 对要显示的数据进行特定格式化后再显示
- 并没有改变原本的数据, 而是产生新的对应的数据
定义过滤器
- 全局定义
// 注册全局过滤器
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>
3、过渡和动画
概念
- 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" alt="">
</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" alt="">
</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>
4、组件的生命周期
生命周期图示
钩子函数
- 初始化显示
- 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>
5、组件之间的通信
通信基本原则
- 不要在子组件中直接修改父组件的状态数据
- 数据和处理数据的函数应该在同一模块内
组件通信常用方式
- 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();
});
- 此方式可实现任意关系的组件间通信,交换数据
- iOS学习——iOS原生实现二维码扫描
- iOS学习——iOS开发小知识点集合
- iOS学习——@class和#import的区别
- iOS学习——UIView的研究
- iOS学习——布局利器Masonry框架源码深度剖析
- iOS项目——自定义UITabBar与布局
- @FeignClient中的@RequestMapping也被Spring MVC加载的问题解决
- Golang语言中Path包用法
- Golang中container/list包中的坑
- 关于Golang语言数组索引的有趣现象
- Golang不定参数
- Go并发编程基础(译)
- go-concurrent-programming.md
- Go语言并发模型:以并行处理MD5为例
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- MySQL 最佳实践:CPU 100%,MySQL 到底在干什么
- 【译】Flutter 1.20 发布
- 算法面试题:一个List,要求删除里面的男生,不用Linq和Lamda,求各种解,并说明优缺点!
- Angular CLI创建的项目文件用途一栏
- [888]python内置函数vars()|dir()|locals()
- Mdnice,一种记录知识的新方式
- [887]python中@classmethod和@staticmethod
- leetcode每日一题-99. 恢复二叉搜索树
- Java 两个经纬度获取方位
- 使用Python实现基本初等函数可视化
- 递归回溯--复原IP地址
- 通过 generic-webhook-trigger 插件实时获取 Bitbucket Repository Events
- 初识TypeScript:查找指定路径下的文件按类型生成json
- Xamarin Forms WPF 干掉默认的窗口导航条
- WPF 从零手动创建承载 Xamarin Forms 项目