本地存储、自定义事件、全局事件总线、消息订阅与发布【Vue】

news2024/12/29 11:02:13

Vue

1.1 浏览器的本地存储

  1. 存储内容大小一般支持5MB左右(不同浏览器可能还不一样)
  2. 浏览器通过 Window.sessionStorage 和 Window.localStorage 属性来实现本地存储机制
  3. 相关API:
    (1)xxxxStorage.setItem('key', 'value');
    该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。
    (2)xxxxStorage.getItem('person');
    该方法接受一个键名作为参数,返回键名对应的值
    (3)xxxxStorage.removeItem('key');
    该方法接受一个键名作为参数,并把该键名从存储中删除。
    (4)xxxxStorage.clear()
    该方法清空存储中的所有数据。
  4. 备注:
    (1)sessionStorage存储的内容会随着浏览器窗口关闭而消失。
    (2)LocalStorage存储的内容,需要手动清除才会消失。
    (3)xxxxStorage.getItem(xxx) 如果xxx对应的value获取不到,那么getItem的返回值是null
    (4)JSON.parse(null)的结果依然是null

1.2 组件的自定义事件

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件
  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中
  3. 绑定自定义事件:
    (1)第一种方式,在父组件中:< Demo @zmy = "test"/ > 或 <Demo v-on:zmy = "test"/ >
    (2)第二种方式,在父组件中:
<Demo ref="demo"/>
......
mounted(){
	this.$refs.xxx.$on('zmy', this.test)
}

(3) 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法
4. 触发自定义事件:this. $ emit('zmy', 数据)
5. 解绑自定义事件:this.$ off('zmy')
6. 组件上也可以绑定原生DOM事件,需要使用native修饰符
7. 注意:通过 this.$ refs.xxx.$ on('zmy', 回调) 绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!

1.3 全局事件总线

1.3.1 理解

  1. 一种组件间通信的方式,适用于任意组件间通信
  2. Vue 原型对象上包含事件处理的方法
    (1) $on(eventName, listener): 绑定自定义事件监听
    (2) $emit(eventName, data): 分发自定义事件
    (3) $off(eventName): 解绑自定义事件监听
    (4) $once(eventName, listener): 绑定事件监听, 但只能处理一次
  3. 所有组件实例对象的原型对象的原型对象就是 Vue 的原型对象
    (1)所有组件对象都能看到 Vue 原型对象上的属性和方法
    (2) Vue.prototype.$bus = new Vue() ,所有的组件对象都能看到$bus 这个属性对象
  4. 全局事件总线
    (1)包含事件处理相关方法的对象(只有一个)
    (2)所有的组件都可以得到

1.3.2 指定事件总线对象

  1. 安装全局事件总线:
new Vue({
	......
	beforeCreate(){
		Vue.prototype.$bus = this//安装全局事件总线,$bus就是当前应用的vm
	},
	......
})
  1. 使用事件总线
    (1)接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身
methods(){
	demo(data){......}
}
......
mounted(){
	this,$bus.$on('xxx', this.demo)
}

(2)提供数据:this.$ bus.$ emit('xxx', 数据)

  1. 最好在 deforeDestroy 钩子中,用 $ off 去解绑当前组件所用到的事件

School.vue

<template>
    <div class="school">
      <h2>学校名称:{{ name }}</h2>
      <h2>学校地址:{{ address }}</h2>
    </div>
  </template>
  
  <script>
      export default {
          name: 'School',
          props: ['getSchoolName'],
          data(){
              return {
                  name: '西安文理',
                  address: '西安',
              }
          },
          mounted(){
            // console.log('School', this);
            this.$bus.$on('hello',(data) => {
              console.log('我是School组件, 收到了数据', data);
            })
          },
          beforeDestroy(){
            this.$bus.$off('hello')
          }
      }
  </script>
  
  <style scoped>
    .school {
      background-color: skyblue;
      padding: 5px;
    }
  </style>

Student.vue

<template>
  <div class="student">
    <h2>学生名称:{{ name }}</h2>
    <h2>学生性别:{{ sex }}</h2>
    <button @click="sendStudentName">把学生名给School组件</button>
  </div>
</template>

<script>
    export default {
        name: 'Student',
        data(){
            return {
                name: '张三',
                sex: '男',
            }
        },
        methods: {
          sendStudentName(){
            this.$bus.$emit('hello', this.name)
          }
        }
    }
