Vue2(十):全局事件总线、消息订阅与发布、TodoList的编辑功能、$nextTick、动画

一、全局事件总线!!

任意组件间通信

比如a想收到别的组件的数据,那么就在a里面给x绑定一个demo自定义事件,所以a里面就得有一个回调函数吧,然后我要是想让d组件给a穿数据,那就让d去触发x的自定义事件,并且传参数进去,那么触发自定义事件就也会调用回调函数,就把数据给到a了 

1.安装全局事件总线

那么x应该放到哪里呢?之前学prototype的时候说它可以让vc、vm都能找到,x放在vue的原型对象上,x写到main.js中

new Vue({el:'#app',render: h => h(App),beforeCreate() {Vue.prototype.$bus=this},
})

注意$on、$off只有vm、vc才能用,如果把创建为一个新的vc可以实现,但是代码有点多,我们就把它创建成一个vm,有一个现成的vm让x直接等于它,写在new Vue后边呢在模版解析完之后才能赋值太晚了,所以就用钩子来赋值。(x一般写成$bus)

2.使用事件总线

a组件要绑定自定义事件

mounted(){this.$bus.$on('hello',(data)=>{console.log('我是school,我收到了',data)})}

3.提供数据

x中开始调用触发

<button @click="sendName">点我把数据传给school</button>
methods:{sendName(){this.$bus.$emit('hello',666)}}

注意:1.我们会有很多条线调用两个组件一个方法名,这些方法名不能重复

2.我们在销毁之前要把事件解绑

4.解绑事件

在哪儿绑的在哪儿解,为啥之前的自定义事件销毁之前不去解绑呢?因为之前那些组件销毁的话身上的自定义事件就一起嘎了,但是这个无论哪个组件销毁x都一直在,组件都销毁了还留着事件那x太累了

beforeDestroy(){this.$bus.$off('hello')}

5.TodoList中的孙传父

app里传给list再传给item的函数全都不要了

