小程序使用 WEUI

WEUI 是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,令用户的使用感知更加统一。包含 button、cell、dialog、progress、toast、article、actionsheet、icon 等各式元素。

1,安装和导入 WEUI

# 在项目根目录执行
npm init
npm install weui-miniprogram

或者下载源码。

2,配置使用

配置 app.json

{
  "usingComponents": {
    "mp-cells": "weui-miniprogram/cells/cells",
    "mp-cell": "weui-miniprogram/cell/cell",
    "mp-form": "weui-miniprogram/form/form",
    "mp-slideview": "weui-miniprogram/slideview/slideview",
    "mp-icon": "weui-miniprogram/icon/icon",
    "mp-badge": "weui-miniprogram/badge/badge",
    "mp-loading": "weui-miniprogram/loading/loading",
    "mp-toptips": "weui-miniprogram/toptips/toptips",
    "mp-dialog": "weui-miniprogram/dialog/dialog",
    "mp-half-screen-dialog": "weui-miniprogram/half-screen-dialog/half-screen-dialog",
    "mp-actionsheet": "weui-miniprogram/actionsheet/actionsheet",
    "mp-navigation-bar": "weui-miniprogram/navigation-bar/navigation-bar"
  },
  "style": "v2"
}

配置 app.wxss

/* 引入 WEUI 样式 */
@import 'weui-miniprogram/weui-wxss/dist/style/weui.wxss';

/* 自定义样式 */
page {
  --weui-BG-0: #ededed;
  --weui-BG-1: #f7f7f7;
  --weui-BG-2: #fff;
  --weui-FG-0: rgba(0, 0, 0, 0.9);
  --weui-FG-HALF: rgba(0, 0, 0, 0.9);
  --weui-FG-1: rgba(0, 0, 0, 0.5);
  --weui-RED: #fa5151;
  --weui-ORANGE: #fa9d3b;
  --weui-YELLOW: #ffc300;
  --weui-GREEN: #91d300;
  --weui-LIGHTGREEN: #95ec69;
  --weui-BRAND: #07c160;
  --weui-BLUE: #10aeff;
  --weui-INDIGO: #1485ee;
  --weui-PURPLE: #6467f0;
  --weui-WHITE: #fff;
  --weui-LINK: #576b95;
  --weui-TEXTGREEN: #06ae56;
  --weui-FG: #000;
  --weui-BG: #fff;
  --weui-TAG-TEXT-ORANGE: #fa9d3b;
  --weui-TAG-BACKGROUND-ORANGE: rgba(250, 157, 59, 0.1);
  --weui-TAG-TEXT-GREEN: #06ae56;
  --weui-TAG-BACKGROUND-GREEN: rgba(6, 174, 86, 0.1);
  --weui-TAG-TEXT-BLUE: #10aeff;
  --weui-TAG-BACKGROUND-BLUE: rgba(16, 174, 255, 0.1);
  --weui-TAG-TEXT-BLACK: rgba(0, 0, 0, 0.5);
  --weui-TAG-BACKGROUND-BLACK: rgba(0, 0, 0, 0.05);
}

3,在页面中使用

页面配置文件(index.json)

{
  "navigationBarTitleText": "WEUI 示例",
  "usingComponents": {
    "mp-cells": "weui-miniprogram/cells/cells",
    "mp-cell": "weui-miniprogram/cell/cell",
    "mp-form": "weui-miniprogram/form/form",
    "mp-slideview": "weui-miniprogram/slideview/slideview",
    "mp-icon": "weui-miniprogram/icon/icon",
    "mp-badge": "weui-miniprogram/badge/badge",
    "mp-loading": "weui-miniprogram/loading/loading",
    "mp-toptips": "weui-miniprogram/toptips/toptips",
    "mp-dialog": "weui-miniprogram/dialog/dialog",
    "mp-actionsheet": "weui-miniprogram/actionsheet/actionsheet",
    "mp-gallery": "weui-miniprogram/gallery/gallery",
    "mp-msg": "weui-miniprogram/msg/msg",
    "mp-grids": "weui-miniprogram/grids/grids",
    "mp-grid": "weui-miniprogram/grid/grid",
    "mp-tabbar": "weui-miniprogram/tabbar/tabbar",
    "mp-searchbar": "weui-miniprogram/searchbar/searchbar"
  }
}

