前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端-vue数据传递: 我有特殊的实现技巧

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

作者头像
grain先森
发布2019-03-29 11:03:12
7270
发布2019-03-29 11:03:12
举报
文章被收录于专栏:grain先森grain先森

作者:toBeTheLight   www.cnblogs.com/front-Thinking/p/4364337.html

前言

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

有这么几种数据传递方式,vuex、props、eventBus和特殊的eventBus。

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 改变。

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.11.19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • vuex
  • props
    • demo
      • 限制
      • eventBus
        • demo
          • 问题
          • 特殊的eventBus?
            • demo
              • 不同
                • 解决的问题
                • 探讨
                  • 为什么使用计算属性
                    • 为什么要用事件
                    • 简化版的vuex
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档