浏览代码

feat: dialog taro

richard1015 4 年之前
父节点
当前提交
01de2ea97f

+ 1 - 3
jd/generate-nutui-taro-vue.js

@@ -8,9 +8,7 @@ config.nav.map((item) => {
   item.packages.forEach((element) => {
     let { name, show, type, taro } = element;
     if (show && taro) {
-      importStr += `import ${name} from './__VUE/${name.toLowerCase()}/index${
-        type === 'methods' ? '' : '.taro.vue'
-      }';\n`;
+      importStr += `import ${name} from './__VUE/${name.toLowerCase()}/index.taro.vue';\n`;
       packages.push(name);
     }
   });

+ 2 - 1
src/config.json

@@ -177,7 +177,7 @@
         {
           "version": "3.0.0",
           "name": "Notify",
-          "taro": true,
+          "taro": false,
           "type": "methods",
           "cName": "消息通知",
           "desc": "在页面顶部展示消息提示,支持函数调用和组件调用两种方式",
@@ -321,6 +321,7 @@
         },
         {
           "name": "Dialog",
+          "taro": true,
           "type": "methods",
           "cName": "对话框",
           "desc": "模态对话框,在浮层中显示,引导用户进行相关操作,支持图片对话框。",

+ 0 - 1
src/packages/__VUE/dialog/demo.vue

@@ -2,7 +2,6 @@
   <div class="demo">
     <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>

+ 139 - 0
src/packages/__VUE/dialog/doc.taro.md

@@ -0,0 +1,139 @@
+# Dialog 对话框
+
+
+### 介绍
+
+模态对话框,在浮层中显示,引导用户进行相关操作,常用于消息提示、消息确认,或在当前页面内完成特定的交互操作。
+
+### 安装
+    
+```javascript
+import { createApp } from 'vue';
+import { Dialog } from '@nutui/nutui@taro';
+
+const app = createApp();
+app.use(Dialog);
+```
+
+## 使用方式
+
+```html
+<nut-cell title="基础弹框" @click="baseClick"></nut-cell>
+<nut-dialog title="基础弹框" content="这是基础弹框。" v-model:visible="visible1" @cancel="onCancel" @ok="onOk" />
+
+<nut-cell title="无标题弹框" @click="noTitleClick"></nut-cell>
+<nut-dialog content="这是无标题弹框。" v-model:visible="visible2" @cancel="onCancel" @ok="onOk" />
+
+<nut-cell title="提示弹框" @click="tipsClick"></nut-cell>
+<nut-dialog no-cancel-btn title="温馨提示" content="这是提示弹框。" v-model:visible="visible3" @cancel="onCancel" @ok="onOk" />
+
+<nut-cell title="异步关闭" @click="componentClick"></nut-cell>
+<nut-dialog title="异步关闭" :content="closeContent" :visible="visible4" @cancel="onCancel" @ok="onOkAsync" />
+```
+
+``` javascript
+import { ref } from 'vue';
+export default {
+  setup() {
+    const visible1 = ref(false);
+    const visible2 = ref(false);
+    const visible3 = ref(false);
+    const visible4 = ref(false);
+    const closeContent = ref('');
+    const sleep = () => new Promise((resolve) => setTimeout(resolve, 1000));
+    const countDown = (second: number) => `倒计时 ${second} 秒`;
+
+    const onCancel = () => {
+      console.log('event cancel');
+    };
+    const onOk = () => {
+      console.log('event ok');
+    };
+    const onOkAsync = () => {
+      sleep()
+        .then(() => {
+          closeContent.value = countDown(2);
+          return sleep();
+        })
+        .then(() => {
+          closeContent.value = countDown(1);
+          return sleep();
+        })
+        .then(() => {
+          closeContent.value = countDown(0);
+        })
+        .then(() => {
+          visible4.value = false;
+        });
+    };
+
+    const baseClick = (): void => {
+      visible1.value = true;
+    };
+    const noTitleClick = () => {
+      visible2.value = true;
+    };
+    const tipsClick = () => {
+      visible3.value = true;
+    };
+
+    const componentClick = () => {
+      closeContent.value = `点击确定时3s后关闭`;
+      visible4.value = true;
+    };
+
+    return {
+      visible1,
+      visible2,
+      visible3,
+      visible4,
+      onCancel,
+      onOk,
+      closeContent,
+      onOkAsync,
+      baseClick,
+      noTitleClick,
+      componentClick,
+      tipsClick
+    };
+  }
+};
+```
+
+
+## Props
+
+| 字段                   | 说明                                  | 类型    | 默认值   |
+|------------------------|---------------------------------------|---------|----------|
+| title                  | 标题                                  | String  | -        |
+| content                | 内容,支持HTML                        | String  | -        |
+| teleport               | 指定挂载节点                          | String  | "body"   |
+| 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 | -      |
+| closed | 关闭回调,任何情况关闭弹窗都会触发 | Function | -      |
+
+
+## Slots
+
+| 名称    | 说明               |
+|---------|--------------------|
+| header  | 自定义标题区域     |
+| default | 自定义内容         |
+| footer  | 自定义底部按钮区域 |

+ 199 - 0
src/packages/__VUE/dialog/index.taro.vue

@@ -0,0 +1,199 @@
+<template>
+  <nut-popup
+    :teleport="teleport"
+    v-model:visible="showPopup"
+    :close-on-click-overlay="closeOnClickOverlay"
+    :lock-scroll="lockScroll"
+    round
+    @click-overlay="closed"
+    @click-close-icon="closed"
+  >
+    <view :class="classes">
+      <view v-if="title" class="nut-dialog__header">
+        <slot v-if="$slots.header" name="header"></slot>
+        <template v-else>{{ title }}</template>
+      </view>
+
+      <view class="nut-dialog__content" :style="{ textAlign }">
+        <slot v-if="$slots.default" name="default"></slot>
+        <view v-else v-html="content"></view>
+      </view>
+
+      <view class="nut-dialog__footer" v-if="!noFooter">
+        <slot v-if="$slots.footer" name="footer"></slot>
+        <template v-else>
+          <nut-button
+            size="small"
+            plain
+            type="primary"
+            class="nut-dialog__footer-cancel"
+            v-if="!noCancelBtn"
+            @click="onCancel"
+          >
+            {{ cancelText }}
+          </nut-button>
+          <nut-button
+            v-if="!noOkBtn"
+            size="small"
+            type="primary"
+            class="nut-dialog__footer-ok"
+            :class="{ disabled: okBtnDisabled }"
+            :disabled="okBtnDisabled"
+            @click="onOk"
+          >
+            {{ okText }}
+          </nut-button>
+        </template>
+      </view>
+    </view>
+  </nut-popup>
+</template>
+<script lang="ts">
+import { onMounted, computed, watch, ref } from 'vue';
+import { createComponent } from '../../utils/create';
+const { componentName, create } = createComponent('dialog');
+import Popup, { popupProps } from '../popup/index.taro.vue';
+import Button from '../button/index.taro.vue';
+export default create({
+  inheritAttrs: false,
+  children: [Popup, Button],
+  components: {
+    'nut-popup': Popup,
+    'nut-button': Button
+  },
+  props: {
+    ...popupProps,
+    closeOnClickOverlay: {
+      type: Boolean,
+      default: false
+    },
+    title: {
+      type: String,
+      default: ''
+    },
+    content: {
+      type: String,
+      default: ''
+    },
+    noFooter: {
+      type: Boolean,
+      default: false
+    },
+    noOkBtn: {
+      type: Boolean,
+      default: false
+    },
+    noCancelBtn: {
+      type: Boolean,
+      default: false
+    },
+    cancelText: {
+      type: String,
+      default: '取消'
+    },
+    okText: {
+      type: String,
+      default: '确定'
+    },
+    okBtnDisabled: {
+      type: Boolean,
+      default: false
+    },
+    cancelAutoClose: {
+      type: Boolean,
+      default: true
+    },
+    textAlign: {
+      type: String,
+      default: 'center'
+    },
+    onOk: {
+      type: Function,
+      default: null
+    },
+    onCancel: {
+      type: Function,
+      default: null
+    },
+    onClose: {
+      type: Function,
+      default: null
+    },
+    onClosed: {
+      type: Function,
+      default: null
+    },
+    closeOnPopstate: {
+      type: Boolean,
+      default: false
+    }
+  },
+  emits: [
+    'update',
+    'update:visible',
+    'ok',
+    'cancel',
+    'open',
+    'opened',
+    'close',
+    'closed'
+  ],
+  setup(props, { emit }) {
+    const showPopup = ref(props.visible);
+    onMounted(() => {
+      if (props.closeOnPopstate) {
+        window.addEventListener('popstate', function () {
+          closed();
+        });
+      }
+    });
+
+    watch(
+      () => props.visible,
+      (value) => {
+        showPopup.value = value;
+      }
+    );
+
+    const classes = computed(() => {
+      return {
+        [componentName]: true
+      };
+    });
+
+    const update = (val: boolean) => {
+      emit('update', val);
+      emit('update:visible', val);
+    };
+
+    const closed = () => {
+      update(false);
+      emit('closed');
+    };
+
+    const onCancel = () => {
+      emit('cancel');
+      if (props.cancelAutoClose) {
+        closed();
+      }
+    };
+
+    const onOk = () => {
+      closed();
+      emit('ok');
+    };
+
+    return {
+      closed,
+      classes,
+      onCancel,
+      onOk,
+      showPopup
+    };
+  }
+});
+</script>
+
+<style lang="scss">
+@import 'index.scss';
+</style>

+ 1 - 1
src/sites/mobile-taro/vue/src/app.config.ts

@@ -1,6 +1,6 @@
 export default {
   pages: [
-    'pages/notify/index',
+    'pages/dialog/index',
     'pages/range/index',
     'pages/picker/index',
     'pages/uploader/index',

+ 3 - 0
src/sites/mobile-taro/vue/src/pages/dialog/index.config.ts

@@ -0,0 +1,3 @@
+export default {
+  navigationBarTitleText: 'Dialog'
+};

+ 107 - 0
src/sites/mobile-taro/vue/src/pages/dialog/index.vue

@@ -0,0 +1,107 @@
+<template>
+  <div class="demo">
+    <nut-cell title="基础弹框" @click="baseClick"></nut-cell>
+    <nut-dialog
+      title="基础弹框"
+      content="这是基础弹框。"
+      v-model:visible="visible1"
+      @cancel="onCancel"
+      @ok="onOk"
+    />
+
+    <nut-cell title="无标题弹框" @click="noTitleClick"></nut-cell>
+    <nut-dialog
+      content="这是无标题弹框。"
+      v-model:visible="visible2"
+      @cancel="onCancel"
+      @ok="onOk"
+    />
+
+    <nut-cell title="提示弹框" @click="tipsClick"></nut-cell>
+    <nut-dialog
+      no-cancel-btn
+      title="温馨提示"
+      content="这是提示弹框。"
+      v-model:visible="visible3"
+      @cancel="onCancel"
+      @ok="onOk"
+    />
+
+    <nut-cell title="异步关闭" @click="componentClick"></nut-cell>
+    <nut-dialog
+      title="异步关闭"
+      :content="closeContent"
+      :visible="visible4"
+      @cancel="onCancel"
+      @ok="onOkAsync"
+    />
+  </div>
+</template>
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+  setup() {
+    const visible1 = ref(false);
+    const visible2 = ref(false);
+    const visible3 = ref(false);
+    const visible4 = ref(false);
+    const closeContent = ref('');
+    const sleep = () => new Promise((resolve) => setTimeout(resolve, 1000));
+    const countDown = (second: number) => `倒计时 ${second} 秒`;
+
+    const onCancel = () => {
+      console.log('event cancel');
+    };
+    const onOk = () => {
+      console.log('event ok');
+    };
+    const onOkAsync = () => {
+      sleep()
+        .then(() => {
+          closeContent.value = countDown(2);
+          return sleep();
+        })
+        .then(() => {
+          closeContent.value = countDown(1);
+          return sleep();
+        })
+        .then(() => {
+          closeContent.value = countDown(0);
+        })
+        .then(() => {
+          visible4.value = false;
+        });
+    };
+
+    const baseClick = (): void => {
+      visible1.value = true;
+    };
+    const noTitleClick = () => {
+      visible2.value = true;
+    };
+    const tipsClick = () => {
+      visible3.value = true;
+    };
+
+    const componentClick = () => {
+      closeContent.value = `点击确定时3s后关闭`;
+      visible4.value = true;
+    };
+
+    return {
+      visible1,
+      visible2,
+      visible3,
+      visible4,
+      onCancel,
+      onOk,
+      closeContent,
+      onOkAsync,
+      baseClick,
+      noTitleClick,
+      componentClick,
+      tipsClick
+    };
+  }
+};
+</script>