mirror of
https://github.com/ZiuChen/ZiuChen.github.io.git
synced 2025-08-17 06:49:38 +08:00
feat: 新增 Demo 站点
This commit is contained in:
parent
35932564d9
commit
d1f2269fbe
36
docs/demos/promiseify-post-message/Index.vue
Normal file
36
docs/demos/promiseify-post-message/Index.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
<h2>Home</h2>
|
||||
<iframe ref="iframeRef" src="/demos/promiseify-post-message/inner" frameborder="0" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { registerBase } from './base'
|
||||
|
||||
const iframeRef = ref<HTMLIFrameElement | null>(null)
|
||||
|
||||
onMounted(() => {
|
||||
if (iframeRef.value && iframeRef.value.contentWindow) {
|
||||
registerBase(iframeRef.value.contentWindow)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 隐藏掉窄屏时 fixd 在顶部的 Return to top */
|
||||
:global(.VPLocalNav) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.home {
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
</style>
|
40
docs/demos/promiseify-post-message/Inner.vue
Normal file
40
docs/demos/promiseify-post-message/Inner.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div class="inner">
|
||||
<h2>Inner</h2>
|
||||
<button @click="getUserToken('123456')">getUserToken: {{ userToken }}</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { registerSdk, postMessage } from './sdk'
|
||||
|
||||
registerSdk()
|
||||
|
||||
const userToken = ref('')
|
||||
|
||||
async function getUserToken(userId: string) {
|
||||
const token = await postMessage({
|
||||
namespace: 'user',
|
||||
action: 'getUserToken',
|
||||
payload: {
|
||||
userId
|
||||
}
|
||||
})
|
||||
|
||||
if (token) {
|
||||
userToken.value = token as string
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 隐藏掉窄屏时 fixd 在顶部的 Return to top */
|
||||
:global(.VPLocalNav) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.inner {
|
||||
padding: 25px;
|
||||
}
|
||||
</style>
|
43
docs/demos/promiseify-post-message/base.ts
Normal file
43
docs/demos/promiseify-post-message/base.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import get from 'lodash-es/get'
|
||||
import { FuncMap } from './types'
|
||||
import { JSBridgeParams } from './sdk'
|
||||
|
||||
/**
|
||||
* 注册 SDK 基座
|
||||
*/
|
||||
export function registerBase(target: Window) {
|
||||
window.addEventListener('message', async (e) => {
|
||||
const params = e.data as JSBridgeParams<any>
|
||||
const namespace = params.namespace
|
||||
const action = params.action
|
||||
const callback = get(callbackMap, [namespace, action])
|
||||
if (callback) {
|
||||
const result = await callback(params.payload)
|
||||
target.postMessage(
|
||||
{
|
||||
params,
|
||||
result
|
||||
},
|
||||
'*'
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type Namespace = keyof FuncMap
|
||||
type Action = keyof FuncMap[Namespace]
|
||||
type Payload = FuncMap[Namespace][Action] extends { payload: infer P } ? P : never
|
||||
type Result = FuncMap[Namespace][Action] extends { result: infer R } ? R : never
|
||||
|
||||
const callbackMap: Record<
|
||||
Namespace,
|
||||
{
|
||||
[key in Action]: (payload: Payload) => Result
|
||||
}
|
||||
> = {
|
||||
user: {
|
||||
getUserToken: ({ userId }) => {
|
||||
return 'token:' + userId
|
||||
}
|
||||
}
|
||||
}
|
17
docs/demos/promiseify-post-message/index.md
Normal file
17
docs/demos/promiseify-post-message/index.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
layout: page
|
||||
navbar: false
|
||||
sidebar: false
|
||||
aside: false
|
||||
footer: false
|
||||
---
|
||||
|
||||
# Promiseify PostMessage
|
||||
|
||||
将 postMessage 消息通信 Promise 化
|
||||
|
||||
<script setup>
|
||||
import DemoComponent from './Index.vue'
|
||||
</script>
|
||||
|
||||
<DemoComponent />
|
14
docs/demos/promiseify-post-message/inner.md
Normal file
14
docs/demos/promiseify-post-message/inner.md
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
layout: page
|
||||
navbar: false
|
||||
sidebar: false
|
||||
aside: false
|
||||
footer: false
|
||||
outline: false
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import DemoComponent from './Inner.vue'
|
||||
</script>
|
||||
|
||||
<DemoComponent />
|
46
docs/demos/promiseify-post-message/sdk.ts
Normal file
46
docs/demos/promiseify-post-message/sdk.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { FuncMap } from './types'
|
||||
|
||||
export interface JSBridgeParams<T extends keyof FuncMap> {
|
||||
namespace: T
|
||||
action: keyof FuncMap[T]
|
||||
payload: FuncMap[T][keyof FuncMap[T]] extends { payload: infer P } ? P : never
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册 SDK 应用
|
||||
*/
|
||||
export function registerSdk() {
|
||||
window.addEventListener('message', messageHandler)
|
||||
}
|
||||
|
||||
const postMessageCallbackMap = new Map()
|
||||
|
||||
function messageHandler({ data, type }: MessageEvent) {
|
||||
if (type === 'message') {
|
||||
const { params, result } = data
|
||||
const key = [params.namespace, params.action, params.id].join('.')
|
||||
const callback = postMessageCallbackMap.get(key)
|
||||
if (callback) {
|
||||
callback(result)
|
||||
postMessageCallbackMap.delete(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let uniqueId = 0
|
||||
|
||||
export function postMessage<T extends keyof FuncMap>(
|
||||
params: JSBridgeParams<T>
|
||||
): Promise<FuncMap[T][keyof FuncMap[T]] extends { result: infer R } ? R : never> {
|
||||
return new Promise((resolve) => {
|
||||
if (window.parent) {
|
||||
const id = uniqueId++
|
||||
const key = [params.namespace, params.action, id].join('.')
|
||||
postMessageCallbackMap.set(key, resolve)
|
||||
const _params = structuredClone(params)
|
||||
// @ts-expect-error - id is private field.
|
||||
_params.id = id
|
||||
window.parent.postMessage(_params, '*')
|
||||
}
|
||||
})
|
||||
}
|
11
docs/demos/promiseify-post-message/types.ts
Normal file
11
docs/demos/promiseify-post-message/types.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* 基座与 SDK 共享同一份类型定义
|
||||
*/
|
||||
export interface FuncMap {
|
||||
user: {
|
||||
getUserToken: {
|
||||
payload: { userId: string }
|
||||
result: string
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user