当前位置: 首页 > news >正文

vue数据传递--我有特殊的实现技巧

前言

最近碰到了比较多的关于vue的eventBus的问题,之前定技术选型的时候也被问到了,vuex和eventBus的使用范围。所以简单的写一下。同时有一种特殊的实现方案。

组件之间传值有这么几种数据传递方式,vuex、props、eventBus和特殊的eventBus

vuex

我就传两个数据,vuex真是太麻烦了。用是不可能用的,理解又理解不了。

props

demo

父子组件传值,官方api,只写个demo。

  1. 父组件

    // 将事件绑定至子组件
    <son :info="info" @update="updateHandler"/>
    // data
    info: 'sendToSon'
    // methods
    updateHandler (newVal) {
      this.info = newVal
    }
  2. 子组件

    // props
    props: ['info']
    // 触发绑定在组件上的事件,向上传值,在父组件某个方法中使用
    this.$emit('update', 'got')

父向子传值-->props
子向父传值-->子组件绑定事件回调定义在父组件,子组件触发此事件。
因不推荐子组件内直接修改父组件传入的props,需使用自定义事件。

限制

父子组件。

eventBus

demo

bus皆为导入的bus实例

// bus
const bus = new Vue()
// 数据接收组件
// 当前组件接收值则
bus.$on('event1', (val)=>{})
// 数据发出组件
// 当前组件发出值则
bus.$emit('event1', val)

可以看出本质是一个vue实例充当事件绑定的媒介。
在所有实例中使用其进行数据的通信。

双(多)方使用同名事件进行沟通。

问题

  1. $emit时,必须已经$on,否则将无法监听到事件,也就是说对组件是有一定的同时存在的要求的。(注:路由切换时,新路由组件先created,旧路由组件再destoryed,部分情况可以分别写入这两个生命周期,见此问题)。
  2. $on在组件销毁后不会自动解除绑定,若同一组件多次生成则会多次绑定事件,则会一次$emit,多次响应,需额外处理。
  3. 数据非“长效”数据,无法保存,只在$emit后生效。

所以是否有一种更适用的方案呢?

特殊的eventBus?

demo

我们先来看个代码,线上代码。
bus皆为导入的bus实例

// bus
const bus = new Vue({
  data () {
    return {
      // 定义数据
      val1: ''
    }
  },
  created () {
    // 绑定监听
    this.$on('updateData1', (val)=>{
      this.val1 = val
    })
  }
})

// 数据发出组件

import bus from 'xx/bus'
// 触发在bus中已经绑定好的事件
bus.$emit('update1', '123')

// 数据接收组件


{{val1}}
// 使用computed接收数据
computed {
  val1 () {
    // 依赖并返回bus中的val1
    return bus.val1
  }
}

不同

  1. 正统的eventBus只是用来绑定触发事件,并不关心数据,不与数据发生交集。而这个方案多一步将数据直接添加在bus实例上。且事件监听与数据添加需提前定义好。
  2. 数据接收方不再使用$on来得知数据变化,而是通过计算属性的特征被动接收。

解决的问题

  1. 通信组件需同时存在?数据在bus上存储,所以没有要求。
  2. 多次绑定?绑定监听都在bus上,不会重复绑定。
  3. 数据只在$emit后可用?使用计算属性直接读取存在bus上的值,不需要再次触发事件。

探讨

为什么使用计算属性

其实应该是为什么不能直接添加到data上,如data1: bus.data1?我们可以再看一段代码,线上代码。
将bus修改为

data () {
  return {
    // 多一层结构
    val: {
      result: 0
    }
  }
},
created () {
  this.$on('update1', val => {
    console.log('触发1', i1++)
    this.val.result = val
  })
}

数据接收组件改为

// template
data中获取直接修改值:{{dataResult}}
data中获取直接修改值的父层:{{dataVal}}
computed中依赖直接修改值:{{computedResult}}
// js
data () {
    return {
      // 获取直接修改值
      dataResult: bus.val.result,
      // 获取直接修改值的父层
      dataVal: bus.val
    }
  },
  computed: {
    computedResult () {
      // 依赖直接修改值
      return bus.val.result
    }
  }

可以看到,data中获取直接修改值时值的数据是无法动态响应的。

为什么要用事件

其实不用$emit触发,使用bus.val = 1直接赋值也是可以的,那么为什么不这么做呢?

简化版的vuex

其实这种eventBus就是简化版的vuex。
vue文档中有这样一段话:

组件不允许直接修改属于 store 实例的 state,而应执行 action 来分发 (dispatch) 事件通知 store 去改变,我们最终达成了 Flux 架构。这样约定的好处是,我们能够记录所有 store 中发生的 state 改变。

那么可以用vuex中store对应bus实例,state对应dataaction对应事件dispatch对应$emit
同时vuex中组件获取数据的方式正是通过计算属性,那么其实vuexFlux架构的理解和使用也没有那么难。

相关文章:

  • 有哪些新手程序员不知道的小技巧?
  • Jquery append()总结(一)
  • 知识碎片
  • IOS 获取设备屏幕的尺寸
  • 代码片段---S3C2440按键中断驱动程序的设计
  • 《利用Python进行数据分析·第2版》第12章 pandas高级应用
  • 动态ACL
  • 聊聊reactive streams的backpressure
  • python 运行 hadoop 2.0 mapreduce 程序
  • ListView优化
  • 蓝桥杯第二届试题集锦
  • OpenAI发文怒怼:对抗样本怎么不会对检测产生干扰了?
  • mina编解码(摘录)
  • 团队作业7——第二次项目冲刺-Beta版本项目计划
  • mysql登陆密码忘记,解决办法
  • 《Java编程思想》读书笔记-对象导论
  • 2019.2.20 c++ 知识梳理
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • avalon2.2的VM生成过程
  • ES学习笔记(12)--Symbol
  • HashMap ConcurrentHashMap
  • KMP算法及优化
  • spring boot 整合mybatis 无法输出sql的问题
  • WebSocket使用
  • 浮现式设计
  • 类orAPI - 收藏集 - 掘金
  • 力扣(LeetCode)21
  • 你不可错过的前端面试题(一)
  • 我是如何设计 Upload 上传组件的
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • 做一名精致的JavaScripter 01:JavaScript简介
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • !!Dom4j 学习笔记
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • #pragma multi_compile #pragma shader_feature
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (02)vite环境变量配置
  • (LeetCode) T14. Longest Common Prefix
  • (二)WCF的Binding模型
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d
  • /var/lib/dpkg/lock 锁定问题
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...
  • @ModelAttribute注解使用
  • @serverendpoint注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)
  • @Service注解让spring找到你的Service bean
  • [145] 二叉树的后序遍历 js