Svelte如何通过Store函数传回调获取模态框确认结果
Svelte全局确认模态框回调实现方案
这个需求完全可以实现,不需要调整模态框全局挂载的现有架构,只需要给store补充回调存储和触发逻辑即可,具体实现步骤如下:
1. 改造modal状态仓库
首先给模态框状态新增回调函数字段,同时补充确认/取消的触发方法,修改modal.ts代码如下:
//=== modal.ts === import { writable } from 'svelte/store' // 扩展模态框状态类型,新增回调字段 export const modal = writable({ title: '', message: '', button: '', mode: '', show: false, callback: null as ((confirmed: boolean) => void) | null // 存储用户操作后的回调 }) // 确认操作触发方法 export function confirmModal() { modal.update(state => { // 存在回调则传入true,代表用户确认操作 if (state.callback) state.callback(true) // 关闭模态框,清空回调避免内存泄漏 return { ...state, show: false, callback: null } }) } // 取消/关闭模态框触发方法 export function cancelModal() { modal.update(state => { // 存在回调则传入false,代表用户取消操作 if (state.callback) state.callback(false) // 关闭模态框,清空回调 return { ...state, show: false, callback: null } }) } // 唤起删除确认模态框方法,新增第四个回调参数 export function confirmTrash( modalTitle: string, modalMessage: string, buttonText: string, onAction: (confirmed: boolean) => void ){ modal.set({ title: modalTitle, message: modalMessage, button: buttonText, mode: 'trash', show: true, callback: onAction }) }
2. 调整全局挂载的Modal.svelte组件
给模态框的操作按钮绑定刚才写的确认/取消方法,不要直接修改modal的show状态,代码修改如下:
<!-- === Modal.svelte === --> <script lang="ts"> import { modal, confirmModal, cancelModal } from '$lib/stores/modal' // 其他自定义模态框逻辑保持不变 </script> {#if $modal.show} <h2>{$modal.title}</h2> <p>{$modal.message}</p> <button on:click={confirmModal}>{$modal.button}</button> <!-- 建议补充取消按钮,绑定取消逻辑 --> <button on:click={cancelModal}>取消</button> {/if}
注意:所有模态框关闭路径都要绑定对应方法:如果你的模态框支持点击蒙层关闭、按ESC键关闭,直接把这些关闭事件绑定到
cancelModal方法上,保证用户任何操作都能正确触发回调,不会出现回调悬挂的问题。
3. 业务组件调用
直接在调用confirmTrash时传入回调函数即可拿到用户操作结果:
<!-- === Component.svelte === --> <script lang="ts"> import { confirmTrash } from '$lib/stores/modal' const handleTrash = () => { confirmTrash( '删除确认', '该操作不可恢复,确定要删除该内容吗?', '确认删除', (confirmed) => { if (confirmed) { // 用户点击了删除按钮,在这里执行实际删除逻辑 console.log('执行删除操作') } else { // 用户取消了操作 console.log('用户取消删除') } } ) } </script> <a href="#trash" on:click|preventDefault={handleTrash}>删除</a>
注意给点击事件加
|preventDefault修饰符,避免a标签的默认锚点跳转行为影响页面。
如果你习惯用async/await写法,也可以把confirmTrash改成返回Promise的形式,调用时直接用const confirmed = await confirmTrash(...)即可,逻辑和回调写法完全一致,只是把回调的触发放到Promise的resolve里就行。
内容的提问来源于stack exchange,提问作者Clifton Labrum
相关产品推荐
相关产品推荐

