Skip to content

Commit b0a4941

Browse files
committed
feat: add useBroadcastChannelPlugin from @vue-hooks-plus/use-request-plugins
1 parent eda4900 commit b0a4941

File tree

10 files changed

+345
-3
lines changed

10 files changed

+345
-3
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@
7373
"vue-tsc": "1.0.9",
7474
"vue-typical": "^2.1.0",
7575
"pinia":"^2.0.34",
76+
"broadcast-channel":"^5.1.0",
7677
"three":"0.147.0",
78+
"axios": "^0.24.0",
7779
"vue-demi": "^0.13.11"
7880
},
7981
"lint-staged": {

packages/hooks/docs/.vitepress/router.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ const useRequestPlugins = [
170170
text: '全局请求状态管理',
171171
link: '/useRequest/plugins/fetchsing/',
172172
},
173+
{
174+
text: "同源跨窗口广播",
175+
link: "/useRequest/plugins/broadcastChannel/"
176+
}
173177
],
174178
},
175179
]
@@ -179,9 +183,13 @@ const useRequestPluginsEN = [
179183
text: 'UseRequest External Plugins',
180184
items: [
181185
{
182-
text: 'Global Fetching',
186+
text: 'global Fetching',
183187
link: '/en/useRequest/plugins/fetchsing/',
184188
},
189+
{
190+
text: "broadcastChannel",
191+
link: "/en/useRequest/plugins/broadcastChannel/"
192+
}
185193
],
186194
},
187195
]
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<template>
2+
<div>Current: {{ loading ? 'loading..' : data }}</div>
3+
4+
<div>
5+
<vhp-button @click="refresh()">Refresh</vhp-button>
6+
<div style="margin-top: 8px;">
7+
<h4>Desc</h4>
8+
<input v-model="input">
9+
<vhp-button style="margin-left: 4px;" @click="submit()">Send</vhp-button>
10+
</div>
11+
</div>
12+
<div>
13+
<h3>Channel History:</h3>
14+
<div v-for="(item, index) in other" :key="index">{{ item }}</div>
15+
</div>
16+
</template>
17+
18+
<script lang="ts" setup>
19+
import { ref } from 'vue'
20+
import { useRequest } from 'vue-hooks-plus'
21+
import { useBroadcastChannelPlugin } from '@vue-hooks-plus/use-request-plugins'
22+
23+
function getUsername(params: { desc: string }): Promise<string> {
24+
return new Promise(resolve => {
25+
setTimeout(() => {
26+
resolve(`${params.desc}-${String(Date.now())}`)
27+
}, 1000)
28+
})
29+
}
30+
31+
const other = ref<string[]>([])
32+
const input = ref('')
33+
const desc = ref('good')
34+
35+
const submit = () => {
36+
desc.value = `send-other-${input.value}`
37+
}
38+
39+
const { data, loading, refresh } = useRequest(
40+
() => getUsername({ desc: desc.value }),
41+
{
42+
refreshDeps: true,
43+
broadcastChannel: 'nice-broadcastChannel',
44+
onBroadcastChannel: (message: any, channel: any) => {
45+
other.value.push(message.data)
46+
},
47+
},
48+
[useBroadcastChannelPlugin],
49+
)
50+
</script>
51+
52+
<style scoped lang="less"></style>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
map:
3+
# 映射到docs的路径
4+
path: /useRequest/plugins/broadcastChannel
5+
source:
6+
path: https://github.com/InhiblabCore/vue-hooks-plus/blob/master/packages/use-request-plugins/src/useBroadcastChannelPlugin/index.ts
7+
demoPath: https://github.com/InhiblabCore/vue-hooks-plus/blob/master/packages/hooks/src/useRequest/docs/plugins/broadcastChannel/demo/demo.vue
8+
---
9+
10+
# BroadcastChannel(Experimental)
11+
12+
> VERY IMPORTANT: This utility is currently in an experimental stage. This means that breaking changes will happen in minor AND patch releases. Use at your own risk. If you choose to rely on this in production in an experimental stage, please lock your version to a patch-level version to avoid unexpected breakages.
13+
14+
`useBroadcastChannelPlugin` is a utility for broadcasting and syncing the state of your useRequest State between browser tabs/windows with the same origin.
15+
16+
## Feature
17+
18+
- Act as the intermediate state for all requests, where users can operate on the collected request results.
19+
20+
## Install
21+
22+
```bash
23+
24+
# It is necessary to ensure that the application contains `broadcast-channel` .
25+
26+
1. npm i broadcast-channel
27+
28+
2. npm i @vue-hooks-plus/use-request-plugins
29+
30+
```
31+
32+
## Demo
33+
34+
<demo src="./demo/demo.vue"
35+
language="vue"
36+
title="Same origin cross window communication"
37+
desc="Opening the same new window, sending and refreshing data will result in data being transmitted across windows."> </demo>
38+
39+
## API
40+
41+
```typescript
42+
import { useRequest } from 'vue-hooks-plus'
43+
import { useBroadcastChannelPlugin } from '@vue-hooks-plus/use-request-plugins'
44+
45+
useRequest(
46+
service,
47+
{
48+
broadcastChannel?: string
49+
broadcastChannelKey?: string
50+
broadcastChannelOptions?: BroadcastChannelOptions
51+
customPostMessage?: (postMessage: (msg?: any) => Promise<void>, channel?: BroadcastChannel) => void
52+
onBroadcastChannel?: (value?: MessageType, channel?: BroadcastChannel, setFetchState?: Fetch<any, []>['setFetchState']) => void
53+
},
54+
[useBroadcastChannelPlugin],
55+
)
56+
```
57+
58+
## Options
59+
60+
| Property | Description | Type |
61+
| --- | --- | --- |
62+
| broadcastChannel | Required, the name of the channel, which must be the same as the channel name to receive the same frequency data. | `string` |
63+
| broadcastChannelKey | Non mandatory identifier used to distinguish different application types. | `string` |
64+
| broadcastChannelOptions | The configuration item for `broadcast-channel` has a default configuration of `{webWorkerSupport: false}` | `BroadcastChannelOptions` |
65+
| customPostMessage | User defined collection and sending of data. The default sending method is `type`, `data`, `param`, `error` | `(potMessage: (msg?: any)=>Promise<void>, channel?: BroadcastChannel) => void` |
66+
| onBroadcastChannel | Monitor and collect the same frequency data sent by other applications (including multiple windows of the same application) | `(value?: MessageType, channel?: BroadcastChannel, setFetchState?: Fetch<any, []>['setFetchState']) => void` |
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
map:
3+
# 映射到docs的路径
4+
path: /useRequest/plugins/broadcastChannel
5+
source:
6+
path: https://github.com/InhiblabCore/vue-hooks-plus/blob/master/packages/use-request-plugins/src/useBroadcastChannelPlugin/index.ts
7+
demoPath: https://github.com/InhiblabCore/vue-hooks-plus/blob/master/packages/hooks/src/useRequest/docs/plugins/broadcastChannel/demo/demo.vue
8+
---
9+
10+
# BroadcastChannel(实验)
11+
12+
> 非常重要:此实用程序目前处于试验阶段。这意味着重大更改将在次要和补丁版本中发生。使用风险自负。如果您选择在实验阶段的生产中依赖它,请将您的版本锁定为补丁级别版本以避免意外损坏
13+
14+
基于 `broadcast-channel` 实现的 `useRequest` 的插件,用于在具有`相同来源`的浏览器选项卡/窗口之间广播和同步 `useRequest` 的状态。
15+
16+
## 功能
17+
18+
- `broadcast-channel` 功能的集成。
19+
- 相同来源的浏览器选项卡/窗口之间数据的广播和同步。
20+
- 支持自定义信息发送和 `channel` 的使用。
21+
22+
## 安装
23+
24+
```bash
25+
26+
# 需要保证应用含有 `broadcast-channel`。
27+
28+
1. npm i broadcast-channel
29+
30+
2. npm i @vue-hooks-plus/use-request-plugins
31+
32+
```
33+
34+
## 代码演示
35+
36+
<demo src="./demo/demo.vue"
37+
language="vue"
38+
title="同源跨窗口通信"
39+
desc="打开一个同样的新窗口,发送和刷新数据会发现数据跨窗口传递。"> </demo>
40+
41+
## API
42+
43+
```typescript
44+
import { useRequest } from 'vue-hooks-plus'
45+
import { useBroadcastChannelPlugin } from '@vue-hooks-plus/use-request-plugins'
46+
47+
useRequest(
48+
service,
49+
{
50+
broadcastChannel?: string
51+
broadcastChannelKey?: string
52+
broadcastChannelOptions?: BroadcastChannelOptions
53+
customPostMessage?: (postMessage: (msg?: any) => Promise<void>, channel?: BroadcastChannel) => void
54+
onBroadcastChannel?: (value?: MessageType, channel?: BroadcastChannel, setFetchState?: Fetch<any, []>['setFetchState']) => void
55+
},
56+
[useBroadcastChannelPlugin],
57+
)
58+
```
59+
60+
## Options
61+
62+
| Property | Description | Type |
63+
| --- | --- | --- |
64+
| broadcastChannel | 必填,频道的名称,需要频道名称一样才能接收到同频数据。 | `string` |
65+
| broadcastChannelKey | 非必填,用于区分不同应用类型的标识符。 | `string` |
66+
| broadcastChannelOptions | `broadcast-channel` 的配置项,默认配置`{ webWorkerSupport:false }` | `BroadcastChannelOptions` |
67+
| customPostMessage | 用户自定义收集发送数据,默认发送方式为 `type`,`data`,`params`,`error` | `(postMessage: (msg?: any) => Promise<void>, channel?: BroadcastChannel) => void` |
68+
| onBroadcastChannel | 监听收集其他应用(包括同一应用的多窗口)发送的同频数据 | `(value?: MessageType, channel?: BroadcastChannel, setFetchState?: Fetch<any, []>['setFetchState']) => void` |
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
<template>
22
<div style="margin-top: 16px;">读取值:{{ loading ? 'loading' : data }}</div>
3+
<vhp-button @click="refresh()">刷新</vhp-button>
34
</template>
45

