【微信小程序】记一次自定义微信小程序组件的思路

最近来个需求,要求给小程序的 modal 增加个关闭按钮,上网一查发现原来 2018 年就有人给出解决方案了,于是总结下微信小程序自定义组件的思路:一句话,用 wxml + css实现和原生组件类似的样式和效果,之后用 JS 实现类似原生组件的功能。

比如 modal 组件,观察可以得出就是个在页面顶层显示的 mask + div。modal 的显示与否可以通过 wx-if 控制,需要注意的点是 modal 显示的时候要有动画效果,这个功能可以通过 css animation 实现。

自定义 modal 的示例代码:

WXML:

html 复制代码
<view wx-if="{{cusModalShow}}" bindtap="handleCusModalMaskTap" class="cus-modal">
    <view catchtap class="cus-modal__content">
        <view class="cus-modal__close-btn" bindtap="handleCusModalMaskTap">
            ×
        </view>
        <view class="cus-modal__content-title">
            <text>提示</text>
        </view>
        <view class="cus-modal__content-text">
            <text>请确认操作</text>
        </view>
        <view class="cus-modal__content-buttons">
            <text bindtap="handleCusModalCancel" class="cus-modal__content-button-cancel">取消</text>
            <text bindtap="handleCusModalConfirm" class="cus-modal__content-button-confirm">确认</text>
        </view>
    </view>
</view>

CSS:

css 复制代码
@keyframes fade-in {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

.cus-modal {
    display: flex;
    align-items: center;
    justify-content: center;

    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.6);

    animation: fade-in 0.3s ease;
}

.cus-modal__content {
    background-color: white;
    border-radius: 15px;
    width: 80%;
    position: relative;
}

.cus-modal__close-btn {
    color: rgb(179, 179, 179);
    font-size: 1.5rem;
    position: absolute;
    right: 0.5rem;
    top: 0.1rem;
}

.cus-modal__content-title,
.cus-modal__content-text {
    font-size: 1.1rem;
    text-align: center;
}

.cus-modal__content-title {
    font-weight: bold;
    margin: 40px 0 20px 0;
}

.cus-modal__content-text {
    color: rgb(179, 179, 179);
    margin-bottom: 40px;
}

.cus-modal__content-buttons {
    display: flex;
}

.cus-modal__content-buttons {
    border-top: 1px solid rgb(245, 245, 245);
}

.cus-modal__content-buttons>text {
    flex: 1;
    text-align: center;
    padding: 20px 30px;
    border-right: 1px solid rgb(245, 245, 245);
    box-sizing: border-box;
    height: 60px;
}

.cus-modal__content-buttons>text:last-child {
    border-right: none;
}

.cus-modal__content-button-cancel {
    font-weight: bold;
}

.cus-modal__content-button-confirm {
    font-weight: bold;
    color: rgb(90, 117, 155);
}

自定义 Picker:

这里实际只是模拟了原生 Picker 从底部弹入的效果,具体内容可以通过放在里面的组件实现。

WXML

html 复制代码
<view bindtap="closeBottomPicker" wx-if="{{cusPickerShow}}" class="cus-picker">
    <view class="cus-picker__mask"></view>
    <view catchtap class="cus-picker__content">
        <!-- <view class="cus-picker__header">
            <text class="cus-pick__header__btn-cancel">取消</text>
            <text class="cus-pick__header__btn-confirm">确定</text>
        </view> -->
        <some-component bindclose="handleCarFilterClose"></some-component>
    </view>
</view>

CSS:

css 复制代码
@keyframes slide-up-from-bottom {
    0% {
        transform: translateY(100%);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes fade-in {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

.cus-picker {
    z-index: 114514;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

.cus-picker__mask {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    background-color: rgba(0, 0, 0, 0.5);
    animation: fade-in 0.3s ease;
}

.cus-picker__content {
    box-sizing: border-box;
    position: absolute;
    height: 50%;
    width: 100%;
    bottom: 0;
    background-color: white;
    animation: slide-up-from-bottom 0.3s ease;
}

.cus-picker__header {
    display: flex;
    justify-content: space-between;
    padding: 20px;
    border-bottom: 1px solid rgb(245, 245, 245);
    font-size: 16px;
}

.cus-pick__header__btn-cancel {
    color: rgb(127, 127, 127);
}

.cus-pick__header__btn-confirm {
    color: rgb(0, 196, 105);
}
相关推荐
layman05281 分钟前
openeuler 虚拟机:Nginx 日志分析脚本
前端·javascript·nginx
curdcv_po9 分钟前
ts 非空 断言, 后缀加感叹号!,有话要说!!!
前端
烛阴20 分钟前
快速上手Axios:前端开发者必备技能
前端·javascript
究极无敌暴龙战神X22 分钟前
Vite中定义@软链接
前端
摇摇奶昔x29 分钟前
Vue.js 中 “require is not defined“
前端·javascript·vue.js
烛阴39 分钟前
Cheerio DOM操作深度指南:轻松玩转HTML元素操作
前端·javascript·后端
rookie fish1 小时前
如何控制electron的应用在指定的分屏上打开[特殊字符]
前端·javascript·electron
hweiyu001 小时前
Electron简介(附电子书学习资料)
前端·javascript·electron
sunbyte1 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | RandomChoicePicker(标签生成)
前端·javascript·vue.js