【Vue.js】Vue.js中的事件处理、过滤器、过渡和动画、组件的生命

作者:神秘网友 发布时间:2020-09-27 08:02:33

【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>

生命周期图示

【Vue.js】Vue.js中的事件处理、过滤器、过渡和动画、组件的生命

钩子函数

  • 初始化显示
  1. beforeCreate()
  2. created()
  3. beforeMount()
  4. mounted()
  • 更新状态
  1. beforeUpdate()
  2. updated()
  • 销毁 vue 实例
  1. beforeDestory()
  2. 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:
  1. 只指定名称:
props: ['name', 'age', 'logDog']
  1. 指定名称和类型
props: {
    name: String,
    age: Number,
    logDog: Function
}
  1. 指定名称、类型、必要性、默认值
props: {
    name: {type: String, required: true, default:xxx},
}
  • 使用注意
  1. 此方式用于父组件向子组件传递数据
  2. 所有标签属性都会成为组件对象的属性,模板页面可以直接引用
  3. 存在缺陷:
    (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},
}
  • 使用注意
  1. 此方式只用于子组件向父组件发送消息或数据
  2. 隔代组件或兄弟组件间通信此种方式不合适

代码示例

## 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中的事件处理、过滤器、过渡和动画、组件的生命相关教程

  1. 微软预览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. 首先,最好进行一些基本的硬件检查,以确保一切都按预期

  2. 【Git 使用笔记】第四部分:git在公司中的开发流程

    【Git 使用笔记】第四部分:git在公司中的开发流程 为什么80%的码农都做不了架构师? 先声明几个变量 仓管A:主分支,只有master分支 仓管B:开发分支,只有各个业务开发分支 仓管B fork 于 A 如下图 为了保证 代码的稳定性,只有 仓管B中的某个分支测试完毕

  3. 框架源码专题:Spring的事件监听、发布机制

    框架源码专题:Spring的事件监听、发布机制 文章目录 1.Spring内置事件 2.自定义事件 3.事件监听器 4.事件发布 publishEvent 4.Spring事件原理 Spring内置事件是Spring在内部帮我们写好的事件,在使用时,不需要重写他们,只需在容器中注入重写后的监听器即可

  4. 4.6嵌入式开发中的c语言(上)

    4.6嵌入式开发中的c语言(上) 文章目录 数据类型 c语言位操作 变位 清0 左移 右移 判断条件 嵌入式中~位取反 range范围 delay延时可以用for循环,delay一个固定时间 技术教程图 这是错误永远出字节四不了循环体到255归0 在做通讯协议,包头 包尾 校验位 不

  5. 事件冒泡、事件委托和事件捕获

    事件冒泡、事件委托和事件捕获 事件冒泡会从当前触发的事件目标一级一级往上传递,依次触发,直到document为止。 事件捕获会从document开始触发,一级一级往下传递,依次触发,直到真正事件目标为止。 事件委托依靠的就是事件冒泡和捕获的机制。 一个很简单的

  6. 【LeetCode每日一题】[简单]501. 二叉搜索树中的众数

    【LeetCode每日一题】[简单]501. 二叉搜索树中的众数 【LeetCode每日一题】[简单]501. 二叉搜索树中的众数 501. 二叉搜索树中的众数 题目来源 算法思想:树,中序遍历 题目: /** * Definition for a binary tree node. * public class TreeNode { * int val;

  7. 浅析STL算法中的堆排序

    浅析STL算法中的堆排序 堆结构简述 了解过数据结构的人,应该对堆结构不陌生,堆的底层是使用数组来实现的,但却保持了二叉树的特性。堆分为两种,最大堆和最小堆,以最大堆为例,最大堆保持了根结点大于两个左右两个孩子,同时所有子树一次类推。由于堆底层

  8. 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