浏览代码

feat: overlay组件

suzigang 5 年之前
父节点
当前提交
b543bc5672

+ 273 - 265
src/config.js

@@ -1,370 +1,378 @@
 module.exports = {
-  versions: [
+  "versions": [
     {
-      name: '1.x',
-      link: '/1x/'
+      "name": "1.x",
+      "link": "/1x/"
     },
     {
-      name: '2.x',
-      link: '/'
+      "name": "2.x",
+      "link": "/"
     },
     {
-      name: '3.x',
-      link: '/3x/'
+      "name": "3.x",
+      "link": "/3x/"
     }
   ],
-  header: [
+  "header": [
     {
-      name: 'guide',
-      cName: '指南',
-      path: '/'
+      "name": "guide",
+      "cName": "指南",
+      "path": "/"
     },
     {
-      name: '/',
-      cName: '组件',
-      path: '/'
+      "name": "/",
+      "cName": "组件",
+      "path": "/"
     },
     {
-      name: 'example',
-      cName: '示例',
-      path: '/'
+      "name": "example",
+      "cName": "示例",
+      "path": "/"
     },
     {
-      name: 'resource',
-      cName: '资源',
-      path: '/resource'
+      "name": "resource",
+      "cName": "资源",
+      "path": "/resource"
     }
   ],
-  docs: {
-    name: '指南',
-    packages: [
+  "docs": {
+    "name": "指南",
+    "packages": [
       {
-        name: 'intro',
-        cName: '介绍',
-        show: true
+        "name": "intro",
+        "cName": "介绍",
+        "show": true
       },
       {
-        name: 'start',
-        cName: '快速上手',
-        show: true
+        "name": "start",
+        "cName": "快速上手",
+        "show": true
       },
       {
-        name: 'theme',
-        cName: '主题定制',
-        show: true
+        "name": "theme",
+        "cName": "主题定制",
+        "show": true
       },
       {
-        name: 'international',
-        cName: '国际化',
-        show: true
+        "name": "international",
+        "cName": "国际化",
+        "show": true
       },
       {
-        name: 'https://github.com/jdf2e/nutui/releases',
-        cName: '更新日志',
-        show: true,
-        isLink: true
+        "name": "https://github.com/jdf2e/nutui/releases",
+        "cName": "更新日志",
+        "show": true,
+        "isLink": true
       }
     ]
   },
-  nav: [
+  "nav": [
     {
-      name: '布局组件',
-      packages: [
+      "name": "布局组件",
+      "packages": [
         {
-          name: 'Button',
-          sort: 1,
-          cName: '按钮组件',
-          type: 'component',
-          show: true,
-          desc: '按钮用于触发一个操作,如提交表单。',
-          author: 'richard1015'
+          "name": "Button",
+          "sort": 1,
+          "cName": "按钮组件",
+          "type": "component",
+          "show": true,
+          "desc": "按钮用于触发一个操作,如提交表单。",
+          "author": "richard1015"
         },
         {
-          name: 'collapse',
-          sort: 2,
-          cName: '折叠面板',
-          type: 'component',
-          show: true,
-          desc: '折叠面板',
-          author: 'Ymm0008'
+          "name": "collapse",
+          "sort": 2,
+          "cName": "折叠面板",
+          "type": "component",
+          "show": true,
+          "desc": "折叠面板",
+          "author": "Ymm0008"
         },
         {
-          name: 'collapse',
-          sort: 3,
-          cName: '折叠面板-item',
-          type: 'component',
-          show: false,
-          desc: '折叠面板-item',
-          author: 'Ymm0008'
+          "name": "collapse",
+          "sort": 3,
+          "cName": "折叠面板-item",
+          "type": "component",
+          "show": false,
+          "desc": "折叠面板-item",
+          "author": "Ymm0008"
         },
         {
-          name: 'Layout',
-          sort: 4,
-          cName: '布局',
-          type: 'component',
-          show: true,
-          desc: '简便地创建布局',
-          author: 'undo'
+          "name": "Layout",
+          "sort": 4,
+          "cName": "布局",
+          "type": "component",
+          "show": true,
+          "desc": "简便地创建布局",
+          "author": "undo"
         },
         {
-          name: 'col',
-          sort: 5,
-          cName: '布局-Col',
-          type: 'component',
-          show: false,
-          desc: '布局组件Col',
-          author: 'undo'
+          "name": "col",
+          "sort": 5,
+          "cName": "布局-Col",
+          "type": "component",
+          "show": false,
+          "desc": "布局组件Col",
+          "author": "undo"
         },
         {
-          name: 'row',
-          sort: 6,
-          cName: '布局-Row',
-          type: 'component',
-          show: false,
-          desc: '布局组件Row',
-          author: 'undo'
+          "name": "row",
+          "sort": 6,
+          "cName": "布局-Row",
+          "type": "component",
+          "show": false,
+          "desc": "布局组件Row",
+          "author": "undo"
         }
       ]
     },
     {
-      name: '操作反馈',
-      packages: [
+      "name": "操作反馈",
+      "packages": [
         {
-          name: 'BackTop',
-          sort: '1',
-          cName: '回到顶部',
-          type: 'component',
-          show: true,
-          desc: '较长页面快捷回到顶部',
-          author: 'liqiong43'
+          "name": "BackTop",
+          "sort": "1",
+          "cName": "回到顶部",
+          "type": "component",
+          "show": true,
+          "desc": "较长页面快捷回到顶部",
+          "author": "liqiong43"
         }
       ]
     },
     {
-      name: '基础组件',
-      packages: [
+      "name": "基础组件",
+      "packages": [
         {
-          name: 'Temp',
-          sort: 1,
-          cName: '模板组件',
-          type: 'component',
-          show: true,
-          desc: '组件模板示例',
-          author: 'richard1015'
+          "name": "Temp",
+          "sort": 1,
+          "cName": "模板组件",
+          "type": "component",
+          "show": true,
+          "desc": "组件模板示例",
+          "author": "richard1015"
         },
         {
-          name: 'Cell',
-          sort: 1,
-          cName: '单元格组件',
-          type: 'component',
-          show: true,
-          desc: '展示列表',
-          author: 'richard1015'
+          "name": "Cell",
+          "sort": 1,
+          "cName": "单元格组件",
+          "type": "component",
+          "show": true,
+          "desc": "展示列表",
+          "author": "richard1015"
         },
         {
-          name: 'Uploader',
-          sort: 2,
-          cName: '上传组件',
-          type: 'component',
-          show: true,
-          desc: '上传文件、图片',
-          author: 'richard1015'
+          "name": "Uploader",
+          "sort": 2,
+          "cName": "上传组件",
+          "type": "component",
+          "show": true,
+          "desc": "上传文件、图片",
+          "author": "richard1015"
         },
         {
-          name: 'Icon',
-          sort: 3,
-          cName: '图标组件',
-          type: 'component',
-          show: true,
-          desc: '图标',
-          author: 'richard1015'
+          "name": "Icon",
+          "sort": 3,
+          "cName": "图标组件",
+          "type": "component",
+          "show": true,
+          "desc": "图标",
+          "author": "richard1015"
         },
         {
-          name: 'Price',
-          sort: 4,
-          cName: '价格组件',
-          type: 'component',
-          show: true,
-          desc: '价格组件',
-          author: 'ailululu'
+          "name": "Price",
+          "sort": 4,
+          "cName": "价格组件",
+          "type": "component",
+          "show": true,
+          "desc": "价格组件",
+          "author": "ailululu"
         },
         {
-          name: 'Checkbox',
-          sort: 5,
-          cName: '复选按钮',
-          type: 'component',
-          show: true,
-          desc: '复选按钮',
-          author: 'Ymm0008'
+          "name": "Checkbox",
+          "sort": 5,
+          "cName": "复选按钮",
+          "type": "component",
+          "show": true,
+          "desc": "复选按钮",
+          "author": "Ymm0008"
         },
         {
-          name: 'Swiper',
-          sort: 6,
-          cName: '轮播',
-          type: 'component',
-          show: true,
-          desc: '轮播',
-          author: 'ailululu'
+          "name": "Swiper",
+          "sort": 6,
+          "cName": "轮播",
+          "type": "component",
+          "show": true,
+          "desc": "轮播",
+          "author": "ailululu"
         },
         {
-          name: 'Avatar',
-          sort: 7,
-          cName: '头像',
-          type: 'component',
-          show: true,
-          desc: '头像',
-          author: 'ailululu'
+          "name": "Avatar",
+          "sort": 7,
+          "cName": "头像",
+          "type": "component",
+          "show": true,
+          "desc": "头像",
+          "author": "ailululu"
         },
         {
-          name: 'Popup',
-          sort: 8,
-          cName: '弹出层',
-          type: 'component',
-          show: true,
-          desc:
-            '弹出层容器,用于展示弹窗、信息提示等内容,支持多个弹出层叠加展示',
-          author: 'szg2008',
-          version: '3.0.0'
+          "name": "Popup",
+          "sort": 8,
+          "cName": "弹出层",
+          "type": "component",
+          "show": true,
+          "desc": "弹出层容器,用于展示弹窗、信息提示等内容,支持多个弹出层叠加展示",
+          "author": "szg2008",
+          "version": "3.0.0"
         },
         {
-          name: 'Dialog',
-          type: 'component',
-          cName: '对话框',
-          desc:
-            '模态对话框,在浮层中显示,引导用户进行相关操作,支持图片对话框。',
-          sort: 8,
-          show: true,
-          author: 'dsj'
+          "name": "Dialog",
+          "type": "component",
+          "cName": "对话框",
+          "desc": "模态对话框,在浮层中显示,引导用户进行相关操作,支持图片对话框。",
+          "sort": 8,
+          "show": true,
+          "author": "dsj"
         },
         {
-          version: '3.0.0',
-          name: 'Radio',
-          type: 'component',
-          cName: '单选按钮',
-          desc: '单选按钮',
-          sort: 9,
-          show: true,
-          author: 'Ymm0008'
+          "version": "3.0.0",
+          "name": "Radio",
+          "type": "component",
+          "cName": "单选按钮",
+          "desc": "单选按钮",
+          "sort": 9,
+          "show": true,
+          "author": "Ymm0008"
         },
         {
-          version: '3.0.0',
-          name: 'RadioGroup',
-          type: 'component',
-          cName: '单选按钮组',
-          desc: '单选按钮组',
-          sort: 10,
-          show: false,
-          author: 'Ymm0008'
+          "version": "3.0.0",
+          "name": "RadioGroup",
+          "type": "component",
+          "cName": "单选按钮组",
+          "desc": "单选按钮组",
+          "sort": 10,
+          "show": false,
+          "author": "Ymm0008"
         },
         {
-          version: '3.0.0',
-          name: 'CheckboxGroup',
-          type: 'component',
-          cName: '多选按钮组',
-          desc: '多选按钮组',
-          sort: 11,
-          show: false,
-          author: 'Ymm0008'
+          "version": "3.0.0",
+          "name": "CheckboxGroup",
+          "type": "component",
+          "cName": "多选按钮组",
+          "desc": "多选按钮组",
+          "sort": 11,
+          "show": false,
+          "author": "Ymm0008"
+        },
+        {
+          "version": "3.0.0",
+          "name": "OverLay",
+          "type": "component",
+          "cName": "遮罩层",
+          "desc": "创建一个遮罩层,通常用于阻止用户进行其他操作",
+          "sort": 14,
+          "show": true,
+          "author": "szg2008"
         }
       ]
     },
     {
-      name: '导航组件',
-      packages: [
+      "name": "导航组件",
+      "packages": [
         {
-          name: 'Navbar',
-          sort: 3,
-          cName: '导航组件',
-          type: 'componment',
-          show: true,
-          desc: '导航组件',
-          author: 'liqiong43'
+          "name": "Navbar",
+          "sort": 3,
+          "cName": "导航组件",
+          "type": "componment",
+          "show": true,
+          "desc": "导航组件",
+          "author": "liqiong43"
         },
         {
-          name: 'tab',
-          sort: 1,
-          cName: '标签组件',
-          type: 'component',
-          show: true,
-          desc: '标签组件',
-          author: 'zhenyulei'
+          "name": "tab",
+          "sort": 1,
+          "cName": "标签组件",
+          "type": "component",
+          "show": true,
+          "desc": "标签组件",
+          "author": "zhenyulei"
         },
         {
-          name: 'menu',
-          sort: 2,
-          cName: '菜单组件',
-          type: 'component',
-          show: true,
-          desc: '下拉菜单组件',
-          author: 'vickyYE'
+          "name": "menu",
+          "sort": 2,
+          "cName": "菜单组件",
+          "type": "component",
+          "show": true,
+          "desc": "下拉菜单组件",
+          "author": "vickyYE"
         },
         {
-          name: 'tabbar',
-          sort: 2,
-          cName: '标签栏组件',
-          type: 'component',
-          show: true,
-          desc: '标签栏组件',
-          author: 'Drjingfubo'
+          "name": "tabbar",
+          "sort": 2,
+          "cName": "标签栏组件",
+          "type": "component",
+          "show": true,
+          "desc": "标签栏组件",
+          "author": "Drjingfubo"
         }
       ]
     },
     {
-      name: '数据录入',
-      packages: [
+      "name": "数据录入",
+      "packages": [
         {
-          name: 'InputNumber',
-          sort: 1,
-          cName: '数字输入框',
-          type: 'component',
-          show: true,
-          desc: '数字输入框组件',
-          author: 'szg2008'
+          "name": "InputNumber",
+          "sort": 1,
+          "cName": "数字输入框",
+          "type": "component",
+          "show": true,
+          "desc": "数字输入框组件",
+          "author": "szg2008"
         },
         {
-          name: 'Input',
-          sort: 2,
-          cName: '输入框',
-          type: 'component',
-          show: true,
-          desc: '输入框组件',
-          author: 'gxx158'
+          "name": "Input",
+          "sort": 2,
+          "cName": "输入框",
+          "type": "component",
+          "show": true,
+          "desc": "输入框组件",
+          "author": "gxx158"
         },
         {
-          version: '3.0.0',
-          name: 'Switch',
-          type: 'component',
-          cName: '开关组件',
-          desc: '用来打开或关闭选项',
-          sort: 3,
-          show: true,
-          author: 'zongyue3'
+          "version": "3.0.0",
+          "name": "Switch",
+          "type": "component",
+          "cName": "开关组件",
+          "desc": "用来打开或关闭选项",
+          "sort": 3,
+          "show": true,
+          "author": "zongyue3"
         },
         {
-          version: '3.0.0',
-          name: 'Rate',
-          sort: 4,
-          cName: '评分',
-          type: 'component',
-          show: true,
-          desc: '评分组件',
-          author: 'undo'
+          "version": "3.0.0",
+          "name": "Rate",
+          "sort": 4,
+          "cName": "评分",
+          "type": "component",
+          "show": true,
+          "desc": "评分组件",
+          "author": "undo"
         },
         {
-          version: '3.0.0',
-          name: 'Calendar',
-          type: 'component',
-          cName: '日历',
-          desc: '日历组件',
-          sort: 5,
-          show: true,
-          author: ''
+          "version": "3.0.0",
+          "name": "Calendar",
+          "type": "component",
+          "cName": "日历",
+          "desc": "日历组件",
+          "sort": 5,
+          "show": true,
+          "author": ""
         }
       ]
     },
     {
-      name: '业务组件',
-      packages: []
+      "name": "业务组件",
+      "packages": []
     }
   ]
-};
+};

+ 59 - 0
src/packages/overlay/demo.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="demo">
+    <h2>基础用法</h2>
+    <nut-cell>
+      <nut-button type="primary" @click="state.show = true"
+        >显示遮罩层</nut-button
+      >
+      <nut-overlay v-model:show="state.show" :z-index="2000"></nut-overlay>
+    </nut-cell>
+    <h2>嵌套内容</h2>
+    <nut-cell>
+      <nut-button type="success" @click="state.show2 = true"
+        >嵌套内容</nut-button
+      >
+      <nut-overlay v-model:show="state.show2" :z-index="2000">
+        <div class="wrapper">
+          <div class="content">这里是正文</div>
+        </div>
+      </nut-overlay>
+    </nut-cell>
+  </div>
+</template>
+
+<script lang="ts">
+import { reactive } from 'vue';
+import { createComponent } from '@/utils/create';
+const { createDemo } = createComponent('overlay');
+export default createDemo({
+  props: {},
+  setup() {
+    const state = reactive({
+      show: false,
+      show2: false
+    });
+    return {
+      state
+    };
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+.wrapper {
+  display: flex;
+  height: 100%;
+  align-items: center;
+  justify-content: center;
+  .content {
+    display: flex;
+    width: 150px;
+    height: 150px;
+    background: #fff;
+    border-radius: 8px;
+    align-items: center;
+    justify-content: center;
+    color: red;
+  }
+}
+</style>

+ 54 - 0
src/packages/overlay/doc.md

@@ -0,0 +1,54 @@
+# overlay 组件
+
+### 介绍
+
+创建一个遮罩层,通常用于阻止用户进行其他操作
+
+### 安装
+
+```javascript
+import { createApp } from 'vue';
+import { OverLay } from '@nutui/nutui';
+
+const app = createApp();
+app.use(OverLay);
+```
+
+## 代码演示
+
+### 基础用法
+
+```html
+<nut-overlay v-model:show="state.show" :z-index="2000"></nut-overlay>
+```
+
+### 弹出位置
+
+```html
+<nut-overlay v-model:show="state.show2" :z-index="2000">
+  <div class="wrapper">
+    <div class="content">这里是正文</div>
+  </div>
+</nut-overlay>
+```
+
+## API
+
+### Props
+
+| 参数                   | 说明             | 类型           | 默认值 |
+| ---------------------- | ---------------- | -------------- | ------ |
+| show                   | 当前组件是否显示 | Boolean        | false  |
+| z-index                | 遮罩层级         | String、Number | 2000   |
+| duration               | 动画时长,单位秒 | String、Number | 0.3    |
+| overlay-class          | 自定义遮罩类名   | String         | -      |
+| overlay-style          | 自定义遮罩样式   | CSSProperties  | -      |
+| lock-scroll            | 背景是否锁定     | Boolean        | false  |
+| overlay                | 是否显示遮罩     | Boolean        | true   |
+| close-on-click-overlay | 是否点击遮罩关闭 | Boolean        | true   |
+
+### Events
+
+| 事件名 | 说明       | 回调参数     |
+| ------ | ---------- | ------------ |
+| click  | 点击时触发 | event: Event |

+ 36 - 0
src/packages/overlay/index.scss

@@ -0,0 +1,36 @@
+.overlay-fade-enter-active {
+  animation: nut-fade-in;
+}
+
+.overlay-fade-leave-active {
+  animation: nut-fade-out;
+}
+
+.nut-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.7);
+}
+
+@keyframes nut-fade-in {
+  from {
+    opacity: 0;
+  }
+
+  to {
+    opacity: 1;
+  }
+}
+
+@keyframes nut-fade-out {
+  from {
+    opacity: 1;
+  }
+
+  to {
+    opacity: 0;
+  }
+}

+ 20 - 7
src/packages/popup/overlay/index.vue

@@ -1,17 +1,20 @@
 <template>
-  <Transition name="popup-fade">
+  <Transition name="overlay-fade">
     <view
       @touchmove.stop="touchmove"
+      @click="onClick"
       :style="{ animationDuration: `${duration}s`, ...overlayStyle, zIndex }"
       v-show="show"
       :class="classes"
-    ></view>
+    >
+      <slot></slot>
+    </view>
   </Transition>
 </template>
 <script lang="ts">
 import { CSSProperties, PropType, computed } from 'vue';
 import { createComponent } from '@/utils/create';
-const { componentName, create } = createComponent('popup-overlay');
+const { componentName, create } = createComponent('overlay');
 const overlayProps = {
   show: {
     type: Boolean,
@@ -49,13 +52,12 @@ export { overlayProps };
 
 export default create({
   props: overlayProps,
-  emits: [],
-  setup(props) {
+  emits: ['click', 'update:show'],
+  setup(props, { emit }) {
     const classes = computed(() => {
       const prefixCls = componentName;
       return {
         [prefixCls]: true,
-        ['nut-mask']: true,
         [props.overlayClass]: true
       };
     });
@@ -64,7 +66,18 @@ export default create({
         e.preventDefault();
       }
     };
-    return { classes, touchmove };
+
+    const onClick = e => {
+      emit('click', e);
+      if (props.closeOnClickOverlay) {
+        emit('update:show', false);
+      }
+    };
+
+    return { classes, touchmove, onClick };
   }
 });
 </script>
+<style lang="scss">
+@import 'index.scss';
+</style>

+ 0 - 17
src/packages/popup/index.scss

@@ -1,11 +1,3 @@
-.popup-fade-enter-active {
-  animation: nut-fade-in;
-}
-
-.popup-fade-leave-active {
-  animation: nut-fade-out;
-}
-
 .popup-slide {
   &-center-enter-active {
     animation: nut-fade-in;
@@ -145,12 +137,3 @@
     }
   }
 }
-
-.nut-popup-overlay {
-  position: fixed;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  background-color: rgba(0, 0, 0, 0.7);
-}

+ 2 - 6
src/packages/popup/index.vue

@@ -1,8 +1,7 @@
 <template>
   <Teleport :to="teleport">
-    <nut-popup-overlay
+    <nut-overlay
       :show="show && overlay"
-      v-if="state.overLayCount === 1"
       :class="overlayClass"
       :style="overlayStyle"
       :zIndex="state.zIndex"
@@ -43,7 +42,7 @@ import {
   CSSProperties
 } from 'vue';
 import { useLockScroll } from './use-lock-scroll';
-import Overlay, { overlayProps } from './overlay/index.vue';
+import { overlayProps } from './../overlay/index.vue';
 import { createComponent } from '@/utils/create';
 const { componentName, create } = createComponent('popup');
 
@@ -101,9 +100,6 @@ const popupProps = {
 };
 
 export default create({
-  Component: {
-    'nut-popup-overlay': Overlay
-  },
   props: {
     ...overlayProps,
     ...popupProps