Browse Source

chore: dialog

richard1015 4 years ago
parent
commit
6b8598d15c
4 changed files with 141 additions and 87 deletions
  1. 39 21
      src/packages/dialog/demo.vue
  2. 52 22
      src/packages/dialog/doc.md
  3. 44 30
      src/packages/dialog/index.ts
  4. 6 14
      src/packages/dialog/index.vue

+ 39 - 21
src/packages/dialog/demo.vue

@@ -1,49 +1,67 @@
 <template>
   <div class="demo">
-    <!-- <nut-cell title="基础弹框" @click="baseClick"></nut-cell> -->
-    <nut-cell title="标签弹框" @click="noTitleClick"></nut-cell>
+    <nut-cell title="基础弹框" @click="baseClick"></nut-cell>
+    <nut-cell title="无标题弹框" @click="noTitleClick"></nut-cell>
+    <nut-cell title="提示弹框" @click="tipsClick"></nut-cell>
+    <nut-cell title="组件调用" @click="componentClick"></nut-cell>
     <nut-dialog
-      title="标签式使用"
-      :close-on-click-overlay="false"
-      :content="content"
+      title="组件调用"
+      content="如果需要在弹窗内嵌入组件或其他自定义内容,可以使用组件调用的方式。"
       v-model:visible="visible"
     >
     </nut-dialog>
-
-    <!-- <template v-slot:header>
-        
-      </template> -->
   </div>
 </template>
 <script lang="ts">
-import { ref, getCurrentInstance } from 'vue';
+import { ref } from 'vue';
 import { createComponent } from '@/utils/create';
 const { createDemo } = createComponent('dialog');
