浏览代码

feat(dialog): 函数式使用支持挂载指定节点teleport功能

richard1015 4 年之前
父节点
当前提交
79a89f4a55
共有 3 个文件被更改,包括 81 次插入14 次删除
  1. 36 11
      src/packages/dialog/demo.vue
  2. 33 0
      src/packages/dialog/doc.md
  3. 12 3
      src/packages/dialog/index.ts

+ 36 - 11
src/packages/dialog/demo.vue

@@ -1,15 +1,29 @@
 <template>
   <div class="demo">
-    <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="组件调用"
-      content="如果需要在弹窗内嵌入组件或其他自定义内容,可以使用组件调用的方式。"
-      v-model:visible="visible"
-    >
-    </nut-dialog>
+    <nut-cell-group title="函数式调用">
+      <nut-cell title="基础弹框" @click="baseClick"></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-group>
+    <nut-cell-group title="标签式调用">
+      <nut-cell title="组件调用" @click="componentClick"></nut-cell>
+      <nut-dialog
+        teleport="#app"
+        title="组件调用"
+        content="如果需要在弹窗内嵌入组件或其他自定义内容,可以使用组件调用的方式。"
+        v-model:visible="visible"
+      >
+      </nut-dialog>
+    </nut-cell-group>
+    <nut-cell-group title="teleport 使用,挂载到指定节点">
+      <nut-cell title="body 节点下" @click="teleportClick('body')"></nut-cell>
+      <nut-cell title="#app 节点下" @click="teleportClick('#app')"></nut-cell>
+      <nut-cell
+        title="demo class 元素节点下"
+        @click="teleportClick('.demo')"
+      ></nut-cell>
+    </nut-cell-group>
   </div>
 </template>
 <script lang="ts">
@@ -57,12 +71,23 @@ export default createDemo({
       visible.value = true;
     };
 
+    const teleportClick = (teleport: string) => {
+      Dialog({
+        teleport,
+        title: '挂载至 ' + teleport,
+        content: '打开开发者工具看一下 Elements Tab',
+        noCancelBtn: true,
+        onCancel
+      });
+    };
+
     return {
       visible,
       baseClick,
       noTitleClick,
       componentClick,
-      tipsClick
+      tipsClick,
+      teleportClick
     };
   }
 });

+ 33 - 0
src/packages/dialog/doc.md

@@ -38,6 +38,37 @@ Dialog({
 ```
 
 
+## teleport 使用,挂载到指定节点
+
+``` html
+<nut-dialog teleport="#app" ... />
+```
+
+``` javascript
+Dialog({
+  teleport: '#app',
+  ...
+});
+Dialog({
+  teleport: '.demo',
+  ...
+});
+```
+
+## 函数调用 proxy.&dialog(...)
+
+``` javascript
+import { getCurrentInstance } from 'vue';
+
+setup(){
+  const { proxy } = getCurrentInstance();
+  proxy.$dialog({
+    title: '基础弹框',
+    content: '支持函数调用和组件调用两种方式。'
+  });
+}
+```
+
 
 ## 标签式组件使用
 
@@ -64,6 +95,7 @@ export default {
 |---------------------|---------------------------------------|----------|----------|
 | title               | 标题                                  | String   | -        |
 | content             | 内容,支持HTML                        | String   | -        |
+| teleport            | 指定挂载节点                          | String   | "body"   |
 | closeOnClickOverlay | 点击蒙层是否关闭对话框                | Boolean  | false    |
 | noFooter            | 是否隐藏底部按钮栏                    | Boolean  | false    |
 | noOkBtn             | 是否隐藏确定按钮                      | Boolean  | false    |
@@ -87,6 +119,7 @@ export default {
 |------------------------|---------------------------------------|---------|----------|
 | title                  | 标题                                  | String  | -        |
 | content                | 内容,支持HTML                        | String  | -        |
+| teleport               | 指定挂载节点                          | String  | "body"   |
 | close-on-click-overlay | 点击蒙层是否关闭对话框                | Boolean | false    |
 | no-footer              | 是否隐藏底部按钮栏                    | Boolean | false    |
 | no-ok-btn              | 是否隐藏确定按钮                      | Boolean | false    |

+ 12 - 3
src/packages/dialog/index.ts

@@ -6,7 +6,7 @@ export class DialogOptions {
   cancelText?: string = '取消';
   okText?: string = '确定';
   textAlign?: string = 'center';
-  teleport?: String = 'body';
+  teleport?: String | HTMLElement = 'body';
 
   // function
   onUpdate?: Function = (value: boolean) => {};
@@ -29,13 +29,22 @@ class DialogFunction {
 
   constructor(_options: DialogOptions) {
     let options = Object.assign(this.options, _options);
+    let elWarp: HTMLElement = document.body;
+    let teleport = _options.teleport as string;
+    if (teleport != 'body') {
+      if (typeof teleport == 'string') {
+        elWarp = document.querySelector(teleport) as HTMLElement;
+      } else {
+        elWarp = _options.teleport as HTMLElement;
+      }
+    }
     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);
+            elWarp.removeChild(root);
           }
         };
         options.teleport = `#${root.id}`;
@@ -45,7 +54,7 @@ class DialogFunction {
       }
     };
     const instance: any = createVNode(Wrapper);
-    document.body.appendChild(root);
+    elWarp.appendChild(root);
     render(instance, root);
   }