【vue】弹窗组件的几种调用方式

写在前面

本文仅代表个人对vue组件的一些粗浅认识,仅供参考,如有错漏,欢迎指出。

vue 弹窗组件的几种调用方式

1. 同一组件调用

<template>
  <el-button plain @click="dialogVisible = true" >
    Click to open the Dialog
  </el-button>

  <el-dialog
    v-model="dialogVisible"
    title="Tips"
    width="500"
    :center="false"
    :before-close="handleClose"
  >
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogVisible = false">Cancel</el-button>
        <el-button type="primary" @click="dialogVisible = false">
          Confirm
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessageBox } from 'element-plus'

const dialogVisible = ref(false)

const handleClose = (done: () => void) => {
  ElMessageBox.confirm('Are you sure to close this dialog?')
    .then(() => {
      done()
    })
    .catch(() => {
      // catch error
    })
}
</script>

缺点:弹窗代码在父组件中,导致代码较多

2.父子组件调用

父组件

<template>
<el-button @click="clickBtn">点击出现弹窗</el-button>
<Dialog v-model:visible="visible" @close="close" @submit="submit"></Dialog>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import Dialog from './components/Dialog.vue';

const visible = ref(false)

const clickBtn = () => {
    visible.value = true
}
const close = () => {
    visible.value = false
}
const submit =() => {
    visible.value =false
}
</script>


子组件

<template>
    <el-dialog v-model="props.visible" title="dialog" width="452px">
        <el-button @click="close">取消</el-button>
        <el-button @click="$emit('update:visible', false)">确定</el-button>
    </el-dialog>
</template>

<script lang="ts" setup>
const props = defineProps( { visible: Boolean})
const emit = defineEmits(['update:visible'])
const close =() => {
    emit('update:visible')
}
</script>

缺点:需要一个变量控制子组件展示隐藏,耦合重

3.父组件调用子组件方法

子组件暴露弹窗打开关闭方法

<template>
    <el-dialog v-model="visible" title="dialog" width="452px">
        <el-button @click="close">取消</el-button>
        <el-button @click="submit">确定</el-button>
    </el-dialog>
</template>

<script lang="ts" setup>
import {ref} from 'vue'
const emit = defineEmits(['submit'])

const visible = ref(false)

const open = () => {
    visible.value = true
}

const close =() => {
    visible.value = false
}

const submit = () => {
    visible.value = false
    emit('submit', [123])
}

defineExpose({open, close})
</script>

父组件通过ref调用

<template>
<el-button @click="clickBtn">点击出现弹窗</el-button>
<Dialog2 ref="dialogRef" @submit="submit"></Dialog2>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import Dialog2 from './components/Dialog2.vue';

const dialogRef = ref()

const clickBtn = () => {
    dialogRef.value.open()
}

const submit =(list) => {
    console.log('list :>> ', list);
    dialogRef.value.close()
}
</script>

缺点:需要知道子组件暴露的方法,不利于解耦

4.函数式调用

子组件

<template>
    <el-dialog v-model="visible" title="dialog" width="452px">
        <el-button @click="close">取消</el-button>
        <el-button @click="submit">确定</el-button>
    </el-dialog>
</template>

<script lang="ts" setup>
import {onMounted, ref}  from 'vue'

interface Props {
    close?: () => void,
    submit?: (list:any) => void
}
const props = defineProps<Props>( )

const visible = ref(false)

onMounted( () => {
    visible.value = true
})

const close =() => {
    visible.value = false
    props?.close?.()
}
const submit = () => {
    visible.value = false
    props?.submit?.([123])
}
</script>

index.ts: 动态调用

import Dialog3 from './Dialog3.vue'
import  { createApp } from 'vue';

const useDialog = (options: any) => {
    const mountNode = document.createElement('div')
    document.body.appendChild(mountNode)
    
    return new Promise((resolve, reject) => {
        let app: any = createApp(Dialog3, {
            ...options,
            close: () => {
                app.unmount()
                mountNode.remove()
                app = undefined
                reject()
            },
            submit: (list: any) => {
                app.unmount()
                mountNode.remove()
                app = undefined
                resolve(list)
            }
        })
    
        if (app) {
            app.mount(mountNode)        
        }
    })
    

}
export default useDialog


父组件中使用

<template>
  <el-button @click="clickBtn">点击出现弹窗</el-button>
  </template>
  
  <script setup lang="ts">
  import useDialog from './index.ts'
  
  
  const clickBtn = () => {
      useDialog({}).then(list => {
          console.log('object :>> ', list);
      })
  }
  
  </script>
  
  

优点: 需要使用组件式才调用,只需要传递props,不需要了解子组件内部逻辑
很多组件都是使用这种思想,如element-plus的MessageBox

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue组件调用弹窗组件可以通过以下步骤实现: 1. 首先,创建一个弹窗组件,可以在组件的`template`中定义弹窗的内容和样式。 ```vue <template> <div class="modal"> <div class="modal-content"> <!-- 弹窗内容 --> <slot></slot> </div> </div> </template> <script> export default { name: 'Modal', // ...组件的其他配置 } </script> <style> .modal { /* 弹窗样式 */ } .modal-content { /* 弹窗内容样式 */ } </style> ``` 2. 在需要使用弹窗组件中,引入并注册弹窗组件。 ```vue <template> <div> <!-- 点击按钮触发弹窗 --> <button @click="openModal">打开弹窗</button> <!-- 使用弹窗组件 --> <Modal v-if="showModal"> <!-- 弹窗内容 --> <h2>这是一个弹窗</h2> <p>欢迎使用弹窗组件!</p> <button @click="closeModal">关闭</button> </Modal> </div> </template> <script> import Modal from './Modal.vue'; export default { name: 'ParentComponent', components: { Modal, }, data() { return { showModal: false, }; }, methods: { openModal() { this.showModal = true; }, closeModal() { this.showModal = false; }, }, } </script> ``` 在上述代码中,点击按钮 `打开弹窗` 会触发 `openModal` 方法,将 `showModal` 属性设置为 `true`,从而显示弹窗组件弹窗组件组件中使用时,可以通过插槽(slot)传递弹窗的内容和样式。 这样,当点击按钮时,弹窗组件会显示,并且可以通过弹窗中的按钮或其他交互元素来关闭弹窗

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值