56
<script lang="ts" setup>
67
import { useRequest } from 'vue-hooks-plus'
78
89
function getUsername(): Promise<string> {
10+
console.log('刷新')
11+
912
return new Promise((resolve, reject) => {
1013
setTimeout(() => {
1114
resolve(`${String(Date.now())}`)
1215
}, 1000)
1316
})
1417
}
1518
16-
const { data, loading } = useRequest(() => getUsername(), {
19+
const { data, loading, refresh } = useRequest(() => getUsername(), {
1720
refreshOnWindowFocus: true,
21+
focusTimespan: 0,
22+
debounceWait: 500,
1823
})
1924
</script>
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import useBroadcastChannelPlugin from './useBroadcastChannelPlugin'
12
import useFetchingPlugin from './useFetchingPlugin'
23

3-
export { useFetchingPlugin }
4+
export { useFetchingPlugin, useBroadcastChannelPlugin }
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { useBroadcastChannelPlugin } from './useBroadcastChannel'
2+
3+
export default useBroadcastChannelPlugin
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { ref } from 'vue';
2+
import { BroadcastChannel, BroadcastChannelOptions } from 'broadcast-channel'
3+
import { UseRequestPlugin, UseRequestFetchState } from "@vue-hooks-plus/use-request/dist/types/types";
4+
import Fetch from '@vue-hooks-plus/use-request/dist/types/Fetch';
5+
6+
type MessageType = UseRequestFetchState<any, any> & { type: string }
7+
8+
export interface BroadcastChannelType {
9+
broadcastChannel?: string
10+
broadcastChannelKey?: string
11+
broadcastChannelOptions?: BroadcastChannelOptions
12+
customPostMessage?: (postMessage: (msg?: any) => Promise<void>, channel?: BroadcastChannel, setFetchState?: Fetch<any, []>['setFetchState']) => void
13+
onBroadcastChannel?: (value?: MessageType, channel?: BroadcastChannel, setFetchState?: Fetch<any, []>['setFetchState']) => void
14+
}
15+
16+
export const useBroadcastChannelPlugin: UseRequestPlugin<any, [], BroadcastChannelType> = (fetchInstance, { broadcastChannel, broadcastChannelKey, broadcastChannelOptions = { webWorkerSupport: false }, customPostMessage, onBroadcastChannel }) => {
17+
let transaction = false
18+
const channel = ref<BroadcastChannel>()
19+
20+
const tx = (callback: () => void) => {
21+
transaction = true
22+
callback()
23+
transaction = false
24+
}
25+
26+
if (broadcastChannel) {
27+
channel.value = new BroadcastChannel(broadcastChannel, broadcastChannelOptions)
28+
29+
if (customPostMessage) {
30+
customPostMessage(channel.value?.postMessage, channel.value)
31+
}
32+
33+
channel.value.onmessage = message => {
34+
tx(() => {
35+
onBroadcastChannel?.(message, channel.value, fetchInstance.setFetchState)
36+
})
37+
}
38+
}
39+
40+
return {
41+
onSuccess: (data, params) => {
42+
if (broadcastChannel && transaction === false && !customPostMessage) {
43+
channel.value?.postMessage({
44+
type: broadcastChannelKey ?? broadcastChannel,
45+
data,
46+
params,
47+
error: null
48+
})
49+
}
50+
},
51+
onError: (error, params) => {
52+
if (broadcastChannel && transaction === false && !customPostMessage) {
53+
channel.value?.postMessage({
54+
type: broadcastChannelKey ?? broadcastChannel,
55+
params,
56+
error
57+
})
58+
}
59+
}
60+
}
61+
62+
}

0 commit comments

Comments
 (0)