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

最近来个需求,要求给小程序的 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);
}
相关推荐
2603_965896626 分钟前
Grid 网格布局|CSS 二维页面排版体系
前端·css
有味道的男人22 分钟前
搜好货平台关键词商品搜索接口:分页容错与商品数据轻量化提取方案
服务器·前端·javascript
lovingsoft1 小时前
Chrome Lighthouse 详解
前端·chrome
Qlly1 小时前
全栈工程师怎么接需求?从一句「加个功能」聊到能开发、能验收
前端·后端
马可家的菠萝1 小时前
你的微信“文件传输助手”,是不是已经成了第二个网盘?
前端·后端·架构
略略略啦1 小时前
Vibe Coding 基于Spec DD和TDD的实践指南
前端
shmily麻瓜小菜鸡2 小时前
前端实现图片与PDF文字识别敏感信息打码方案
前端·pdf·状态模式
打工仔折腾 AI2 小时前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战
汉堡大王95272 小时前
单次输出拉到100万Token:拆完 Gemini 4 Argon 的续写协议,才看懂谷歌这7个月在憋什么
前端·人工智能·后端
看浪的路人2 小时前
第9讲:大模型应用监控与可观测性——OpenTelemetry + Prometheus + Grafana 全链路追踪
java·前端·spring