Appearance
服务式组件
Dialog、Toast、Notify、ActionSheet 和 Loading 的 manager 都依赖页面中的 service 宿主。manager 负责共享状态,不返回等待用户选择的 Promise;业务结果继续监听宿主事件。多个同类宿主、跨页面所有权和 App 原生层级仍需目标平台实机验证。
1. ActionSheet
manager 的返回值是状态快照或通知项;确认、取消、选择、关闭等用户结果以宿主事件为边界。页面卸载时只清理由当前页面持有的服务状态。
vue
<template>
<view class="service-xtf-action-sheet">
<XtfActionSheet service @select="onResult" @cancel="onCancel" />
<view class="service-actions">
<button class="service-button" @click="openService">显示</button>
<button class="service-button" @click="updateService">更新</button>
<button class="service-button" @click="closeService">关闭或清理</button>
</view>
</view>
</template>
<script setup lang="uts">
import { onUnmounted } from "vue"
import XtfActionSheet from "@/uni_modules/xtf-linkuiunix/components/xtf-action-sheet/xtf-action-sheet.uvue"
import { actionSheetManager } from "@/uni_modules/xtf-linkuiunix/components/xtf-action-sheet/service.uts"
function openService(): void { actionSheetManager.show({ title: "账单操作", actions: [{ key: "edit", label: "编辑" }, { key: "delete", label: "删除", danger: true }] }) }
function updateService(): void { actionSheetManager.update({ title: "请选择后续操作" }) }
function closeService(): void { actionSheetManager.close() }
function onResult(payload: any): void { console.log("ActionSheet 结果由宿主事件返回", payload) }
function onCancel(payload: any): void { console.log("ActionSheet 已取消", payload) }
onUnmounted(() => { actionSheetManager.close() })
</script>
<style>
.service-xtf-action-sheet { display: flex; flex-direction: column; padding: 24rpx; }
.service-actions { display: flex; flex-direction: row; flex-wrap: wrap; }
.service-button { margin-right: 12rpx; margin-bottom: 12rpx; }
</style>2. Dialog
manager 的返回值是状态快照或通知项;确认、取消、选择、关闭等用户结果以宿主事件为边界。页面卸载时只清理由当前页面持有的服务状态。
vue
<template>
<view class="service-xtf-dialog">
<XtfDialog service @confirm-detail="onResult" @cancel="onCancel" />
<view class="service-actions">
<button class="service-button" @click="openService">显示</button>
<button class="service-button" @click="updateService">更新</button>
<button class="service-button" @click="closeService">关闭或清理</button>
</view>
</view>
</template>
<script setup lang="uts">
import { onUnmounted } from "vue"
import XtfDialog from "@/uni_modules/xtf-linkuiunix/components/xtf-dialog/xtf-dialog.uvue"
import { dialogManager } from "@/uni_modules/xtf-linkuiunix/components/xtf-dialog/service.uts"
function openService(): void { dialogManager.confirm({ title: "确认提交", message: "账单将同步到共享账本" }) }
function updateService(): void { dialogManager.update({ message: "同步后将通知所有成员" }) }
function closeService(): void { dialogManager.close() }
function onResult(payload: any): void { console.log("旧请求确认后重入新请求", payload); dialogManager.alert({ title: "后续步骤", message: "此新请求不会被旧确认流程关闭" }) }
function onCancel(): void { console.log("Dialog 已取消") }
onUnmounted(() => { dialogManager.close() })
</script>
<style>
.service-xtf-dialog { display: flex; flex-direction: column; padding: 24rpx; }
.service-actions { display: flex; flex-direction: row; flex-wrap: wrap; }
.service-button { margin-right: 12rpx; margin-bottom: 12rpx; }
</style>3. Notify
manager 的返回值是状态快照或通知项;确认、取消、选择、关闭等用户结果以宿主事件为边界。页面卸载时只清理由当前页面持有的服务状态。
vue
<template>
<view class="service-xtf-notify">
<XtfNotify service @close="onResult" />
<view class="service-actions">
<button class="service-button" @click="openService">显示</button>
<button class="service-button" @click="updateService">追加警告</button>
<button class="service-button" @click="closeService">关闭或清理</button>
</view>
</view>
</template>
<script setup lang="uts">
import { onUnmounted } from "vue"
import XtfNotify from "@/uni_modules/xtf-linkuiunix/components/xtf-notify/xtf-notify.uvue"
import { notifyManager } from "@/uni_modules/xtf-linkuiunix/components/xtf-notify/service.uts"
const ownedIds = [] as Array<string>
function remember(item: UTSJSONObject): void { const id = item["id"] as string; if (!ownedIds.includes(id)) ownedIds.push(id) }
function openService(): void { const first = notifyManager.success({ title: "同步完成", message: "账单已更新" }); const duplicate = notifyManager.success({ title: "同步完成", message: "账单已更新" }); remember(first); remember(duplicate); console.log("dedup 保留 id", first["id"], duplicate["id"]) }
function updateService(): void { remember(notifyManager.warning("仍有一条账单待核对")) }
function closeService(): void { ownedIds.forEach((id: string) => notifyManager.remove(id)); ownedIds.length = 0 }
function onResult(payload: any): void { console.log("Notify 关闭结果由宿主事件返回", payload) }
onUnmounted(() => { closeService() })
</script>
<style>
.service-xtf-notify { display: flex; flex-direction: column; padding: 24rpx; }
.service-actions { display: flex; flex-direction: row; flex-wrap: wrap; }
.service-button { margin-right: 12rpx; margin-bottom: 12rpx; }
</style>4. Toast
manager 的返回值是状态快照或通知项;确认、取消、选择、关闭等用户结果以宿主事件为边界。页面卸载时只清理由当前页面持有的服务状态。
vue
<template>
<view class="service-xtf-toast">
<XtfToast service @close="onResult" />
<view class="service-actions">
<button class="service-button" @click="openService">显示</button>
<button class="service-button" @click="updateService">更新并推进下一项</button>
<button class="service-button" @click="closeService">关闭或清理</button>
</view>
</view>
</template>
<script setup lang="uts">
import { onUnmounted } from "vue"
import XtfToast from "@/uni_modules/xtf-linkuiunix/components/xtf-toast/xtf-toast.uvue"
import { toastManager } from "@/uni_modules/xtf-linkuiunix/components/xtf-toast/service.uts"
function openService(): void { toastManager.success("保存成功", { mode: "queue", duration: 0 }); toastManager.success("同步完成", { mode: "queue", duration: 0 }) }
function updateService(): void { toastManager.update({ message: "当前项处理完成", duration: 0 }); toastManager.clear(); console.log("clear 后下一 tick 推进队列") }
function closeService(): void { toastManager.clearAll(); console.log("clearAll 清空当前与队列") }
function onResult(payload: any): void { console.log("Toast 关闭结果由宿主事件返回", payload) }
onUnmounted(() => { toastManager.clearAll() })
</script>
<style>
.service-xtf-toast { display: flex; flex-direction: column; padding: 24rpx; }
.service-actions { display: flex; flex-direction: row; flex-wrap: wrap; }
.service-button { margin-right: 12rpx; margin-bottom: 12rpx; }
</style>5. Loading
manager 的返回值是状态快照或通知项;确认、取消、选择、关闭等用户结果以宿主事件为边界。页面卸载时只清理由当前页面持有的服务状态。
vue
<template>
<view class="service-xtf-loading">
<XtfLoading service />
<view class="service-actions">
<button class="service-button" @click="openService">显示</button>
<button class="service-button" @click="updateService">更新</button>
<button class="service-button" @click="closeService">关闭或清理</button>
</view>
</view>
</template>
<script setup lang="uts">
import { onUnmounted } from "vue"
import XtfLoading from "@/uni_modules/xtf-linkuiunix/components/xtf-loading/xtf-loading.uvue"
import { loadingManager } from "@/uni_modules/xtf-linkuiunix/libs/loading-manager.uts"
function openService(): void { const state = loadingManager.show({ text: "正在同步", mode: "fullscreen", overlay: true }); console.log("Loading 已显示", state) }
function updateService(): void { const state = loadingManager.update({ text: "正在生成报表" }); console.log("Loading 已更新", state) }
function closeService(): void { const state = loadingManager.hide(); console.log("Loading 已关闭", state) }
onUnmounted(() => { loadingManager.hide() })
</script>
<style>
.service-xtf-loading { display: flex; flex-direction: column; padding: 24rpx; }
.service-actions { display: flex; flex-direction: row; flex-wrap: wrap; }
.service-button { margin-right: 12rpx; margin-bottom: 12rpx; }
</style>请求重入、队列与去重
- xtf-dialog:服务式 Dialog 按请求隔离:beforeClose 等异步守卫未结束时再次 show/confirm,或在 confirm-detail、cancel-detail、action、输入/选项事件中重入新请求,旧请求的后续关闭与状态写回不会作用到新请求。update 修改当前请求,show 才创建新请求;内部请求标识不是业务 API。
- xtf-toast:toastManager.clear()(close 的同义入口)只关闭当前项,保留 queue,并在 nextTick 推进下一项;推进中重复 clear 不跳过队列项。clearAll() 关闭当前项、清空队列并使待推进任务失效,卸载清理应按业务所有权选择。非 queue 的 show 会替换当前项并清空旧队列。
- xtf-notify:相同 type/variant/title/message/description 在 240ms 内连续调用且旧项仍保留时会 dedup,返回同一保留通知项及其 id,可用 notifyManager.remove(id) 精确移除;它不是新通知句柄或 Promise。旧项已移除后再调用会创建新 id,notifyManager.clear() 清空全部通知并重置去重记录;只清理本页通知时应按持有的 id 调用 remove。