+import { Dialog } from '@/nutui';
 export default createDemo({
-  props: {},
-
   setup() {
-    const { proxy } = getCurrentInstance();
-    const content = ref(
-      '模态对话框,在浮层中显示,引导用户进行相关操作,支持图片对话框。'
-    );
     const visible = ref(false);
 
-    const baseClick = () => {
-      proxy.$dialog({
+    const onCancel = () => {
+      console.log('event cancel');
+    };
+    const onOk = () => {
+      console.log('event ok');
+    };
+
+    const baseClick = (): void => {
+      Dialog({
         title: '基础弹框',
-        content: '基础弹框内容'
+        content: '支持函数调用和组件调用两种方式。',
+        onCancel,
+        onOk
       });
     };
     const noTitleClick = () => {
+      Dialog({
+        content: '无标题弹框',
+        onCancel,
+        onOk
+      });
+    };
+    const tipsClick = () => {
+      Dialog({
+        title: '温馨提示',
+        content: '支持函数调用和组件调用两种方式。',
+        onCancel,
+        onOk
+      });
+    };
+
+    const componentClick = () => {
       visible.value = true;
     };
 
     return {
-      content,
       visible,
       baseClick,
-      noTitleClick
+      noTitleClick,
+      componentClick,
+      tipsClick
     };
   }
 });

+ 52 - 22
src/packages/dialog/doc.md

@@ -26,7 +26,7 @@ app.use(Dialog);
 
 ``` javascript
 import { ref } from 'vue';
-
+import { Dialog } from '@nutui/nutui';
 export default {
   setup() {
     const visible = ref(true);
@@ -38,30 +38,60 @@ export default {
 };
 ```
 
+## API
+| 字段                | 说明                                  | 类型     | 默认值   |
+|---------------------|---------------------------------------|----------|----------|
+| title               | 标题                                  | String   | -        |
+| content             | 内容,支持HTML                        | String   | -        |
+| closeOnClickOverlay | 点击蒙层是否关闭对话框                | Boolean  | false    |
+| noFooter            | 是否隐藏底部按钮栏                    | Boolean  | false    |
+| noOkBtn             | 是否隐藏确定按钮                      | Boolean  | false    |
+| noCancelBtn         | 是否隐藏取消按钮                      | Boolean  | false    |
+| cancelText          | 取消按钮文案                          | String   | ”取消“   |
+| okText              | 确定按钮文案                          | String   | ”确定“   |
+| okBtnDisabled       | 禁用确定按钮                          | Boolean  | false    |
+| cancelAutoClose     | 取消按钮是否默认关闭弹窗              | Boolean  | true     |
+| textAlign           | 文字对齐方向,可选值同css的text-align | String   | "center" |
+| closeOnPopstate     | 是否在页面回退时自动关闭              | Boolean  | false    |
+| onUpdate            | 更新                                  | Boolean  | false    |
+| onOk                | 确定按钮回调                          | Function | -        |
+| onCancel            | 取消按钮回调                          | Function | -        |
+| onOpen              | 背景是否锁定                          | Function | -        |
+| onClosed            | 关闭回调,任何情况关闭弹窗都会触发    | Function | -        |
+
+
 ## Props
 
-| 字段 | 说明 | 类型 | 默认值
-|----- | ----- | ----- | ----- 
-| title | 标题 | String | -
-| content | 内容,支持HTML | String | -
-| close-on-click-overlay | 点击蒙层是否关闭对话框 | Boolean | true
-| noFooter | 是否隐藏底部按钮栏 | Boolean | false
-| noOkBtn | 是否隐藏确定按钮 | Boolean | false
-| noCancelBtn | 是否隐藏取消按钮 | Boolean | false
-| cancelText | 取消按钮文案 | String | ”取消“
-| okText | 确定按钮文案 | String | ”确 定“
-| okBtnDisabled | 禁用确定按钮 | Boolean | false
-| cancelAutoClose | 取消按钮是否默认关闭弹窗 | Boolean | true
-| textAlign | 文字对齐方向,可选值同css的text-align | String | "center"
-| closeOnPopstate | 是否在页面回退时自动关闭 | Boolean | false
-| lock-scroll | 背景是否锁定 | Boolean | false
+| 字段                   | 说明                                  | 类型    | 默认值   |
+|------------------------|---------------------------------------|---------|----------|
+| title                  | 标题                                  | String  | -        |
+| content                | 内容,支持HTML                        | String  | -        |
+| close-on-click-overlay | 点击蒙层是否关闭对话框                | Boolean | false    |
+| no-footer              | 是否隐藏底部按钮栏                    | Boolean | false    |
+| no-ok-btn              | 是否隐藏确定按钮                      | Boolean | false    |
+| no-cancel-btn          | 是否隐藏取消按钮                      | Boolean | false    |
+| cancel-text            | 取消按钮文案                          | String  | ”取消“   |
+| ok-text                | 确定按钮文案                          | String  | ”确 定“  |
+| ok-btn-disabled        | 禁用确定按钮                          | Boolean | false    |
+| cancel-auto-close      | 取消按钮是否默认关闭弹窗              | Boolean | true     |
+| text-align             | 文字对齐方向,可选值同css的text-align | String  | "center" |
+| close-on-popstate      | 是否在页面回退时自动关闭              | Boolean | false    |
+| lock-scroll            | 背景是否锁定                          | Boolean | false    |
 
 
 ## Events
 
-| 字段 | 说明 | 类型 | 默认值
-|----- | ----- | ----- | ----- 
-| ok | 确定按钮回调 | Function | -
-| cancel | 取消按钮回调 | Function | -
-| open | 关闭按钮回调 | Function | -
-| closed | 关闭回调,任何情况关闭弹窗都会触发 | Function | -
+| 字段   | 说明                               | 类型     | 默认值 |
+|--------|------------------------------------|----------|--------|
+| ok     | 确定按钮回调                       | Function | -      |
+| cancel | 取消按钮回调                       | Function | -      |
+| closed | 关闭回调,任何情况关闭弹窗都会触发 | Function | -      |
+
+
+## Slots
+
+| 名称    | 说明               |
+|---------|--------------------|
+| header  | 自定义标题区域     |
+| default | 自定义内容         |
+| footer  | 自定义底部按钮区域 |

+ 44 - 30
src/packages/dialog/index.ts

@@ -1,39 +1,52 @@
-import dialogInstance from './index.vue';
-import { render, createVNode, ref } from 'vue';
-export const show = ref(false);
+import Dialog from './index.vue';
+import { render, createVNode, h } from 'vue';
 export class DialogOptions {
-  title: string = '';
-  content: string = '';
-  cancelText: string = '取消';
-  okText: string = '确定';
-  textAlign: string = 'center';
-  teleport: String | Element = 'body';
+  title?: string = '';
+  content?: string = '';
+  cancelText?: string = '取消';
+  okText?: string = '确定';
+  textAlign?: string = 'center';
+  teleport?: String = 'body';
 
   // function
-  private onUpdate: Function = (value: boolean) => {
-    show.value = value;
-  };
-  onOk: Function = () => {};
-  onCancel: Function = () => {};
-  onClose: Function = () => {};
-  onClosed: Function = () => {};
-
-  noFooter: boolean = false;
-  noOkBtn: boolean = false;
-  noCancelBtn: boolean = false;
-  okBtnDisabled: boolean = false;
-  closeOnPopstate: boolean = false;
-  lockScroll: boolean = false;
+  onUpdate?: Function = (value: boolean) => {};
+  onOk?: Function = () => {};
+  onCancel?: Function = () => {};
+  onClose?: Function = () => {};
+  onClosed?: Function = () => {};
+
+  visible?: boolean = true;
+  noFooter?: boolean = false;
+  noOkBtn?: boolean = false;
+  noCancelBtn?: boolean = false;
+  okBtnDisabled?: boolean = false;
+  closeOnPopstate?: boolean = false;
+  lockScroll?: boolean = false;
 }
 
-class Dialog {
+class DialogFunction {
   options: DialogOptions = new DialogOptions();
 
   constructor(_options: DialogOptions) {
-    Object.assign(this.options, _options);
-    show.value = true;
-    const instance: any = createVNode(dialogInstance, this.options as any);
-    render(instance, document.body);
+    let options = Object.assign(this.options, _options);
+    const root = document.createElement('view');
+    root.id = 'dialog-' + new Date().getTime();
+    const Wrapper = {
+      setup() {
+        options.onUpdate = (val: boolean) => {
+          if (val == false) {
+            document.body.removeChild(root);
+          }
+        };
+        options.teleport = `#${root.id}`;
+        return () => {
+          return h(Dialog, options);
+        };
+      }
+    };
+    const instance: any = createVNode(Wrapper);
+    document.body.appendChild(root);
+    render(instance, root);
   }
 
   close = () => {
@@ -52,10 +65,11 @@ class Dialog {
 }
 
 const _Dialog = function(options: DialogOptions) {
-  return new Dialog(options);
+  return new DialogFunction(options);
 };
 _Dialog.install = (app: any) => {
-  app.use(dialogInstance);
+  app.use(Dialog);
   app.config.globalProperties.$dialog = _Dialog;
 };
+export { Dialog };
 export default _Dialog;

+ 6 - 14
src/packages/dialog/index.vue

@@ -1,6 +1,5 @@
 <template>
   <nut-popup
-    name="pop"
     :teleport="teleport"
     v-model:visible="showPopup"
     :close-on-click-overlay="closeOnClickOverlay"
@@ -50,11 +49,11 @@
   </nut-popup>
 </template>
 <script lang="ts">
-import { onMounted, computed, watch, onUnmounted, ref, toRefs } from 'vue';
+import { onMounted, computed, watch, ref } from 'vue';
 import { createComponent } from '@/utils/create';
 const { componentName, create } = createComponent('dialog');
-import { Button, Popup } from '@/nutui';
-import { show } from './index';
+import Popup, { popupProps } from '@/packages/popup/index.vue';
+import { Button } from '@/nutui';
 export default create({
   inheritAttrs: false,
   children: [Popup, Button],
@@ -63,8 +62,8 @@ export default create({
     'nut-button': Button
   },
   props: {
-    ...Popup.popupProps,
-    visible: {
+    ...popupProps,
+    closeOnClickOverlay: {
       type: Boolean,
       default: false
     },
@@ -140,9 +139,7 @@ export default create({
     'closed'
   ],
   setup(props, { emit }) {
-    const showPopup = ref(false);
-    showPopup.value = show.value;
-
+    const showPopup = ref(props.visible);
     onMounted(() => {
       if (props.closeOnPopstate) {
         window.addEventListener('popstate', function() {
@@ -151,10 +148,6 @@ export default create({
       }
     });
 
-    watch(show, value => {
-      showPopup.value = value;
-    });
-
     watch(
       () => props.visible,
       value => {
@@ -195,7 +188,6 @@ export default create({
       classes,
       onCancel,
       onOk,
-      show,
       showPopup
     };
   }