UNPKG

wux-weapp

Version:

一套组件化、可复用、易扩展的微信小程序 UI 组件库

242 lines (229 loc) 6.99 kB
import baseComponent from '../helpers/baseComponent' import classNames from '../helpers/libs/classNames' import styleToCssString from '../helpers/libs/styleToCssString' import warning from '../helpers/libs/warning' import { omit } from '../helpers/shared/omit' import { defaults as dialogConfig, defaultOptions as dialogOptions } from '../dialog/utils' import { defaults as loadingConfig } from '../loading/utils' import { defaults as notificationConfig } from '../notification/utils' import { defaults as toastConfig } from '../toast/utils' import { defaults as toptipsConfig } from '../toptips/utils' let uuid = 0 const appConfig = { dialog: omit({ ...dialogConfig, ...dialogOptions, resetOnClose: true, }, ['onCancel', 'onConfirm']), loading: { ...loadingConfig }, notification: omit(notificationConfig, ['onClick', 'onClose']), toast: omit(toastConfig, ['success']), toptips: omit(toptipsConfig, ['success']), } const warningUnhooked = (valid, componentName) => { if (!valid && console !== undefined) { warning(false, `<${componentName} /> 无法找到对应的组件,请按文档说明使用组件`) } } const useComponentRef = (componentName, vm) => { const { prefixCls, uuid } = vm.data const selector = `#${prefixCls}__${componentName}-${uuid}` const componentCtx = vm.querySelector(selector) return { current: componentCtx, } } const useDialog = (props, vm) => { const holderRef = useComponentRef('dialog', vm) const wrapAPI = {} const keys = ['show', 'open', 'alert', 'confirm', 'prompt'] keys.forEach((type) => { wrapAPI[type] = (config) => { if (!holderRef.current) { warningUnhooked(false, 'Dialog') const fakeResult = () => {} fakeResult.then = () => {} return fakeResult } return holderRef.current[type]({ ...props, ...config }) } }) return [ wrapAPI, holderRef, ] } const useLoading = (props, vm) => { const holderRef = useComponentRef('loading', vm) const show = (config) => { if (!holderRef.current) { warningUnhooked(false, 'Loading') const fakeResult = () => {} fakeResult.then = () => {} return fakeResult } return holderRef.current.show({ ...props, ...config }) } const hide = () => { if (holderRef.current) { holderRef.current.hide() } } return [ { show, hide }, holderRef, ] } const useNotification = (props, vm) => { const holderRef = useComponentRef('notification', vm) const show = (config) => { if (!holderRef.current) { warningUnhooked(false, 'Notification') const fakeResult = () => {} fakeResult.then = () => {} return fakeResult } return holderRef.current.show({ ...props, ...config }) } const hide = () => { if (holderRef.current) { holderRef.current.hide() } } return [ { show, hide }, holderRef, ] } const useToast = (props, vm) => { const holderRef = useComponentRef('toast', vm) const wrapAPI = {} const keys = ['show', 'success', 'warning', 'info', 'error'] keys.forEach((type) => { wrapAPI[type] = (config) => { if (!holderRef.current) { warningUnhooked(false, 'Toast') const fakeResult = () => {} fakeResult.then = () => {} return fakeResult } return holderRef.current[type]({ ...props, ...config }) } }) return [ wrapAPI, holderRef, ] } const useToptips = (props, vm) => { const holderRef = useComponentRef('toptips', vm) const wrapAPI = {} const keys = ['show', 'success', 'warn', 'info', 'error'] keys.forEach((type) => { wrapAPI[type] = (config) => { if (!holderRef.current) { warningUnhooked(false, 'Toptips') const fakeResult = () => {} fakeResult.then = () => {} return fakeResult } return holderRef.current[type]({ ...props, ...config }) } }) return [ wrapAPI, holderRef, ] } baseComponent({ useExport: true, properties: { prefixCls: { type: String, value: 'wux-app', }, config: { type: Object, value: appConfig, }, shadowRoot: { type: Boolean, value: false, }, // 自定义类名 wrapCls: { type: String, value: '', }, // 自定义样式 wrapStyle: { type: [String, Object], value: '', observer(newVal) { this.setData({ extStyle: styleToCssString(newVal), }) }, }, }, data: { extStyle: '', uuid, memoizedAPI: null, }, observers: { ['prefixCls, config'](...args) { this.updateMemoizedAPI(args[1]) }, }, computed: { classes: ['prefixCls, uuid', function(prefixCls, uuid) { const wrap = classNames(prefixCls) const dialog = `${prefixCls}__dialog-${uuid}` const loading = `${prefixCls}__loading-${uuid}` const notification = `${prefixCls}__notification-${uuid}` const toast = `${prefixCls}__toast-${uuid}` const toptips = `${prefixCls}__toptips-${uuid}` return { wrap, dialog, loading, notification, toast, toptips, } }], }, methods: { updateMemoizedAPI(config) { const [dialogAPI] = useDialog(appConfig.dialog, this) const [loadingAPI] = useLoading(config.loading, this) const [notificationAPI] = useNotification(config.notification, this) const [toastAPI] = useToast(config.toast, this) const [toptipsAPI] = useToptips(config.toptips, this) const memoizedAPI = { dialog: dialogAPI, loading: loadingAPI, notification: notificationAPI, toast: toastAPI, toptips: toptipsAPI, } if (this.data.memoizedAPI !== memoizedAPI) { this.setData({ memoizedAPI, }) } }, ['export']() { return { useApp: () => this.data.memoizedAPI, } }, }, attached() { this.setData({ uuid: ++uuid, }) this.updateMemoizedAPI(this.data.config) }, })