mounted(){// this.$bus.on('checkTodo',(id)=>{//   this.checkTodo(id)// }), 不是这么写啊,这里是事件名和事件函数,我本来就是要触发那个函数,而且函数已经写好了直接用this.$bus.$on('deleteTodo',this.deleteTodo)this.$bus.$on('checkTodo',this.checkTodo)},beforeDestroy(){this.$bus.$off(['checkTodo','deleteTodo'])}

item:

methods: {handleCheck(id){this.$bus.$emit('checkTodo',id)},handleDelete(id){this.$bus.$emit('deleteTodo',id)}},

检查vue中如果sourse为root那一般就是$bus

二、消息订阅与发布(pubsub)

在vue里用的不多

在a(需要消息)组件里我们订阅了一个demo的消息,内容是test,然后c(提供数据、发布消息)一旦发布demo的消息并传参666,那么a就会立马收到

1.使用方法

需要引入pubsub-js库,可以在任何一个框架使用

安装pubsub:npm i pubsub-js
引入:import pubsub from 'pubsub-js

接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。

mounted(){// this.$bus.$on('hello',(data)=>{// 	console.log('我是school,我收到了',data)// })this.pubid=pubsub.subscribe('hello',(msgName,data)=>{console.log('dingyuele ',msgName,data)})//两个参数第一个是事件名,第二个是(事件名,数据)},beforeDestroy(){// this.$bus.$off('hello')pubsub.unsubscribe(this.pubid)//括号里面写‘hello’不对,每次订阅消息都有一个订阅id,类似定时器//上面和这里不写this找不到}

提供数据:

methods:{sendName(){pubsub.publish('hello',666)}}

2.TodoList中用pubsub

第三方Vue中不支持查看

我们来修改一下todolist 的delete方法,app:

import pubsub from 'pubsub-js'//mounted:this.pubId=pubsub.subscribe('deleteTodo',this.deleteTodo)},beforeDestroy(){//this.$bus.$off(['checkTodo'])pubsub.unsubscribe(this.pubId)}

item:

handleDelete(id){//this.$bus.$emit('deleteTodo',id)pubsub.publish('deleteTodo',id)}

然后我们之前不是说会传参过来两个吗,一个是函数名,一个是形参,但是函数名我们其实不太需要,这个里面调的是methods里面我们写好的函数,所以就用_占位一下

deleteTodo(_,id)
//传不都是传两个参数吗,用这个_占位

这里没有用箭头函数是我们的函数写在了methods里面,this(delete里的this)就是vm

(为啥要让里面函数的this指向vm?存个疑)

三、TodoList的编辑功能

1.点击获取

首先实现在每个爱好的后面再加一个按钮编辑,让文字处于input框中

在处于input框中的时候,就应该是文字在框里面,编辑完成之后又得恢复成文字样式,所以还得设置一个todo.isEdit来判断当前的todo是不是在编辑中

<span v-show="!todo.isEdit">{{todo.title}}</span><input v-show="todo.isEdit" type="text" :value="todo.title" > 

isEdit为true的时候,表单就出来,否则就隐藏,因为变换比较多的问题这里不用v-if

然后开始添加点击之后让isEdit为true

handleEdit(todo){//todo.isEdit=true 这么加只是表层加了,isEdit没有getter、setter//这样每次都追加的写法有点不好,因为你第一次编辑确实得加这个属性,但是第二次就没必要了this.$set(todo,'isEdit',true)},

但是这样会让每次点击都重新添加isEdit属性不管你以前有没有

   handleEdit(todo) {if (todo.isEdit !== undefined) {todo.isEdit = true;} else {this.$set(todo, 'isEdit', true);}},

老师讲的是hasOwnProperty方法,但是报错说我电脑没有这个我就没用

2.失去焦点

失去焦点之后,isEdit为false,表单消失,而且之前修改的内容需要改到我们的文字里面,注意传的是input表单的value而不是todo.title

<input v-show="todo.isEdit" type="text" :value="todo.title" @blur="handleBlur(todo,$event)"> 
//失去焦点真正执行修改handleBlur(todo,e){//现在的todo已经有isEdit属性了todo.isEdit=falsethis.$bus.$emit('updataTodo',todo.id,e.target.value)}

用全局事件来修改app里的数据,在item中触发updateTodo事件

app:遍历数组看谁的id和我传的一样就修改它的title

updateTodo(id,title){this.todos.forEach((todo)=>{if(todo.id==id) {todo.title=title}})},
mounted(){this.$bus.$on('updateTodo',this.updateTodo)
}
beforeDestroy() {this.$bus.$off('editTodo');
},

四、$nextTick

1、语法:this.$nextTick(回调函数)
2、作用:在下一次 DOM 更新结束,v-for循环结束后执行其指定的回调。
3、什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时(如input自动获取焦点),要在nextTick所指定的回调函数中执行。

我点击了编辑按钮之后我想让他自动获取焦点,如果直接写this.$refs.inputTitle.focus()的话,模版解析等这个函数走完了才显示在页面上,但是那个时候就focus完了,在handleEdit(todo)用$nextTick。

this.$nextTick(function (){this.$refs.inputTitle.focus()});

五、动画

1.动画效果

transition标签在html中不显示,是vue提供的,可以在style设置来去的动画,appear默认打开页面就出现 来 的动画

<button @click="isShow = !isShow">显示/隐藏</button><transition name="hello" :appear="true"><!-- appear="true"这样会报错因为人家要的是布尔值不是字符串 --><!-- :appear="true"简写为appear --><h1 v-show="isShow">你好啊</h1></transition>
.hello-enter-active{animation: atguigu 1s;
}
.hello-leave-active{animation: atguigu 1s reverse;
}
@keyframes atguigu {from{transform: translateX(-100%);}to{transform: translateX(0px);}
}

2.用过渡实现以上效果

元素进入的样式:
v-enter:进入的起点
v-enter-active:进入过程中
v-enter-to:进入的终点

元素离开的样式:
v-leave:离开的起点
v-leave-active:离开过程中
v-leave-to:离开的终点

.hello-enter,.hello-leave-to{/* 进入的起点 */transform: translateX(-100%);}
.hello-enter-to,.hello-leave{
/* 进入的终点 */
transform: translateX(0);
}
.hello-enter-active,.hello-leave-active{transition: 0.5s linear;
}

3.多个元素实现过渡

transition-group

<template><div><button @click="isShow = !isShow">显示/隐藏</button><transition-group name="hello" :appear="true"><!-- appear="true"这样会报错因为人家要的是布尔值不是字符串 --><!-- :appear="true"简写为appear --><h1 v-show="isShow" key="1">你好啊</h1><h1 v-show="isShow" key="2">你好啊</h1></transition-group></div>
</template>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/564356.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】如何用一个哈希表同时封装出unordered_set与unordered_map

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.哈希桶源码 2.哈希…

【算法】小强爱数学(迭代公式+数论取模)

文章目录 1. 问题2. 输入3. 输出4. 示例5. 分析6. 思路7. 数论&#xff0c;取模相关公式8. 数论&#xff0c;同余定理9. 代码 1. 问题 小强发现当已知 x y B xyB xyB以及 x y A xyA xyA时,能很轻易的算出 x n x_ {n} xn​ y n y_ {n} yn​ 的值.但小强想请你在已知A和B的…

vue3项目初始化

初始化项目newsapp VSCode 打开终端&#xff0c;newsapp项目目录&#xff0c;可自定义 vue create newsapp 有提示“因为在此系统上禁止运行脚本”的话&#xff0c;请执行 set-ExecutionPolicy RemoteSigned 执行后再重复执行vue create newsapp 注意选择Vue 3版本 测试项…

CSS案例-2.简单版侧边栏练习

效果 知识点 标签显示模式 块级元素 block-level 常见元素:<h1>~<h6>、<p>、<div>、<ul>、<ol>、<li>等。 特点: 独占一行长度、宽度、边距都可以控制宽度默认是容器(父级宽度)的100%是一个容器及盒子,里面可以放行内或者…

24计算机考研调剂 | 【官方】山东工商学院

山东工商学院 考研调剂招生信息 招生专业&#xff1a; 学院概况&#xff1a; 计算机科学与技术学院始建于1999年&#xff0c;拥有计算机科学与技术一级学科硕士点,在2022软科中国最好学科排名中&#xff0c;计算机科学与技术学科位列全国第104位。在2022年“软科”中国大学专…

ShardingSphere水平分表——开发经验(2)

1. 什么场景下分表&#xff1f; 数据量过大或者数据库表对应的磁盘文件过大。 Q&#xff1a;多少数据分表&#xff1f; A&#xff1a;网上有人说1kw&#xff0c;2kw&#xff1f;不准确。 1、一般看字段的数量&#xff0c;有没有包含text类型的字段。我们的主表里面是不允许有t…

【索引失效】MySQL索引失效场景

1、对索引使用左或者左右模糊匹配 当我们使用左或者左右模糊匹配的时候&#xff0c;也就是 like %xx 或者 like %xx% 这两种方式都会造成索引失效。 比如下面的 like 语句&#xff0c;查询 name 后缀为「林」的用户&#xff0c;执行计划中的 typeALL 就代表了全表扫描&#xff…

(一)基于IDEA的JAVA基础7

关系运算符 运算符 含义 范例 结果 等于 12 false &#xff01; 不等于 1&#xff01;2 true > 大于 1>2 false < 小于 …

Vue 计算属性和watch监听

1.1.计算属性 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><!-- 引入vue.js --><script src"node_modules/vue/dist/vue.js"></script> </h…

raise PyAutoGUIException! ! !

在了解pyautogui时&#xff0c;你是否遇到过这样的情况&#xff1a; y pyautogui.locateOnScreen(kk.png) print(y) 在信心满满下输入完成后选择直接运行&#xff0c;结果却是抛出异常的尴尬。 raise PyAutoGUIException( pyautogui.PyAutoGUIException: PyAutoGUI was unable…

Django之Celery篇(一)

一、介绍 Celery是由Python开发、简单、灵活、可靠的分布式任务队列,是一个处理异步任务的框架,其本质是生产者消费者模型,生产者发送任务到消息队列,消费者负责处理任务。 Celery侧重于实时操作,但对调度支持也很好,其每天可以处理数以百万计的任务。特点: 简单:熟悉…

Python文件读写操作

文件操作注意点 注意点&#xff1a; 1. for line in file --> 会将偏移量移到末尾 2. buffering1 --> 缓冲区中遇到换行就刷新&#xff0c;即向磁盘中写入 3. 读操作结束后&#xff0c;文本偏移量就会移动到读操作结束位置 """编写一个程序,循环不停的写入…