</script>
<style lang="less" scoped>
  .student {
    background-color: orange;
    padding: 5px;
    margin-top: 30px;
  }
</style>

App.vue

<template>
    <div class="app">
        <h1>{{ msg }}</h1>
        <School/>
        <Student/>
    </div>
  </template>
  
  <script>
      import Student from './components/Student.vue'
      import School from './components/School.vue'
      export default {
          name: 'App',
          components: {School, Student},
          data(){
            return {
                msg: '你好啊',
                studentName:''
            }
          },
        }
  </script>

  <style scoped>
    .app{
        background-color: gray;
        padding: 5px;
    }
  </style>

main.js

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false

/* const demo = Vue.extend({})
const d = new demo()           */                            


//创建vm
new Vue({
    el: '#app',
    render: h => h(App),
    beforeCreate(){
        Vue.prototype.$bus = this //安装全局事件总线
    }
})

在这里插入图片描述

1.4 消息的订阅与发布

  1. 一组组件间通信的方式,适用于任意组件通信
  2. 使用步骤:
    (1)安装 pubsub:npm i pubsub-js
    (2)引入:import pubsub from 'pubsub-js'
    (3)接收数据:A组件想接收数据,则在A组件中订阅消息,订阅回调留在A组件自身
methods(){
	demo(data) {......}
}
......
mounted() {
	this.pid = pubsub.subscribe('xxx', this.demo)//订阅消息
}

(4)提供数据:pubsub.publish('xxx', 数据)
(5)最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid)去取消订阅

在这里插入图片描述
在这里插入图片描述

1.5 使用 PubSubJS

  1. 在线文档: https://github.com/mroderick/PubSubJS
  2. 下载: npm install -S pubsub-js
  3. 相关语法
    (1) import PubSub from 'pubsub-js' // 引入
    (2) PubSub.subscribe(‘msgName’, functon(msgName, data){ })
    (3) PubSub.publish(‘msgName’, data): 发布消息, 触发订阅的回调函数调用
    (4) PubSub.unsubscribe(token): 取消消息的订阅

1.6 nextTick

  1. 语法:this.nextTick(回调函数)
  2. 作用:在下一次DOM更新结束后执行其指定的回调
  3. 什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。

1.7 Vue封装的过度与动画

  1. 作用:在插入、更新或移除DOM元素时,在合适的时候给元素添加样式类名

  2. 图示:
    在这里插入图片描述

  3. 写法:
    (1)准备好样式:

  • 元素进入的样式:
    1. v-enter:进入的起点
    2. v-enter-active:进入过程中
    3. v-enter-to:进入的终点
  • 元素离开的样式:
    1. v-leave:离开的起点
    2. v-leave-active:离开过程中
    3. v-leave-to:离开的终点
      (2)使用 < transition >包裹要过度的元素,并配置name属性:
<transition name="hello">
	<h1 v-show="isShow">你好啊!</h1>
</transition>
  1. 备注:若有多个元素需要过度,则需要使用:< transition-group >,且每个元素都要指定key

Tset.vue

<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <transition name="hello" appear>
        <h1 v-show="isShow">你好啊</h1>
    </transition>
  </div>
</template>

<script>
    export default {
        name: 'Test',
        data(){
            return {
                isShow: true
            }
        },

    }
</script>

<style scoped>
    h1{
        background-color: orange;
    }

    .hello-enter-active{
        animation: aaa 0.5s linear;
    }

    .hello-leave-active{
        animation: aaa 0.5s linear reverse;
    }

    @keyframes aaa {
        from{
            transform: translateX(-100%);
        }
        to{
            transform: translateX(0px);
        }
    }
</style>

Tset2.vue

<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <transition-group name="hello" appear>
        <h1 v-show="!isShow" key="1">你好啊</h1>
        <h1 v-show="isShow" key="2">aaa</h1>
    </transition-group>
  </div>
</template>

<script>
    export default {
        name: 'Test',
        data(){
            return {
                isShow: true
            }
        },

    }
</script>

<style scoped>
    h1{
        background-color: orange;
    }
    /* 进入的起点 离开的终点*/
    .hello-enter, .hello-leave-to{
        transform: translateX(-100%);
    }

    .hello-enter-active, .hello-leave-active{
        transition: 0.5s linear;

    }

    /* 进入的终点 离开的起点*/
    .hello-enter-to, .hello-leave{
        transform: translateX(0);
    }
