其他分享
首页 > 其他分享> > 高扩展弹出层组件设计实现

高扩展弹出层组件设计实现

作者:互联网

背景

随着业务的发展,弹窗逐渐替代翻页,承载越来越多的用户需求。由于没有统一、好用的公共弹窗组件,业务同学通常会编写属于自己的弹窗,这造成了一些问题:

我们急切的需要提供一个公共的弹窗组件,不仅要解决以上问题,还必须满足各种业务需求。

设计分析

分析过往的 UI,最常用的弹窗有下面两种:


由此可以得出如下结论:

设计实现

解决滚动穿透问题

打开弹窗,给body设置类名hl-overflow-hidden,关闭弹窗则移除。

document.body.classList.add('hl-overflow-hidden');
document.body.classList.remove('hl-overflow-hidden');


.hl-overflow-hidden {
  overflow: hidden!important;
}

解决蒙层滚动穿透,核心在于设置touchmove

<div @touchmove="preventDefault"></div>
function preventDefault(event) {
  if (typeof event.cancelable !== 'boolean' || event.cancelable) {
    event.preventDefault();
  }
  event.stopPropagation()
}

高度自定义容器设计

将容器从上到下分为三个部分:head/body/foot。

head 区既可以便捷设置title,也可完全自定义。

body 区设置为默认插槽,根据内容高度自动设置滚动,并emit滚动事件。

foot 区由用户自定义,默认不展示。

<div class="huoli-popup fx-col" :style="{ height }">
  <div class="huoli-popup-hd">
    <template v-if="title">{{title}}</template>
    <slot v-else name="title"></slot>
    <img v-if="closable" 
    src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAElBMVEVHcEw0N0o0OEouLkY0N0kwMFAuyLj8AAAABnRSTlMAT4ALcBBngfhBAAAAZUlEQVQoz2NgoA4wgDGYIRSrI0xAJABMmSgJQPiMSs5QWhEiIASTgTLgEjAWXAGUiVAAZSMpAHOQFYCVoCgAKUFRAFKCqgBTAF0LhqHo1mI4DN3pGJ5D9z5GAGEEIUYgY0QDxQAAIDoMW2GxKeQAAAAASUVORK5CYII="
    @click="onClickClose" />
  </div>

  <div class="huoli-popup-bd" @scroll="onScroll">
    <slot></slot>
  </div>

  <div class="huoli-popup-foot"><slot name="foot"></slot></div>
</div>

无依赖简单实现

详见

结合 vant 使用

<template>
  <Popup 
    v-model="show"
    position="bottom"
    round
    :style="{ height, overflow: 'hidden' }"
    get-container="body"
    @close="onClickClose"
  >
    <div class="huoli-popup fx-col">
      <div class="huoli-popup-hd">
        <slot v-else name="title"></slot>
        <img v-if="closable" src="./img/close@2x.png" class="huoli-popup-close-icon" @click="onClickClose" />
      </div>
      <div class="huoli-popup-bd" @scroll="onScroll">
        <slot></slot>
      </div>
      <div class="huoli-popup-foot"><slot name="foot"></slot></div>
    </div>
  </Popup>
</template>

<script>
import { Popup } from "huoli-ui"
export default {
  name: 'huoli-popup',
  props: {
    show: {
      type: Boolean,
      default: false,
    },
    closable: {
      type: Boolean,
      default: false,
    },
    height: {
      type: String,
      default: ',
    },
  },
  components: {
    Popup
  },
  methods: {
    onClickClose() {
      this.$emit('hide');
    },
    onScroll: throttle(function(e) {
      this.$emit('scroll', e)
    })
  }
}
function throttle(func, wait = 50, immediate) {
  let timeout
  return function() {
    const context = this;
    const args = arguments;
    if (immediate) {
      func.apply(context, args);
      immediate = false
    }

    if (timeout) return

    timeout = setTimeout(function() {
      timeout = null;
      func.apply(context, args)
    }, wait);
  }
}
</script>

<style lang="scss">
.huoli-popup {
  height: 100%;
  .huoli-popup-hd {
    min-height: 48px;
    width: 100%;
    background: inherit;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;

    font-size: 16px;
    font-weight: 400;
    color: #262626;
    line-height: 20px;
  }
  .huoli-popup-close-icon {
    position: absolute;
    width: 16px;
    height: 16px;
    right: 16px;
    top: 16px;
  }
  .huoli-popup-bd {
    flex: 1;
    box-sizing: border-box;
    overflow-y: auto;
  }
}
</style>

标签:body,扩展,event,huoli,弹出,组件,overflow,hidden,弹窗
来源: https://www.cnblogs.com/fayin/p/16465973.html