当前位置:编程学习 > > 正文

vue可以使用模态框modal吗(vue基于Teleport实现Modal组件)

时间:2022-01-20 00:05:10类别:编程学习

vue可以使用模态框modal吗

vue基于Teleport实现Modal组件

1.认识Teleport

像我们如果写Modal组件、Message组件、Loading组件这种全局式组件,没有Teleport的话,将它们引入一个.vue文件中,则他们的HTML结构会被添加到组件模板中,这是不够完美的。

vue可以使用模态框modal吗(vue基于Teleport实现Modal组件)

vue可以使用模态框modal吗(vue基于Teleport实现Modal组件)

下面就实战介绍一下如何用Teleport开发Modal组件

2.Teleport的基本用法

Teleport的写法十分简单,只需要用<Teleport></Teleport>将内容包裹,并用to指定将HTML挂到哪个父节点下,就可以啦。

  • <teleport to="#modal">
    内容
    </teleport>
    
    
  • 3.第一步优化

    如果我们在代码中将Teleport要挂载的DOM写死,那么每创建一个全局式组件,就需要有一个DOM节点,会越来越多,并且一直存在,这样的写法不是很优雅。比较好的解决方案就是:

  • setup(){
      const node = document.createElement('li')
      node.id = 'modal'
      document.body.appendChild(node)
      onUnmounted(() => {
        document.body.removeChild(node)
      })
    }
    
    
  • 4.第二步优化

    如果我们后续还要添加Message组件,Loading组件等功能,同样要用到Teleport,在每一个组件内部都写这么一段代码,实在有点冗余,vue3使我们能够很方便的将逻辑功能提取出来,从而达到逻辑复用的目的。

    我们在src-hooks文件夹下创建useDOMCreate.ts文件,来封装这一块逻辑

  • // hooks/useDOMCreate.ts
    import { onUnmounted } from 'vue'
    
    function useDOMCreate(nodeId:string):void {
      const node = document.createElement('li')
      node.id = nodeId
      document.body.appendChild(node)
      onUnmounted(() => {
        document.body.removeChild(node)
      })
    }
    export default useDOMCreate
    
    
    
  • 使用:

  • import useDOMCreate from '../hooks/useDOMCreate'
    setup(props, ctx) {
        useDOMCreate('modal')
    }
    
    
  • 5.实现Modal组件

    具体封装Modal组件的细节这里就不讲啦,也没有什么复杂的逻辑。直接上代码。

  • //Modal.vue
    <template>
      <teleport to="#modal">
        <li class="modal d-block" tabindex="-1" v-if="isVisible">
          <li class="modal-dialog">
            <li class="modal-content">
              <li class="modal-header">
                <h5 class="modal-title">{{title}}</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                  <span aria-hidden="true" @click="onClose">&times;</span>
                </button>
              </li>
              <li class="modal-body">
                <slot></slot>
              </li>
              <li class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal"  @click="onClose">取消</button>
                <button type="button" class="btn btn-primary"  @click="onConfirm">确定</button>
              </li>
            </li>
          </li>
        </li>
      </teleport>
    </template>
    <script lang="ts">
    import { defineComponent } from 'vue'
    import useDOMCreate from '../hooks/useDOMCreate'
    export default defineComponent({
      name: 'Modal',
      emits: ['model-close', 'model-confirm'],
      props: {
        title: {
          type: String,
          default: ''
        },
        isVisible: {
          type: Boolean,
          default: false
        }
      },
      setup(props, ctx) {
        useDOMCreate('modal')
        const onClose = () => {
          ctx.emit('model-close')
        }
        const onConfirm = () => {
          ctx.emit('model-confirm')
        }
        return {
          onClose,
          onConfirm
        }
      }
    })
    </script>
    
    
  • 使用示例

  • <template>
      <li class="post-detail-page">
        <button type="button" class="btn btn-danger" @click="handleDelete">删除</button>
        <modal title='是否确认删除?' :isVisible="modalVisible" @model-close="hanldeModalClose" @model-confirm="handleModalConfim">
          <p>确认要删除这篇文章吗?</p>
        </modal>
      </li>
    </template>
    <script lang="ts">
    import { defineComponent, ref } from 'vue'
    import Modal from '../components/Modal.vue'
    
    export default defineComponent({
      name: 'post-detail',
      components: { Modal },
      setup() {
        const modalVisible = ref(false)
        const handleDelete = () => {
          modalVisible.value = true
        }
        const hanldeModalClose = () => {
          modalVisible.value = false
        }
        const handleModalConfim = () => {
          modalVisible.value = false
          ...
         / /后续逻辑处理
        }
        return {
          hanldeModalClose,
          handleModalConfim,
          handleDelete,
          modalVisible
        }
      }
    })
    </script>
    
    
  • 以上就是vue基于Teleport实现Modal组件的详细内容,更多关于vue Teleport实现Modal组件的资料请关注开心学习网其它相关文章!

    上一篇下一篇

    猜您喜欢

    热门推荐