</style>

Tset3.vue

<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <transition-group name="animate__animated animate__bounce" appear enter-active-class="animate__swing" leave-active-class="animate__backOutUp">
        <h1 v-show="!isShow" key="1">你好啊</h1>
        <h1 v-show="isShow" key="2">aaa</h1>
    </transition-group>
  </div>
</template>

<script>
    import 'animate.css'
    export default {
        name: 'Test',
        data(){
            return {
                isShow: true
            }
        },

    }
</script>

<style scoped>
    h1{
        background-color: orange;
    }
</style>

App.vue

<template>
    <div>
        <Test></Test>
        <Test2></Test2>
        <Test3></Test3>
    </div>
</template>
  
  <script>
      import Test from './components/Test.vue'
      import Test2 from './components/Test2.vue'
      import Test3 from './components/Test3.vue'


      export default {
          name: 'App',
          components: {Test, Test2, Test3},
        
      }
  </script>


main.js

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CT前瞻(三):Adobe系列XD软件绘制简单的原型图与交互设计

文章目录&#x1f4cb;前言&#x1f3af;关于原型图绘制&#x1f3af;XD绘制原型图与交互设计&#x1f3af;关于XD软件其他功能&#x1f4dd;最后&#x1f4cb;前言 Adobe XD是一个协作式易用平台&#xff0c;可帮助团队为网站、移动应用程序、语音界面、游戏等创建设计。还可…

每个 Android 开发者都应该知道的有用资源

每个 Android 开发者都应该知道的有用资源 在本文中&#xff0c;我将提到 7 个资源&#xff0c;这些资源对于 Android 开发人员来说非常有益。我亲自使用过其中的每一个几次。他们无数次派上用场。确保您不要忘记为这些资源添加书签/收藏&#xff0c;以便您可以在需要使用它们时…

医院体检PEIS系统源码

一、医院体检系统概述 1. 医院体检系统概述 目前&#xff0c;大多数的体检还停留在手工操作上&#xff0c;如单位体检时手工书写体检人员信息、医生手工书写体检结果、检验报告打印后进行手工粘贴等&#xff0c;这样造成极大的工作量&#xff0c;效率低下&#xff0c;而且极易…

【三十天精通Vue 3】第九天 Vue 3 路由详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录引言一、Vue 3 路由概述1.1 路由的简介1.2 路由的分类1.3 路由的语…

暗讽友商 昆仑万维大模型预告刺激股价

搭上AI风口&#xff0c;上市公司昆仑万维年内股价大涨217.56%&#xff0c;一时名声大噪。火了以后&#xff0c;昆仑万维的野心越来越大&#xff0c;喊出“All in AGI&#xff08;通用人工智能&#xff09;与AIGC”的豪言壮语。 在近期预告旗下大模型“天工”邀测的公告中&…

STL :双端队列容器 Deque

Deque #include<deque> using namesace std; 双端队列容器 &#xff1a;双向开口的连续线性空间&#xff1b; 擅长尾部和头部添加或删除元素&#xff1a;常数阶&#xff1b; 存储元素并不能保证所有元素都存储到连续的内存空间中&#xff1b; deque 是动态的以分段…

TiDB实战篇-TiDB配置

简介 熟系TiDB的配置相关。 TiDB的大体参数 系统配置对应的是TiDB-Server,PD和TiKV和TiDB-Server基本在集群配置里面配置。 系统配置 系统变量 | PingCAP 文档中心 集群配置 PD 配置文件描述 | PingCAP 文档中心 配置的存储位置 系统配置存储在TiKV中的&#xff0c;集…

如何免费恢复电脑上误删除的视频

虽然我们现在可以在单个硬盘驱动器上存储无数大型视频文件是件好事&#xff0c;但这也意味着单个用户错误或硬件/软件故障可能会立即抹去数小时的记忆&#xff0c;而没有任何明显的方法可以恢复它们。在本文中&#xff0c;我们提供了一个快速的分步视频恢复指南&#xff0c;以帮…

【音视频】利用ffmpeg实现:音视频的提取,rtmp推流等

