美文网首页
Dialog组件

Dialog组件

作者: sweetBoy_9126 | 来源:发表于2020-09-17 17:43 被阅读0次
    • Dialog.vue
    <template>
      <Teleport to="body">
        <template v-if="visible">
          <div class="ivue3-dialog-overlay"
               @click="onClickOverlay"
          ></div>
          <div class="ivue3-dialog-wrapper">
            <div class="ivue3-dialog">
              <header>
                <slot name="title"/>
                <span @click="onClose" class="ivue3-dialog-close"></span>
              </header>
              <main>
                <slot name="content"/>
              </main>
              <footer>
                <Button level="main" @click="ok">OK</Button>
                <Button @click="cancel">Cancel</Button>
              </footer>
            </div>
          </div>
        </template>
      </Teleport>
    </template>
    <script lang="ts">
      import Button from './Button.vue'
      import {ref, SetupContext} from "vue";
    
      export default {
        components: {Button},
        props: {
          visible: {
            type: Boolean,
            default: false
          },
          closeOnClickOverlay: {
            type: Boolean,
            default: true
          },
          ok: {
            type: Function
          }
        },
        setup(props: any, context: SetupContext) {
          const test = ref
          const onClose = () => {
            context.emit('update:visible', !props.visible)
          }
          const onClickOverlay = () => {
            if (props.closeOnClickOverlay) {
              onClose()
            }
          }
          const ok = () => {
            if (props.ok?.() !== false) {
              onClose()
            }
          }
          const cancel = () => {
            context.emit('cancel')
            onClose()
          }
          return {onClose, onClickOverlay, ok, cancel}
        }
      }
    </script>
    
    • DialogDemo.vue
    <template>
      <div>
        <div>Dialog示例</div>
        <h1>示例1</h1>
        <Button @click="onClickToggle">Dialog</Button>
        <Dialog v-model:visible="x" :ok="f1" @cancel="f2" title="我美吗">
          <template v-slot:title>
            <h1>哈哈哈</h1>
          </template>
          <template v-slot:content>
            <p>你好呀</p>
            <p>小姐姐</p>
          </template>
        </Dialog>
      </div>
    </template>
    <script lang="ts">
      import Dialog from '../lib/Dialog.vue'
      import Button from '../lib/Button.vue'
      import {ref} from "vue";
    
      export default {
        name: 'Switch',
        components: {Dialog, Button},
        setup() {
          const x = ref(false)
          const onClickToggle = () => {
            x.value = !x.value
          }
          const f1 = (): Boolean => {
            return false
          }
          const f2 = (): Boolean => {
            return true
          }
          return {x, onClickToggle, f1, f2}
        }
      }
    </script>
    

    我们希望直接使用下面的一行代码就可以打开我们的Dialog

    <Button @click="showDialog">show</Button>
    const showDialog = () => {
      openDialog({title: '标题', content: '你好'})
    }
    

    单独 创建一个openDialog.ts文件导出openDialog方法

    • openDialog.ts
    import Dialog from './Dialog.vue'
    import {createApp} from 'vue'
    interface Options {
      title: string;
      content: string;
    }
    export const openDialog = (options: Options) => {
      const {title, content} = options
    // 因为我们需要将我们的Dialog挂载到页面上所以我们需要创建一个div
      const div = document.createElement('div')
      document.body.append(div)
      const app = createApp(Dialog)
      // 将Dialog组件挂载到div下面
      app.mount(div)
    }
    

    问题1:上面的代码我们点击按钮的时候发现Dialog并没有出来,但是我们看控制台里的html里我们新添加的div标签已经添加到了body下面
    原因:因为我们的Dialog组件需要传入一个visible属性,你不传它默认就是false,所以不会显示
    解决方法:通过引入h函数第一个参数是组件,第二个是元素的属性(第一个参数组件的props,也就是直接可以在使用组件的时候传入的属性),第三个是插槽的属性

    • openDialog.ts
    import {createApp, h} from 'vue'
    
    const app = createApp({
        render() {
          return h(Dialog, {visible: true, cancel: () => {}}, {title, content})
        }
      })
    

    问题2:我们通过上面的代码打开的Dialog点击关闭关闭不了
    原因:我们在把visible作为属性传入的时候我们把它给写死了等于true了
    解决方法:关闭的时候直接把我们创建的Dialog销毁就好了,就不需要改visible了,也就是我们监听我们的update:visible事件当它变为false的时候就把我们的Dialog销毁掉,这里要注意我们在render里监听我们的update事件需要写成onUpdate:对应的属性名,比如onUpdate:visible

    const app = createApp({
        render() {
          return h(Dialog, {
            visible: true, cancel: () => {},
            'onUpdate:visible': (newValue: boolean) => {
              if (newValue === false) {
                app.unmount(div)
              }
            }
            }, {title, content})
        }
      })
      app.mount(div)
    

    相关文章

      网友评论

          本文标题:Dialog组件

          本文链接:https://www.haomeiwen.com/subject/apqryktx.html