You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
npm install vue-nice-modal
# or
yarn add vue-nice-modal
# or
pnpm add vue-nice-modal
使用
import{create}from'vue-nice-modal';importMyModalfrom'./MyModal.vue';constmyModal=create(MyModal);myModal.show({title: 'Hello, world!',content: 'This is a nice modal.',}).then((result)=>{console.log('Confirmed! Result:',result);}).catch((error)=>{console.error('Rejected! Error:',error);});
自定义 Modal 组件
<scriptsetuplang="ts">import{Dialog}from'vant';import{INiceModalHandlers}from'vue-nice-modal';// inject hide/remove/callback methods by vue-nice-modalinterfaceIPropsextendsINiceModalHandlers<number>{visible: boolean;// props you need
title: string;
content: string;}interfaceIEmits{(e: 'update:visible',visible: boolean): void;}constprops=defineProps<IProps>();// @ts-ignoreconstemit=defineEmits<IEmits>();consthandleCancel=()=>{props.hide();// or emit('update:visible', false)props.callback('cancel');// reject the promise};consthandleConfirm=async()=>{// mock async function callconstsleep=(ms: number): Promise<number>=>newPromise((res)=>setTimeout(()=>{res(ms);},ms));constpayload=awaitsleep(1000);// resolve the promise with payloadprops.callback('confirm',payload);};</script><template><dialog:show="visible"
@update:show="$emit('update:visible', false)"
@cancel="handleCancel"
@confirm="handleConfirm"
@closed="remove"
:title="title"
:content="content"
show-cancel-buttonclass="demo-dialog"
><div>Hello, Vue Nice Modal</div></dialog></template>
前言
笔者去年写过一篇 NiceModal:重新思考 React 中的弹窗使用方式,6 月中旬换了工作,技术栈也由 React + TypeScript 切成了 [email protected] + JavaScript :),但是没有发现 @ebay/nice-modal-react 在 vue 生态中的替代方案,故而有了这篇文章。
如果本文能对你日常开发产生一些新的思考和效率的提升,那就太好了!笔者在工作中接触 vue 的时间也就短短半个月,如有设计不当的地方欢迎 PR 一起改进。 Vue Nice Modal - GitHub
在开始进入正题之前,先看看一些与弹窗有关的有趣场景 🤔。
一些有趣的真实场景
案例一:全局弹窗
上图是掘金的登录弹窗,未登录状态下触发该弹窗展示的时机有很多,比如:
开发者往往会基于第三方组件库定义一个
<LoginModal />
,然后将其挂载至Root
组件下。这样会带来一些问题:
<LoginModal />
内部逻辑在组件渲染的时候就会执行,即使弹窗处于隐藏状态setVisible
以及setOtherLoginData
透传至<Main />
内部的多个子组件,你可以选择通过 props 一层一层的传递进去(鬼知道有多少层!),也可以引入工具进行状态共享,但不论怎样,这都不是一件容易的事;展示一个弹窗,为什么会变得如此复杂?
除了上述全局弹窗的场景,还有一种场景也很让人头疼。
案例二:存在分支以及依赖关系的弹窗
弹窗 1 确认弹出弹窗 2,取消则弹出弹窗 3,弹窗 2 以及 弹窗 3 也存在对应的分支逻辑,子孙满堂轻而易举,若按照常规声明式弹窗组件的实现,非常恐怖!
Vue Nice Modal
vue-nice-modal 是一个工具库,可以将 Vue.js 的 modal 组件转换为基于 Promise 的 API。
灵感来源于 @ebay/nice-modal-react 和 vant。
支持 Vue 2.x,通过 vue-demi。
示例
你可以在 examples/* 文件夹中查看完整的项目示例。
安装
使用
自定义 Modal 组件
本节提供了一个使用 vue-nice-modal 库创建自定义 modal 组件的示例。该示例使用 vant UI 库的 Dialog 组件作为示例,但你可以使用任何自定义 modal 组件,并不限制组件库,如在 example-vue2.7.x 里使用的是 ant-design-vue。
在示例中,visible 属性和 update:visible 事件由 vue-nice-modal 注入到自定义 modal 组件中。这些用于控制 modal 组件的可见性。visible 属性应是一个布尔值,用于确定 modal 是可见的还是不可见,update:visible 事件应在 modal 的可见性改变时触发。
hide()、remove() 和 callback() 方法也由 vue-nice-modal 注入到自定义 modal 组件中。这些方法用于隐藏或删除 modal 组件,以及处理用户确认或取消 modal 操作。
modal 组件创建完毕后,可以使用 vue-nice-modal 提供的 create() 函数来创建一个 Modal 对象,该对象包含 show()、hide() 和 remove() 方法。后续即可使用 show() 方法显示自定义 modal 组件,并使用 vue-nice-modal 提供的基于 Promise 的 API 处理用户确认或取消 modal 操作。
API
create(Comp: Component): Modal
create 函数接受 Vue.js 组件并返回一个带有以下方法的 Modal 对象:
show(options: ExtractOptions<ComponentProps>): Promise
显示 modal 组件并返回一个 Promise,如果用户确认 modal 则 resolve,如果用户取消则 reject。
options 参数是一个对象,包含与 modal 组件相关的属性(除去 vue-nice-modal 注入的通用属性与方法,仅包含用户自定义的所需 props,以达到良好的类型提示)。
以下是 show 方法的类型提示实现:
hide(): void
隐藏 modal 组件。
remove(): void
从 DOM 中删除 modal 组件。
类型定义
vue-nice-modal 提供了一些 TypeScript 类型定义:
Modal
Modal 接口定义了 create 返回的对象的方法。
ComponentProps
ComponentProps 工具泛型用于获取 Vue 组件的属性。
INiceModalHandlers
INiceModalHandlers 接口定义了用于处理用户确认或取消 modal 的方法。
ExtractOptions<T extends Record<string, any>>
ExtractOptions 类型用于提取与 modal 组件相关的选项(除去 vue-nice-modal 注入的通用属性与方法)。
注意
推荐阅读
The text was updated successfully, but these errors were encountered: