气泡菜单(Popover)

点击元素,弹出气泡式的菜单。只可由导航栏上图标唤起,通常用于收纳低频使用的功能。

属性

Popover

属性

类型

必填

默认值

说明

visible

boolean

false

是否可见

mode

'dark' | 'light'

'dark'

组件显示模式

placement

'top' | 'top-right' | 'top-left' | 'bottom' | 'bottom-left' | 'bottom-right' | 'left' | 'left-top' | 'left-bottom' | 'right' | 'right-top' | 'right-bottom'

'bottom-right'

方向

className

string

-

类名

mask

boolean

false

是否展示蒙层

maskClosable

boolean

true

是否可点击蒙层关闭

fixMaskFull

boolean

false

用以解决遮罩层受到 transform 影响而显示不全的问题

PopoverItem

属性

类型

必填

默认值

说明

icon

string

-

图标类型

className

string

-

类名

事件

Popover

事件名

说明

类型

onVisibleChange

组件隐藏/显示切换,触发回调

( visible: boolean, mode: 'component' | 'mask' ) => void

PopoverItem

事件名

说明

类型

onTap

点击组件,触发回调

() => void

插槽

Popover

名称

说明

items

tooltip 提示插槽,可以使用 PopoverItem 渲染列表

PopoverItem

名称

说明

icon

图标插槽

样式类

Popover

类名

说明

amd-popover

整体样式

amd-popover-container

主体内容样式

amd-popover-content

内容样式

amd-popover-arrow

箭头样式

amd-popover-inner

内部内容样式

amd-popover-inner-pseudo

tooltip 内容整体样式

类名

说明

amd-popover-item

整体样式

amd-popover-item-icon

图标样式

amd-popover-item-icon-item

图标样式

amd-popover-item-text

文字样式

代码示例

基本使用

index.axml 的代码示例如下:

<view>
  <demo-block title="基础用法">
    <view class="wrap dark">
      <popover 
        placement="bottom"
        visible="{{showDark}}"
        onVisibleChange="handleDarkVisibleChange">
        <button inlineSize="large" inline>点我</button>
        <view slot="items" class="tooltip">Hello World</view>
      </popover>
    </view>
  </demo-block>
  <demo-block title="浅色气泡">
    <view class="wrap">
      <popover 
        placement="right"
        mode="light"
        visible="{{showLight}}"
        onVisibleChange="handleLightVisibleChange">
        <button inlineSize="large" inline>点我</button>
        <view slot="items" class="tooltip">Hello World</view>
      </popover>
    </view>
  </demo-block>
  <demo-block title="气泡位置" className="multi-demo">
    <view class="multi-wrap">
      <popover 
        placement="{{placement}}"
        visible="{{show}}"
        mask="{{showMask}}"
        onVisibleChange="handleVisibleChange">
        <view class="multi">
          <view>点击{{show ? '隐藏' : '显示'}}</view>
          <view>
            {{placement}}
          </view>
        </view>
        <view slot="items" class="tooltip">
          <view>Popover</view> 
          <view>
            Content
          </view>
        </view>
      </popover>
    </view>
    <view class="demo-btn-container">
      <button 
        class="demo-btn"
        onTap="handleNextPosition">
        下个位置
      </button>
      <button 
        class="demo-btn"
        onTap="handleToggleMask">
        {{showMask?'隐藏':'显示'}}蒙层
      </button>
    </view>
  </demo-block>
</view>

index.js 的代码示例如下:

const placement = [
  'top',
  'top-right',
  'top-left',
  'bottom',
  'bottom-left',
  'bottom-right',
  'left',
  'left-top',
  'left-bottom',
  'right',
  'right-top',
  'right-bottom',
];
Page({
  data: {
    placement: placement[0],
    show: true,
    showMask: false,
    showLight: true,
    showDark: true,
  },
  handleLightVisibleChange(e) {
    this.setData({
      showLight: e,
    });
  },
  handleDarkVisibleChange(e) {
    this.setData({
      showDark: e,
    });
  },
  handleNextPosition() {
    let index = placement.indexOf(this.data.placement);
    index = index >= placement.length - 1 ? 0 : index + 1;
    this.setData({
      show: true,
      placement: placement[index],
    });
  },
  handleVisibleChange(visible, mode) {
    this.setData({
      show: visible,
    });
    if (mode === 'mask') {
      my.showToast({ content: '点击mask关闭', duration: 2000 });
    }
  },
  handleToggleMask() {
    this.setData({
      showMask: !this.data.showMask,
    });
  },
});

index.acss 的代码示例如下:

.wrap {
  display: flex;
}
.wrap.dark {
  padding-bottom: 100rpx;
}
.wrap.dark .tooltip {
  color: #fff;
}
.wrap .tooltip {
  white-space: nowrap;
  font-size: 24rpx;
  padding: 16rpx;
}
.multi-demo .demo-block-content {
  background: transparent;
}

.multi-wrap {
  height: 600rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}
.multi-wrap .multi {
  background: #aaa;
  border-radius: 12rpx;
  height: 200rpx;
  width: 200rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #fff;
}
.multi-wrap .tooltip {
  color: #fff;
  font-size: 24rpx;
  padding: 16rpx;
}
.demo-btn-container {
  display: flex;
  justify-content: space-around;
}

.demo-btn {
  width: 45%;
}

index.json 的代码示例如下:

{
  "defaultTitle": "PopoverBase",
  "usingComponents": {
    "popover": "antd-mini/es/Popover/index",
    "demo-block": "../../components/DemoBlock/index",
    "button": "antd-mini/es/Button/index"
  }
}

结合 PopoverItem 组件使用

index.axml 的代码示例如下:

<view>
  <demo-block title="深色气泡菜单">
    <view class="wrap">
      <popover 
        placement="bottom-left"
        visible="{{showDark}}"
        mask
        onVisibleChange="handleDarkVisibleChange">
        <button inline inlineSize="large">点我</button>
        <block slot="items">
          <popover-item 
            onTap="handleTapItem"
            icon="ScanningOutline"
            data-type="showDark"
            data-name="扫一扫">
            扫一扫
          </popover-item>

          <popover-item 
            onTap="handleTapItem"
            icon="ReceivePaymentOutline"
            data-type="showDark"
            data-name="付钱/收钱">
            付钱/收钱
          </popover-item>

          <popover-item 
            onTap="handleTapItem"
            icon="TransportQRcodeOutline"
            data-type="showDark"
            data-name="乘车码">
            乘车码
          </popover-item>
          <popover-item 
            onTap="handleTapItem"
            data-type="showDark"
            data-name="icon 插槽">
            <image
              slot="icon"
              mode="scaleToFill"
              src="{{url}}"
              style="width: 100%;height: 100%;"/>
            icon 插槽
          </popover-item>
        </block>
      </popover>
    </view>
  </demo-block>
  <demo-block title="浅色气泡菜单">
    <view class="wrap">
      <popover 
        placement="bottom-left"
        visible="{{showLight}}"
        mode="light"
        mask
        onVisibleChange="handleLightVisibleChange">
        <button inline inlineSize="large">点我</button>
        <block slot="items">
          <popover-item 
            onTap="handleTapItem"
            icon="ScanningOutline"
            data-type="showLight"
            data-name="扫一扫">
            扫一扫
          </popover-item>

          <popover-item 
            onTap="handleTapItem"
            icon="ReceivePaymentOutline"
            data-type="showLight"
            data-name="付钱/收钱">
            付钱/收钱
          </popover-item>

            <popover-item 
              onTap="handleTapItem"
              icon="TransportQRcodeOutline"
              data-type="showLight"
              data-name="乘车码">
              乘车码
          </popover-item>
          <popover-item 
            onTap="handleTapItem"
            data-type="showLight"
            data-name="icon 插槽">
            <image
              slot="icon"
              mode="scaleToFill"
              src="{{url}}"
              style="width: 100%;height: 100%;"/>
            icon 插槽
          </popover-item>
        </block>
      </popover>
    </view>
  </demo-block>
  <demo-block title="无图标气泡菜单">
    <view class="wrap">
      <popover 
        placement="bottom-left"
        visible="{{showNoIcon}}"
        mask
        onVisibleChange="handleNoIconVisibleChange">
        <button inline inlineSize="large">点我</button>
        <block slot="items">
          <popover-item 
            onTap="handleTapItem"
            data-type="showNoIcon"
            data-name="扫一扫">
            扫一扫
          </popover-item>

          <popover-item 
            onTap="handleTapItem"
            data-type="showNoIcon"
            data-name="付钱/收钱">
            付钱/收钱
          </popover-item>

          <popover-item 
            onTap="handleTapItem"
            data-type="showNoIcon"
            data-name="乘车码">
            乘车码
          </popover-item>
        </block>
      </popover>
    </view>
  </demo-block>
  
</view>

index.js 的代码示例如下:

Page({
  data: {
    showLight: false,
    showDark: false,
    showNoIcon: false,
    url: 'https://gw.alipayobjects.com/mdn/rms_ce4c6f/afts/img/A*XMCgSYx3f50AAAAAAAAAAABkARQnAQ',
  },
  handleLightVisibleChange(e, mode) {
    this.setData({
      showLight: e,
    });
    if (mode === 'mask') {
      my.showToast({ content: '点击mask关闭', duration: 2000 });
    }
  },
  handleDarkVisibleChange(e, mode) {
    this.setData({
      showDark: e,
    });
    if (mode === 'mask') {
      my.showToast({ content: '点击mask关闭', duration: 2000 });
    }
  },
  handleNoIconVisibleChange(e, mode) {
    this.setData({
      showNoIcon: e,
    });
    if (mode === 'mask') {
      my.showToast({ content: '点击mask关闭', duration: 2000 });
    }
  },
  handleTapItem(e) {
    this.setData({
      [e.target.dataset.type]: false,
    });
    my.showToast({ content: `点击了${e.target.dataset.name}` });
  },
});

index.acss 的代码示例如下:

.wrap {
  display: flex;
}

index.json 的代码示例如下:

{
  "defaultTitle": "Popover:结合 PopoverItem 组件",
  "usingComponents": {
    "popover": "antd-mini/es/Popover/index",
    "popover-item": "antd-mini/es/Popover/PopoverItem/index",
    "demo-block": "../../components/DemoBlock/index",
    "button": "antd-mini/es/Button/index"
  }
}