摘要:同时有一种特殊的实现方案。组件之间传值有这么几种数据传递方式,和特殊的。在所有实例中使用其进行数据的通信。双多方使用同名事件进行沟通。数据非长效数据,无法保存,只在后生效。这样约定的好处是,我们能够记录所有中发生的改变。
前言
最近碰到了比较多的关于vue的eventBus的问题,之前定技术选型的时候也被问到了,vuex和eventBus的使用范围。所以简单的写一下。同时有一种特殊的实现方案。
组件之间传值有这么几种数据传递方式,vuex、props、eventBus和特殊的eventBus。
vuex我就传两个数据,vuex真是太麻烦了。用是不可能用的,理解又理解不了。
props demo父子组件传值,官方api,只写个demo。
父组件
// 将事件绑定至子组件// data info: "sendToSon" // methods updateHandler (newVal) { this.info = newVal }
子组件
// props props: ["info"] // 触发绑定在组件上的事件,向上传值,在父组件某个方法中使用 this.$emit("update", "got")
父向子传值-->props
子向父传值-->子组件绑定事件回调定义在父组件,子组件触发此事件。
因不推荐子组件内直接修改父组件传入的props,需使用自定义事件。
父子组件。
eventBus demobus皆为导入的bus实例
// bus const bus = new Vue() // 数据接收组件 // 当前组件接收值则 bus.$on("event1", (val)=>{}) // 数据发出组件 // 当前组件发出值则 bus.$emit("event1", val)
可以看出本质是一个vue实例充当事件绑定的媒介。
在所有实例中使用其进行数据的通信。
双(多)方使用同名事件进行沟通。
问题$emit时,必须已经$on,否则将无法监听到事件,也就是说对组件是有一定的同时存在的要求的。(注:路由切换时,新路由组件先created,旧路由组件再destoryed,部分情况可以分别写入这两个生命周期,见此问题)。
$on在组件销毁后不会自动解除绑定,若同一组件多次生成则会多次绑定事件,则会一次$emit,多次响应,需额外处理。
数据非“长效”数据,无法保存,只在$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 } }不同
正统的eventBus只是用来绑定和触发事件,并不关心数据,不与数据发生交集。而这个方案多一步将数据直接添加在bus实例上。且事件监听与数据添加需提前定义好。
数据接收方不再使用$on来得知数据变化,而是通过计算属性的特征被动接收。
解决的问题通信组件需同时存在?数据在bus上存储,所以没有要求。
多次绑定?绑定监听都在bus上,不会重复绑定。
数据只在$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对应data,action对应事件,dispatch对应$emit。
同时vuex中组件获取数据的方式正是通过计算属性,那么其实vuex和Flux架构的理解和使用也没有那么难。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/110099.html
摘要:需要注意的是,同样的行为也适用于。这意味着我们必须重新绑定每个事件。组件的由调用它的父组件提供,这意味着所有事件都应该与父组件相关联。 原文链接:Vue.js — Considerations and Tricks showImg(https://segmentfault.com/img/bVbqHOd?w=1600&h=1599); Vue.js 是一个很棒的框架。然而,当你开始构建...
摘要:另外需要说明的是,这里只是冻结了的值,引用不会被冻结,当我们需要数据的时候,我们可以重新给赋值。1 状态共享 随着组件的细化,就会遇到多组件状态共享的情况,Vuex当然可以解决这类问题,不过就像Vuex官方文档所说的,如果应用不够大,为避免代码繁琐冗余,最好不要使用它,今天我们介绍的是vue.js 2.6新增加的Observable API ,通过使用这个api我们可以应对一些简单的跨组件数...
摘要:同时增加了单元测试,使用了,增加了可视化配置权限,增加了自定义布局等等,优化了原先的权限方案,支持不刷新页面更新路由等等功能。虽然它的初衷是为了单元测试的,但正好满足了我们的需求。它会重写浏览器的对象,从而才能拦截所有请求,代理到本地。 前言 vue-element-admin 从 2017.04.17提交第一个 commit 以来,维护至今已经有两年多的时间了了,发布了四十多个版本,...
摘要:同时增加了单元测试,使用了,增加了可视化配置权限,增加了自定义布局等等,优化了原先的权限方案,支持不刷新页面更新路由等等功能。虽然它的初衷是为了单元测试的,但正好满足了我们的需求。它会重写浏览器的对象,从而才能拦截所有请求,代理到本地。前言 vue-element-admin 从 2017.04.17提交第一个 commit 以来,维护至今已经有两年多的时间了了,发布了四十多个版本,收获了三...
摘要:根据组件单向数据流和和事件通信机制,需要由子组件通过事件通知父组件,并在父组件中修改原始的数据,完成状态的更新。 本文同步在个人博客shymean.com上,欢迎关注 写Vue有很长一段时间了,除了常规的业务开发之外,也应该思考和反思一下封装组件的正确方式。以弹窗组件为例,一种实现是在需要模板中引入需要弹窗展示的组件,然后通过一个flag变量来控制弹窗的组件,在业务代码里面会充斥着冗余的弹...
阅读 3204·2021-11-08 13:21
阅读 1193·2021-08-12 13:28
阅读 1404·2019-08-30 14:23
阅读 1923·2019-08-30 11:09
阅读 839·2019-08-29 13:22
阅读 2683·2019-08-29 13:12
阅读 2547·2019-08-26 17:04
阅读 2249·2019-08-26 13:22