页面骨架文件(index.wxml)

<!--pages/weui-demo/weui-demo.wxml-->
<view class="page">
  <!-- 页面标题 -->
  <view class="page__hd">
    <view class="page__title">WEUI 组件演示</view>
    <view class="page__desc">微信官方 UI 组件库示例</view>
  </view>

  <!-- 搜索栏 -->
  <mp-searchbar
    bindinput="onSearchInput"
    bindsearch="onSearch"
    bindclear="onClearSearch"
    placeholder="搜索内容">
  </mp-searchbar>

  <!-- 按钮组件 -->
  <view class="page__bd">
    <view class="weui-cells__title">按钮类型</view>
    <view class="weui-btn-area">
      <button class="weui-btn" type="primary" bindtap="onPrimaryClick">主要按钮</button>
      <button class="weui-btn" type="default" bindtap="onDefaultClick">默认按钮</button>
      <button class="weui-btn" type="warn" bindtap="onWarnClick">警告按钮</button>
      <button class="weui-btn weui-btn_disabled" disabled>禁用按钮</button>
      <button class="weui-btn weui-btn_loading" bindtap="onLoadingClick">
        <mp-icon type="waiting" class="weui-primary-loading"></mp-icon>
        加载中
      </button>
      <button class="weui-btn weui-btn_mini" type="primary">小按钮</button>
    </view>

    <!-- 表单组件 -->
    <view class="weui-cells__title">表单元素</view>
    <mp-cells>
      <mp-cell title="开关" value="{{switchChecked}}" prop="switch">
        <switch checked="{{switchChecked}}" bindchange="onSwitchChange"/>
      </mp-cell>
      <mp-cell title="单选框" value="{{radioItems[radioValue]}}" prop="radio" bindtap="showRadioDialog">
        <text class="weui-cell__bd">{{radioItems[radioValue]}}</text>
      </mp-cell>
      <mp-cell title="输入框">
        <input class="weui-input" value="{{inputValue}}" placeholder="请输入内容" bindinput="onInputChange"/>
      </mp-cell>
      <mp-cell title="滑块">
        <slider value="{{sliderValue}}" show-value bindchange="onSliderChange"/>
      </mp-cell>
    </mp-cells>

    <!-- 列表组件 -->
    <view class="weui-cells__title">列表项</view>
    <mp-cells>
      <mp-cell title="带图标" value="详细信息" arrow bindtap="onCellClick" data-index="1">
        <mp-icon type="success" size="16" slot="icon"></mp-icon>
      </mp-cell>
      <mp-cell title="带徽章" value="详细信息" arrow>
        <mp-badge class="weui-badge" content="8" slot="value"></mp-badge>
      </mp-cell>
      <mp-cell title="带副标题" value="详细信息" arrow>
        <view slot="footer">副标题信息</view>
      </mp-cell>
    </mp-cells>

    <!-- 可滑动列表项 -->
    <view class="weui-cells__title">可滑动操作</view>
    <mp-slideview
      buttons="{{slideButtons}}"
      bindbuttontap="onSlideButtonTap"
      data-index="{{index}}"
      wx:for="{{slideItems}}"
      wx:key="id">
      <mp-cell title="{{item.title}}" value="{{item.value}}"></mp-cell>
    </mp-slideview>

    <!-- 网格布局 -->
    <view class="weui-cells__title">网格布局</view>
    <mp-grids>
      <mp-grid
        wx:for="{{gridItems}}"
        wx:key="id"
        icon="{{item.icon}}"
        label="{{item.label}}"
        bindtap="onGridTap"
        data-index="{{index}}">
      </mp-grid>
    </mp-grids>

    <!-- 消息页面 -->
    <view class="weui-cells__title">消息页面</view>
    <mp-msg
      type="success"
      title="操作成功"
      desc="内容详情,可根据实际需要安排"
      buttons="{{msgButtons}}"
      bindbuttontap="onMsgButtonTap">
    </mp-msg>

    <!-- 加载状态 -->
    <view class="weui-cells__title">加载状态</view>
    <view class="weui-flex">
      <view class="weui-flex__item">
        <mp-loading class="custom-loading" type="circle" show="{{loading}}"></mp-loading>
      </view>
      <view class="weui-flex__item">
        <mp-loading class="custom-loading" type="dot" show="{{loading}}"></mp-loading>
      </view>
    </view>
  </view>

  <!-- 底部标签栏 -->
  <mp-tabbar
    tabs="{{tabs}}"
    current="{{currentTab}}"
    bindchange="onTabChange">
  </mp-tabbar>

  <!-- 对话框组件 -->
  <mp-dialog
    title="确认操作"
    show="{{showDialog}}"
    buttons="{{dialogButtons}}"
    bindbuttontap="onDialogButtonTap">
    <view>确定要执行此操作吗?</view>
  </mp-dialog>

  <!-- 动作面板 -->
  <mp-actionsheet
    show="{{showActionSheet}}"
    title="选择操作"
    actions="{{actionSheetActions}}"
    bindclose="onActionSheetClose"
    bindselect="onActionSheetSelect">
  </mp-actionsheet>

  <!-- 顶部提示 -->
  <mp-toptips
    type="error"
    show="{{showErrorTips}}"
    msg="操作失败,请重试"
    bindhide="onTipsHide">
  </mp-toptips>

  <!-- 图片预览 -->
  <mp-gallery
    show="{{showGallery}}"
    imgUrls="{{galleryImages}}"
    bindhide="onGalleryHide">
  </mp-gallery>
