资讯专栏INFORMATION COLUMN

Vue 组件通信的解决方案

liukai90 / 1859人阅读

摘要:数据通信首先我们通常说数据传递组件通信什么什么的我认为可以分成两种场景页面和页面之间组件和组件之间通信方案不管什么场景在使用的时候一般我们有下面种选择去实现数据通信选择通信方案我们在选择通信方案的时候比如说确定列表页如何把每一项的传递给详情

数据通信

首先, 我们通常说数据传递, 组件通信什么什么的, 我认为可以分成两种场景:

页面和页面之间

组件和组件之间

通信方案

不管什么场景, 在使用 Vue 的时候, 一般我们有下面 5 种选择去实现数据通信.

vuex

storage

props

event

URL queryString

选择通信方案

我们在选择通信方案的时候, 比如说确定 列表页如何把每一项的 id 传递给 详情页的时候,
一般要考虑什么问题? 你是直接全套都是 vuex, 还是说喜欢使用 sessionStorage?

一般我们要考虑下面的几个问题:

页面是否可以刷新

页面是否可以分享 (或者说URL 是否要求 RESTful)

数据更新之后, 所有使用此数据的组件是否都需要响应更新

分析

先说 "页面和页面之间的通信场景", 首先上面的 5 种方案, 我们可选的有:

vuex, storage, URL queryString.

然后分析一下, 每一种方案, 它对上面的 3个问题, 是不是很好的解决掉了:
备注:
页面通信场景不会要求实时响应, 因为就算下个页面的确是实时响应, 你也看不见,
所以主要看 "刷新" 和 "分享"

vuex: 不能刷新, 不能分享
storage: 不能分享
url: 能刷新, 能分享

这样看来, url queryString 的方式是 "页面通信场景" 中的最佳选择, 但是我依旧有疑虑:

我始终觉得把跳转信息, 暴露给用户, 是很不好的事情; (心理问题, 可以克服)

url 的长度限制; 这个无所谓的, 2k, 你再怎么传递, 我都不会觉得你会出现超过 2k 的情况

url 需要拼接, 这个拼接是否麻烦? 也不麻烦, 只是对象转字符串.

这样每个页面都需要在进入的时候先解析一下 queryString, 这样是不是增加了麻烦的程度
也可以通过 mixins 来操作. 聚合到 mixins, 况且也不一定很多.

所以我们可以选择 "url queryString" 作为 "页面和页面通信场景" 中的通信方案.
以后你就可以这样用了:

比如列表页面跳转到详情页要带一个 id

    this.$router.push({
        path: "detail",
        query: {
            id
        }
    })

你的 url 会始终长这样:

https://abc.com/#/?id=123

备注: 如果你的页面不能刷新和分享, 你完全可以三种方案随便选, 爱谁谁.

重点: url queryString 的方式, 有一个问题解决不了:

从详情页到订单页, 通过 queryString 带了商品信息过来, 假设此时 url 长这样:
    order/?goods=xxx
订单页面有一个收货地址栏, 点击可以进入地址编辑页面, 此时的 url 不会带参数的(你可以试试带一下看多麻烦)
    address-edit/
地址编辑页面有一个保存按钮, 点击会返回到订单页面
    order/

so, url queryString 丢了.

我目前的解决方案:
针对这种存在多入口的页面, 一定要在进入它的第一时间, 先把 queryString 存起来.
并且做如下判断:

if (// 存在 queryString) {
    // use queryString
} else {
    // use storage
}

但是这种方式还是搞不定 从地址编辑页返回到订单页, 用户此时分享订单页, 分享出去的玩意肯定会是错的.

现在来说下 "组件和组件之间的通信场景"
上面的 5 种方案, 可以选择 vuex, event, props, storage

先看下 刷新, 分享和实时响应
vuex, 不能刷新
event, props 能刷新能分享
storage 不能分享 & 实时.

解释:
为什么 vuex 在这里还是不能刷新
因为如果使用的 state 里面的值是其他页面设置的而不是 init 就存在的, 刷新丢值.
为什么 event, props 可以做到防刷新防分享
因为这两个玩意是程序运行它就生效的, 它也可以做到实时更新.
storage 虽然在存的时候有一个事件, 但是这太 trick 了.

所以我们选择的是 event, props?

分析一下吧.
组件通信可以分成两种, 父子, 同辈.

父子之间呢:
父传子: props
子传父: $emit(event)

