开发一个简单的UI组件-代码步骤

272 阅读1分钟

引入hi-element

具体的使用方式请参考hi-element文档

toast.ts

// 核心库
import { HIElement, customElement, html, ref, observable } from 'hi-element';`
// 样式
import { ToastStyles as styles } from "./toast.style";
// 模版文件
const template = html<HiToast>`
<div class="ToastBox PosF WS TC PoiNo" ${ref('ToastBox')} style="${x => x.position()}">
    ${x => x.content}
</div>
// 定义元素
@customElement({
   name: 'h-toast',
   template,
   styles
})
export class HiToast extends HIElement {
    // ------------------ 构造函数 ------------------
    constructor(
    ) {
        super();
    }
    // ------------------ 参数 ------------------
    @observable
    ToastBox: HTMLDivElement;
    
    /**
     * 显示内容
     * @public
     */
    content = '';
    /**
     * 间隔时间
     * @public
     */
    duration: number | undefined;
    /**
     * 定时器
     * @public
     */    
    timer!: any;
    /**
     * 显示状态
     * @public
     * @remarks
     */
    private _show!: boolean;
    get show(): boolean {
        return this._show;
    }
    set show(value: boolean) {
        this._show = value;
        if ( value === null || value === false ){
        HiAnimateService.run(this.ToastBox, 'fadeOut', 0.5, () => {
            this.$emit('close');
            this.remove();
        });
        } else {
            HiAnimateService.run(this.ToastBox, 'fadeIn', 0.5);
        }
    }
    /**
     * 显示位置信息设置 
     * @date 6/16/2022 - 2:03:25 PM
     * @examples [10,10] or ['45%'] or [,,20,20] or ['20%',20]
     * @type {Array<string>}
     */
    site: Array<string> | undefined;
    // ------------------ 属性 ------------------

    // ------------------ 自定义函数 ------------------
    /**
     * 当自定义元素第一次被连接到文档DOM时被调用
     * @internal
     */
    connectedCallback() {
        super.connectedCallback();
        this.position();
    }
    
    /**
     * 设置参数
     * @date 2022-06-16
     * @param { any } message
     * @param { string} type
     * @param { string} content
     * @param { number } duration
     * @param { callback: () => void = (() => {})} 
     * @returns { void }
     */
    setParams (
        toast:any, 
        options, 
        callback: () => void = (() => {})
    ): void {
        toast.duration = options.duration;
        toast.content = options.content;
        toast.site = options!.site;
        toastContent.appendChild(toast);
        toast.show = true;
        toast.timer = setTimeout(()=>{
            toast.show = false;
        }, options.duration || HI_CONFIG.case.config.toast?.duration );
    }   
    /**
     * 及时显示位置
     * @date 6/16/2022 - 2:02:42 PM
     *
     * @returns {string}
     */
    position(): string {
        if ( !this.site ) {
            return '';
        };
        let CSS: any = {};
        for ( let i=0; i < this.site.length; i++ ) {
            if( !this.site[i] ){
                continue;
            } else {
                let _Site;
                if ( typeof this.site[i] === 'string' && this.site[i].indexOf('%') >= 0 ) {
                    _Site = this.site[i];
                } else {
                    _Site = this.site[i] + 'px';
                };
                switch(i){
                    case 0: CSS.top = _Site; CSS.bottom = 'auto'; break;
                    case 1: CSS.right = _Site; CSS.left = 'auto'; CSS['margin-left'] = 'auto'; break;
                    case 2: CSS.bottom = _Site; break;
                    case 3: CSS.left = _Site; CSS['margin-left'] = 'auto'; break;
                };
            };
        };
        return `top:${CSS.top}; right:${CSS.right}; bottom:${CSS.bottom}; left:${CSS.left}; margin-left:${CSS['margin-left']};`;        
    }
}

创建元素加载的位置

let toastContent: any = document.getElementById('HiToastWrap');
if(!toastContent){
    toastContent = document.createElement('div');
    toastContent.id = 'HiToastWrap';
    Style(toastContent)({
        'position': 'fixed',
        'pointer-events': 'none',
        'left': 0,
        'right': 0,
        'top': '-100px',
        'z-index': 3050
    });
    document.body.appendChild(toastContent);
}

创建提示服务,方便调用

/**
 * 消息提示
 * @function get
 * @date 6/17/2022 - 1:50:51 PM
 *
 * @export
 * @param {{
        content: string, 
        duration: number, 
        site: Array<any>,
    }} options
 * @param { Object } options 请求参数对象
 * @param { string } options.content 显示内容
 * @param { Function } options.duration 显示时间间隔
 * @param { Function } options.site 位置
 */
export function HiToastService (
    options: {
        content: string, 
        duration?: number, 
        site?: Array<any>,
    }) {
        const toast = new HiToast();
        toast.setParams(toast, options);
        return toast
}

调用方法

HiToastService.toast({content:'内容', duration: 2000, site: [50%]})

toast.style文件

// 核心库
import { css } from 'hi-element';
export const ToastStyles = css`
${hiConfigStyle()}
:host{
    --radius: ${HI_CONFIG.case.config.toast?.radius+ 'px'};
}
.ToastBox{
    left:50%;
    bottom:20px;
    min-width:100px;
    max-width:100%;
    border-radius: var(--radius, --borderRadius);
    background-color: var(--colorNeutral7);
    box-shadow: var(--colorNeutral4) 0 0 5px;
    color:#fff;
    padding:10px;
    transform: translateX(-50%);
}
`;

效果展示