目录 可列出电脑的设备 音频桌面视频&#xff0c;存mp4 录声音 推流到服务器 音频桌面视频&#xff0c;推流到服务器 音频笔记本摄像头&#xff0c;推流到服务器 参考资料 可列出电脑的设备 输入下面的语句即可列出电脑的设备 ffmpeg -list_devices true -f dshow -i dum…

(链表)相交链表(双指针法)

文章目录前言&#xff1a;问题描述&#xff1a;问题解析&#xff1a;代码实现&#xff1a;总结&#xff1a;前言&#xff1a; 此篇是关于链表的经典练习题。 问题描述&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节…

【测试开发篇9】Junit框架

目录 一、认识Junit框架 Junit和Selenium的关系是什么 导入Junit框架common-io包 二、Junit框架的使用 2.1Junit有哪些常用注解 2.1.1Test注解 2.1.2BeforeEach 2.1.3BeforeAll 2.1.4AfterAll 2.1.5AfterEach 2.2Junit的断言 Assertions.assertEquals(期待值&#…

小白推荐|使用git建立自己的代码仓库

1 git 1.1 什么是git 版本控制工具&#xff0c;用于团队协作与项目管理 1.2 git 安装教程 step1&#xff1a;进入git下载官网Git for Windows step2&#xff1a;点击Download step3&#xff1a;打开下载好的文件&#xff0c;按照下面图片一步一步安装 剩下的一直点Next就完…

ansible-playbook task 指定位置执行

文章目录执行顺序指定执行--tags–start-at--skip-tags--step混合执行顺序 1.检查play中是否存在pre_tasks定义&#xff0c;存在的话则顺序执行pre_tasks中定义的所有tasks 2.如果存在pre_tasks定义&#xff0c;则检查是否存在触发handler&#xff0c;如存在则顺序执行相关触发…

Java中的锁是什么意思,有哪些分类?

Java锁&#xff08;Java Locks&#xff09;是Java编程语言中用于实现多线程同步和互斥的机制。在并发编程中&#xff0c;多线程同时访问共享资源可能导致竞态条件&#xff08;Race Condition&#xff09;和其他并发问题&#xff0c;Java锁提供了一种控制多线程并发访问的方式&a…

FluxMQ—物联网高性能MQTT网关

FluxMQ—物联网高性能MQTT网关 随着物联网技术的快速发展&#xff0c;人们越来越意识到实时、可靠、安全的数据传输对于智能化的生产与生活的重要性。因此&#xff0c;市场对于高性能的物联网数据传输解决方案有着强烈的需求。FluxMQ正是为满足这一需求而诞生的一款高性能、可…

Adobe 观察 |最低工资标准来了,学会这几招,让加薪更简单

最新调整后的全国各地区最低工资标准情况来了&#xff01; 人力资源和社会保障部新发布的数据显示&#xff0c;截至今年4月1日&#xff0c;共有15个地区第一档月最低工资标准在2000元及以上&#xff0c;分别是上海&#xff08;2590元&#xff09;、深圳&#xff08;2360元&…

Pandas 2.0发布——更快的速度更低的内存占用

【重磅】Pandas 2.0发布&#xff01;更快的速度更低的内存占用&#xff01; Pandas 是一个用于操作数据的 Python 库&#xff0c;在 Python 开发人员中非常流行。尤其在数据科学和机器学习领域中&#xff0c;Pandas已经成为不可或缺的基础库。 4月3日&#xff0c;Pandas 2.0正…

ESLint 与 Prettier 配合解决代码格式问题

可以了解下Prettier&#xff0c;官网&#xff1a;Prettier 中文网 Prettier 是一个“有态度”的代码格式化工具 Prettier常见的一些配置&#xff1a; tabWidth&#xff1a;指定缩进宽度&#xff0c;默认为 2&#xff0c;建议设置为 4&#xff1b;printWidth&#xff1a;指定代…

MyBatis核心配置文件详解

<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><environments default"…

页面布局基础知识

一、布局方案 1、什么是静态布局 概念 静态布局&#xff0c;也称为固定布局&#xff0c;是一种传统网页设计。页面布局使用绝对长度单位&#xff0c;采用固定宽度。忽略浏览器实际&#xff0c;网页布局始终按照最初写代码时的布局来显示。 优点&#xff1a;简单 缺点&#xf…