这就是 "props down, events up";

但是其实还有:
父传子: this.$refs.xxx
子传父: this.$parent.xxx

还有: 自定义 v-model

还有: 让 props 是一个对象.

同辈之间: event-bus.

所以这就完了? 啥都没有了? 嗯, 就这样.

思考

关于 vuex 的应用场景的考虑
不是应该所有的组件, 路由之间的数据传递都应该通过 vuex, 当同时存在两种方式可以选择的时候,选择 vuex 的唯一理由只有一个:

需要响应式的状态

why?

因为 vuex 虽然有辅助函数, 但是用起来还是要 引入, 定义. 而且真的是一刷新页面就挂了. 

可以通过监听 beforeunload 事件, 在其中缓存 state, 然后在 onload 事件再恢复, 这样可以避免掉vuex 的丢值.

没有必要追求全项目统一的一种通信方式, 理论上你不考虑刷新分享, 全项目都用 vuex, 什么事情也不会有的.

vuex 是状态管理, 不是保存常量的地方.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/87119.html

相关文章

  • vue中8种组件通信方式, 值得收藏!

    摘要:一父组件通过的方式向子组件传递数据,而通过子组件可以向父组件通信。而且只读,不可被修改,所有修改都会失效并警告。 之前写了一篇关于vue面试总结的文章, 有不少网友提出组件之间通信方式还有很多, 这篇文章便是专门总结组件之间通信的 vue是数据驱动视图更新的框架, 所以对于vue来说组件间的数据通信非常重要,那么组件之间如何进行数据通信的呢?首先我们需要知道在vue中组件之间存在什么样...

    BicycleWarrior 评论0 收藏0
  • Vue 组件通信方式

    摘要:本身提供哪几种通信方式首先灵感源于,支持双向绑定,本质还是单向数据流。跟一样,组件间最基本的数据流是通过向子组件传递数据。但是在却很少使用,因为组件可以自定义事件,即后面的组件间通信方式其实就是订阅发布模式。 例子是在 jsrun.net 平台编写,不支持移动端平台,所以本文建议在 PC 端进行阅读。 Vue 是数据驱动的视图框架,那么组件间的数据通信是必然的事情,那么组件间如何进行数...

    hss01248 评论0 收藏0
  • vue组件通信六种方式(完整版)

    摘要:本文总结了组件间通信的几种方式,如和,以通俗易懂的实例讲述这其中的差别及使用场景,希望对小伙伴有些许帮助。状态改变提交操作方法。 前言 组件是 vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。一般来说,组件可以有以下几种关系:showImg(https://segmentfault.com/img/remote/146000001...

    frontoldman 评论0 收藏0
  • Vue项目总结】组件通信处理方案

    摘要:组件之间的通信是我们在项目中常常碰到的,而选择合适的通信方式尤为重要,这里总结下作者在实际项目中所运用到的通信方案,如有遗漏,请大家见谅。示例效果如下兄弟组件同级别组件相互间的通信,我们可以使用或着。 Vue组件之间的通信是我们在项目中常常碰到的,而选择合适的通信方式尤为重要,这里总结下作者在实际项目中所运用到的通信方案,如有遗漏,请大家见谅。文章代码具体见DEMO;文章首发于imon...

    TerryCai 评论0 收藏0
  • vue2.0开发聊天程序(三)组件通信

    摘要:我在中写了这段代码在组件被创建时候将会执行此函数相当于进入页面的自执行使用方法监听属性并执行一个回调函数按道理在元素被创建的时候,会将监听到的值赋给并且打印。 天地不仁以万物为刍狗,宇宙无义视众生如蝼蚁                  ——萧鼎和我 上一节列出了5个关键点,第一个路由已经解决了,接下来解决第二个问题: 组件的通信问题 一、组件的关系 组件之间的关系无非就是两种父子关系...

    ddongjian0000 评论0 收藏0
  • VUE前端工程化( 一)(掌握组件多种通信及数据同步)

    摘要:是一个事件,它向下传播到当前实例的所有后代。由于后代扩展为多个子树,事件传播将会遵循许多不同的路径。组件修改实现递归地在父链上传播事件。 组件通信 父子组件通信 父传子 props属性 子传父 $emit事件 这两种官方文档里有很详细的介绍就不解释了 还是举个栗子: //parent.vue父组件 parent: {{money}} ...

    Tony_Zby 评论0 收藏0

发表评论

0条评论

liukai90

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<