微信小程序vant弹窗组件的实现方式(5)

通过closable属性决定是否显示默认的关闭按钮,也可以通过关闭图标相关属性配置更改按钮样式,关闭按钮的事件有onClickCloseIcon,通过$emit触发组件的自定义事件close。

onClickCloseIcon() { this.$emit('close'); },

内容分发

接受一个默认的slot,其位置根据传入的 position 参数不同有 top、right、bottom、left、center 五种,根据这五种位置参数有对应的五种不同的弹出位置和动画

过渡动画

使用transform来实现动画效果,根据 position 参数的五种情况有五种默认动画

// popup/index.less .van-bottom-enter, .van-bottom-leave-to { transform: translate3d(0, 100%, 0); } .van-top-enter, .van-top-leave-to { transform: translate3d(0, -100%, 0); } .van-left-enter, .van-left-leave-to { transform: translate3d(-100%, -50%, 0); } .van-right-enter, .van-right-leave-to { transform: translate3d(100%, -50%, 0); }

同时暴露了外部样式类可以用来自定义动画,这里动画阶段划分和vue相同,分类: enter、enter-active、enter-to、leave、leave-active、leave-to

// popup/index.ts VantComponent({ classes: [ 'enter-class', 'enter-active-class', 'enter-to-class', 'leave-class', 'leave-active-class', 'leave-to-class' ], ... }

八、Dialog对话框组件源码分析

组件部分源码结构

dialog组件部分源码结构如下:

微信小程序vant弹窗组件的实现方式

结构同popup组件,不同点在于index.json使用了 van-popup、van-button 组件,以及多了dialog.ts这个暴露API函数调用方法的文件。

组件布局结构

dialog组件整体基于popup组件,在其默认slot中添加了顶部标题的slot和按钮组元素,大致结构如下

微信小程序vant弹窗组件的实现方式

源码结构:

// dialog/index.wxml <van-popup show="{{ show }}" ... > <view wx:if="{{ title || useTitleSlot }}" > <slot wx:if="{{ useTitleSlot }}" /> <block wx:elif="{{ title }}"> {{ title }}</block> </view> <slot wx:if="{{ useSlot }}" /> <view wx:elif="{{ message }}" > <text>{{ message }}</text> </view> <view> <van-button wx:if="{{ showCancelButton }}" ... > {{ cancelButtonText }} </van-button> <van-button wx:if="{{ showConfirmButton }}" ... > {{ confirmButtonText }} </van-button> </view> </van-popup>

函数式调用实现

在前面中通过Dialog函数调用来打开弹出框组件,实现函数式调用的核心思路主要是: 通过selectComponent(selector)方法查找(类似于查找DOM、Vue中查找组件实例)对页面中定义渲染好的dialog组件,手动更新其组件实例的数据。 ** Dialog方法定义如下:

const Dialog: Dialog = options => { options = { ...Dialog.currentOptions, ...options }; return new Promise((resolve, reject) => { const context = options.context || getContext(); const dialog = context.selectComponent(options.selector); delete options.context; delete options.selector; if (dialog) { dialog.setData({ onCancel: reject, onConfirm: resolve, ...options }); queue.push(dialog); } else { console.warn('未找到 van-dialog 节点,请确认 selector 及 context 是否正确'); } }); };

**

函数式调用时候根据传入的options配置去更新找到的组件实例上的属性

由微信小程序自定义组件限制不能更新slot,slot需要用组件嵌套来传入

函数式调用中的options会有默认值强制覆盖掉van-dialog组件属性处传入的非id等其他属性,即函数调用的时通过组件传入的属性无效

**

Dialog.confirm

确认弹窗

调用方法

Dialog.confirm({ selector: '#van-dialog', title: '提示', message: '这里放置提示内容' })

实现方式

Dialog.confirm = options => Dialog({ showCancelButton: true, ...options });

调用Dialog时候默认执行定了显示取消按钮,其他无区别

Dialog.close

关闭弹窗

调用方法

Dialog.close()

实现方式

Dialog.close = () => { queue.forEach(dialog => { dialog.close(); }); queue = []; };

遍历内部缓存的所有调用Dialog方法找到的van-dialog组件实例,执行其close方法

Dialog.setDefaultOptions

更改对话框默认配置

调用方法

Dialog.setDefaultOptions(options)

实现方式

Object.assign(Dialog.currentOptions, options);

通过Object.assign将传入的默认配置合并到内部Dialog.currentOptions配置上

Dialog.resetDefaultOptions

恢复对话框默认配置

调用方法

Dialog.resetDefaultOptions()

实现方式

Dialog.resetDefaultOptions = () => { Dialog.currentOptions = { ...Dialog.defaultOptions }; };

恢复Dialog.currentOptions配置为Dialog.defaultOptions

总结

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/48616d427c2b36025f75d062a150313a.html