首先, 咱们一般说数据传递, 组件通讯什么什么的, 我认为能够分红两种场景:javascript
页面和页面之间vue
组件和组件之间java
无论什么场景, 在使用 Vue 的时候, 通常咱们有下面 5 种选择去实现数据通讯.vuex
vuex缓存
storagesession
props函数
eventthis
URL queryStringurl
咱们在选择通讯方案的时候, 好比说肯定 列表页如何把每一项的 id 传递给 详情页的时候,
通常要考虑什么问题? 你是直接全套都是 vuex, 仍是说喜欢使用 sessionStorage?code
通常咱们要考虑下面的几个问题:
页面是否能够刷新
页面是否能够分享 (或者说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 是状态管理, 不是保存常量的地方.