</view>

页面样式文件(index.wxss)

/* pages/weui-demo/weui-demo.wxss */
.page {
  height: 100%;
  background-color: var(--weui-BG-0);
}

.page__hd {
  padding: 40rpx;
  text-align: center;
  background: linear-gradient(135deg, #1AAD19 0%, #16C2C2 100%);
  color: white;
}

.page__title {
  font-size: 36rpx;
  font-weight: bold;
  margin-bottom: 16rpx;
}

.page__desc {
  font-size: 28rpx;
  opacity: 0.8;
}

.page__bd {
  padding: 32rpx;
}

.weui-btn-area {
  display: flex;
  flex-direction: column;
  gap: 20rpx;
  padding: 0 32rpx;
}

.weui-cells__title {
  margin-top: 40rpx;
  margin-bottom: 16rpx;
  padding-left: 32rpx;
  padding-right: 32rpx;
  color: rgba(0, 0, 0, 0.9);
  font-size: 28rpx;
  font-weight: 500;
}

.custom-loading {
  text-align: center;
  padding: 40rpx 0;
}

/* 自定义网格样式 */
.grid-custom .weui-grid__icon {
  width: 64rpx;
  height: 64rpx;
}

.grid-custom .weui-grid__label {
  font-size: 24rpx;
  margin-top: 16rpx;
}

/* 消息页面自定义样式 */
.msg-custom {
  margin: 40rpx 0;
}

/* 搜索栏样式 */
.search-bar-custom {
  margin: 20rpx 32rpx;
}

页面脚本文件(index.js)

// pages/weui-demo/weui-demo.js
Page({
  data: {
    // 搜索相关
    searchValue: '',

    // 表单数据
    switchChecked: false,
    radioValue: 0,
    radioItems: ['选项一', '选项二', '选项三'],
    inputValue: '',
    sliderValue: 50,

    // 列表数据
    slideItems: [
      { id: 1, title: '可滑动项一', value: '值一' },
      { id: 2, title: '可滑动项二', value: '值二' },
      { id: 3, title: '可滑动项三', value: '值三' }
    ],
    slideButtons: [
      {
        type: 'warn',
        text: '删除',
        extClass: 'test',
        src: '' // icon的路径
      },
      {
        type: 'default',
        text: '置顶',
        extClass: 'test',
        src: '' // icon的路径
      }
    ],

    // 网格数据
    gridItems: [
      { id: 1, icon: 'picture', label: '图片' },
      { id: 2, icon: 'music', label: '音乐' },
      { id: 3, icon: 'video', label: '视频' },
      { id: 4, icon: 'location', label: '位置' },
      { id: 5, icon: 'search', label: '搜索' },
      { id: 6, icon: 'setting', label: '设置' }
    ],

    // 消息页面按钮
    msgButtons: [
      { type: 'primary', text: '推荐操作', value: 0 },
      { type: 'default', text: '辅助操作', value: 1 }
    ],

    // 标签栏
    tabs: [
      { key: 'home', title: '首页', icon: 'home' },
      { key: 'discover', title: '发现', icon: 'discover' },
      { key: 'user', title: '我的', icon: 'user' }
    ],
    currentTab: 'home',

    // 对话框
    showDialog: false,
    dialogButtons: [
      { type: 'default', text: '取消', value: 0 },
      { type: 'primary', text: '确定', value: 1 }
    ],

    // 动作面板
    showActionSheet: false,
    actionSheetActions: [
      { name: '选项一', value: 1 },
      { name: '选项二', value: 2 },
      { name: '选项三', value: 3, type: 'warn' }
    ],

    // 提示信息
    showErrorTips: false,

    // 图片预览
    showGallery: false,
    galleryImages: [
      'https://placekitten.com/400/300',
      'https://placekitten.com/400/301',
      'https://placekitten.com/400/302'
    ],

    // 加载状态
    loading: false
  },

  onLoad() {
    console.log('WEUI 示例页面加载');
    this.showWelcomeTips();
  },

  /**
   * 显示欢迎提示
   */
  showWelcomeTips() {
    wx.showToast({
      title: '欢迎使用 WEUI',
      icon: 'success',
      duration: 2000
    });
  },

  /**
   * 按钮点击事件
   */
  onPrimaryClick() {
    console.log('主要按钮点击');
    this.showDialog('primary');
  },

  onDefaultClick() {
    console.log('默认按钮点击');
    this.showActionSheet();
  },

  onWarnClick() {
    console.log('警告按钮点击');
    this.showErrorTip();
  },

  onLoadingClick() {
    console.log('加载按钮点击');
    this.showLoading();
  },

  /**
   * 表单变化事件
   */
  onSwitchChange(e) {
    const value = e.detail.value;
    this.setData({ switchChecked: value });
    console.log('开关状态:', value);

    wx.showToast({
      title: `开关: ${value ? '开' : '关'}`,
      icon: 'none'
    });
  },

  onInputChange(e) {
    this.setData({ inputValue: e.detail.value });
  },

  onSliderChange(e) {
    this.setData({ sliderValue: e.detail.value });
  },

  /**
   * 列表项点击
   */
  onCellClick(e) {
    const index = e.currentTarget.dataset.index;
    console.log('点击单元格:', index);

    wx.showToast({
      title: `点击第${index}项`,
      icon: 'none'
    });
  },

  /**
   * 单选框对话框
   */
  showRadioDialog() {
    const items = this.data.radioItems;
    const current = this.data.radioValue;

    wx.showActionSheet({
      itemList: items,
      success: (res) => {
        if (!res.cancel) {
          this.setData({ radioValue: res.tapIndex });
        }
      }
    });
  },

  /**
   * 滑动操作
   */
  onSlideButtonTap(e) {
    const { index, value } = e.detail;
    const item = this.data.slideItems[index];

    console.log('滑动操作:', index, value);

    if (value === 0) { // 删除
      this.deleteSlideItem(index);
    } else if (value === 1) { // 置顶
      this.topSlideItem(index);
    }
  },

  deleteSlideItem(index) {
    wx.showModal({
      title: '确认删除',
      content: '确定要删除此项吗?',
      success: (res) => {
        if (res.confirm) {
          const items = this.data.slideItems.filter((_, i) => i !== index);
          this.setData({ slideItems: items });

          wx.showToast({
            title: '删除成功',
            icon: 'success'
          });
        }
      }
    });
  },

  topSlideItem(index) {
    const items = [...this.data.slideItems];
    const [item] = items.splice(index, 1);
    items.unshift(item);
    this.setData({ slideItems: items });

    wx.showToast({
      title: '置顶成功',
      icon: 'success'
    });
  },

  /**
   * 网格点击
   */
  onGridTap(e) {
    const index = e.currentTarget.dataset.index;
    const item = this.data.gridItems[index];

    wx.showToast({
      title: `点击: ${item.label}`,
      icon: 'none'
    });
  },

  /**
   * 消息页面按钮点击
   */
  onMsgButtonTap(e) {
    const value = e.detail.value;
    console.log('消息按钮点击:', value);

    if (value === 0) {
      wx.showToast({
        title: '推荐操作',
        icon: 'success'
      });
    } else {
      this.showActionSheet();
    }
  },

  /**
   * 标签栏切换
   */
  onTabChange(e) {
    const key = e.detail.key;
    this.setData({ currentTab: key });

    wx.showToast({
      title: `切换到: ${this.getTabName(key)}`,
      icon: 'none'
    });
  },

  getTabName(key) {
    const map = { home: '首页', discover: '发现', user: '我的' };
    return map[key] || '未知';
  },

  /**
   * 搜索功能
   */
  onSearchInput(e) {
    this.setData({ searchValue: e.detail.value });
  },

  onSearch(e) {
    const keyword = e.detail.value;
    console.log('搜索关键词:', keyword);

    if (!keyword.trim()) {
      wx.showToast({
        title: '请输入搜索内容',
        icon: 'none'
      });
      return;
    }

    wx.showLoading({ title: '搜索中...' });

    // 模拟搜索
    setTimeout(() => {
      wx.hideLoading();
      wx.showToast({
        title: `搜索: ${keyword}`,
        icon: 'success'
      });
    }, 1000);
  },

  onClearSearch() {
    this.setData({ searchValue: '' });
    console.log('清除搜索');
  },

  /**
   * 对话框相关
   */
  showDialog(type = 'primary') {
    this.setData({ showDialog: true });
  },

  onDialogButtonTap(e) {
    const value = e.detail.value;
    this.setData({ showDialog: false });

    if (value === 1) {
      wx.showToast({
        title: '确认操作',
        icon: 'success'
      });
    } else {
      console.log('取消操作');
    }
  },

  /**
   * 动作面板
   */
  showActionSheet() {
    this.setData({ showActionSheet: true });
  },

  onActionSheetClose() {
    this.setData({ showActionSheet: false });
  },

  onActionSheetSelect(e) {
    const action = e.detail;
    console.log('选择动作:', action);

    wx.showToast({
      title: `选择: ${action.name}`,
      icon: 'success'
    });
  },

  /**
   * 错误提示
   */
  showErrorTip() {
    this.setData({ showErrorTips: true });
  },

  onTipsHide() {
    this.setData({ showErrorTips: false });
  },

  /**
   * 加载状态
   */
  showLoading() {
    this.setData({ loading: true });

    // 3秒后隐藏加载
    setTimeout(() => {
      this.setData({ loading: false });
      wx.showToast({
        title: '加载完成',
        icon: 'success'
      });
    }, 3000);
  },

  /**
   * 图片预览
   */
  showGallery() {
    this.setData({ showGallery: true });
  },

  onGalleryHide() {
    this.setData({ showGallery: false });
  },

  /**
   * 页面分享
   */
  onShareAppMessage() {
    return {
      title: 'WEUI 小程序组件示例',
      path: '/pages/weui-demo/weui-demo'
    };
  },

  /**
   * 分享到朋友圈
   */
  onShareTimeline() {
    return {
      title: 'WEUI 小程序组件示例',
      imageUrl: '/images/share.jpg'
    };
  }
});

主要组件说明 ​

​mp-cells/mp-cell: 列表单元格

​mp-form: 表单容器

​mp-slideview: 可滑动操作项

​mp-dialog: 对话框

​mp-actionsheet: 动作面板

​mp-toptips: 顶部提示

​mp-loading: 加载指示器

​mp-msg: 消息页面

​mp-grids/mp-grid: 网格布局

​mp-tabbar: 底部标签栏

自定义主题 ​,可以通过 CSS 变量自定义主题色:

page {
  --weui-BRAND: #你的主题色;
}

这个完整的 WEUI 示例展示了如何在小程序中使用官方 UI 组件库,包含了丰富的组件示例和交互逻辑,可以直接在项目中使用。

通关密语:WEUI