Vue 之 父组件给子组件传参实现自定义弹窗组件

父组件向子组件传参

详情查看:Vue 之 组件之间的传值通信(多种方法,简洁而不失重点)

  • 传统方式:通过属性 props 传参
  • 特殊方式:通过 ref 调用子组件方法,然后通过方法传参

这里重点说明一下特殊方式,场景的不同决定传参的方式合适与否

比如自定义弹窗组件,需要的动态参数可能有:确定按钮的text、取消按钮的text、弹窗的文本内容、弹窗的title;

  • 传统方式传参在某种特殊业务下可能不是那么完美:如果在一个页面中可能有操作的不同,不同的操作可能弹窗的数据不一样,这个时候如果使用 props 传参的话,一个弹窗组件4个属性,2个组件就8个……,这么下去的话,在当前vue 页面 data绑定的数据变量就可能有很多了;
  • 而如果是通过ref 调用子组件的方法传参的话就方便很多了,直接在需要调用弹窗的方法里面自定义一个对象,把需要动态改变的参数塞到这个对象里面,在子组件中对传过来的参数进行接收,这样既满足了组件的复用性,又满足了组件的灵活性,并且调用组件的父组件也不用定义那么多数据变量了。


自定义弹窗组件

  • 自定义弹窗代码如下:
<template>
  <!-- 自定义确认弹窗组件 -->
  <div class="dialog-container" v-if="isShow" @click.stop>
    <div class="dialog-box">
      <div class="dialog-title">{
   
   { dialogData.title }}</div>
      <div class="dialog-message">{
   
   { dialogData.message }}</div>
      <div class="dialog-btns">
        <el-button class="btn" @click="cancel">{
   
   { dialogData.cancelText }}</el-button>
        <el-button type="primary" class="confirm-btn btn" @click="confirm">{
   
   { dialogData.confirmText }}</el-button>
      </div>
    </div>
  </div>
</template>
export default {
    
    
  data() {
    
    
    return {
    
    
      isShow: false, // 是否显示弹窗
      // 弹窗的默认内容
      dialogData: {
    
    
        title: '提示', // 弹窗标题
        message: '请确认,是否提交!?', // 弹窗内容message
        cancelText: '取消', // 弹窗的取消按钮文字
        confirmText: '确认', // 弹窗的确认按钮文字
      },
      defaultDialogData: {
    
    }, // 弹窗的默认内容
      // 弹窗确定的回调,当然这个也可以不用,直接用按钮的回调传参即可btnCallback
      confirmCallback: null,
      // 弹窗取消的回调,当然这个也可以不用,直接用按钮的回调传参即可btnCallback
      cancelCallback: null,
      // 弹窗按钮的回调
      btnCallback: null,
    }
  },
  methods: {
    
    
    open(dialogData) {
    
    
      // 保存初始的弹窗数据
      this.defaultDialogData = JSON.parse(JSON.stringify(this.dialogData))
      // 将传过来的弹窗数据赋值给当前数据
      this.dialogData = Object.assign(this.dialogData, dialogData)
      this.isShow = true
      // 这里定义返回一个 promise
      return new Promise((resolve, reject) => {
    
    
        // 方式一
        // this.confirmCallback = resolve
        // this.cancelCallback = reject
        // 方式二
        this.btnCallback = resolve
      })
    },
    close() {
    
    
      // 重置弹窗相关数据
      this.dialogData = JSON.parse(JSON.stringify(this.defaultDialogData))
      this.isShow = false
    },
    confirm() {
    
    
      // 方式一
      // if (this.confirmCallback) {
    
    
      //   this.confirmCallback('confirm')
      // }
      // 方式二
      if (this.btnCallback) {
    
    
        this.btnCallback('confirm')
      }
      this.close()
    },
    cancel() {
    
    
      // 方式一
      // if (this.cancelCallback) {
    
    
      //   this.cancelCallback('cancel')
      // }
      // 方式二
      if (this.btnCallback) {
    
    
        this.btnCallback('cancel')
      }
      this.close()
    },
  },
}
  • 调用自定义弹窗的父组件,就不写那么多东西了,简单两个按钮模拟一下
    在这里插入图片描述
<template>
  <div>
    <el-button type="primary" @click="handleSubmit">提交</el-button>
    <el-button type="warning" @click="handleDelete">删除</el-button>

    <ConfirmDialogVue ref="ConfirmDialog" />
  </div>
</template>
import ConfirmDialogVue from '@/components/ConfirmDialog/ConfirmDialog.vue'
export default {
    
    
  data() {
    
    
    return {
    
    }
  },
  components: {
    
    
    ConfirmDialogVue,
  },
  methods: {
    
    
    async handleSubmit() {
    
    
      // 方式一
      // try {
    
    
      //   const res = await this.$refs.ConfirmDialog.open()
      //   if (res) {
    
    
      //     console.log('提交-确定-', res)
      //     // 调接口啥的
      //     // doing
      //   }
      // } catch (rej) {
    
    
      //   console.log('提交-取消-', rej)
      //   // 取消的时候你如果想做点什么可以这里操作
      // }

      // 方式二,就不用 try catch了
      const res = await this.$refs.ConfirmDialog.open()
      if (res) {
    
    
        if (res == 'confirm') {
    
    
          console.log('提交-确定-', res)
          // 调接口啥的
          // doing
        } else if (res == 'cancel') {
    
    
          console.log('提交-取消-', res)
          // 取消的时候你如果想做点什么可以这里操作
        }
      }
    },
    handleDelete() {
    
    
      const dialogData = {
    
    
        message: '请确认,是否删除!?',
        confirmText: '删除',
      }
      // 方式一
      // this.$refs.ConfirmDialog.open(dialogData)
      //   .then(res => {
    
    
      //     console.log('删除-确定-', res)
      //     // 调接口啥的
      //     // doing
      //   })
      //   .catch(rej => {
    
    
      //     console.log('删除-取消-', rej)
      //     // 取消的时候你如果想做点什么可以这里操作
      //   })

      // 方式二
      this.$refs.ConfirmDialog.open(dialogData).then(res => {
    
    
        if (res == 'confirm') {
    
    
          console.log('删除-确定-', res)
          // 调接口啥的
          // doing
        } else if (res == 'cancel') {
    
    
          console.log('删除-取消-', res)
          // 取消的时候你如果想做点什么可以这里操作
        }
      })
    },
  },
}
  • 效果如下(样式有点难看暂请忽略……)
    在这里插入图片描述

代码中使用了两种不同的方式解决弹窗按钮回调的问题,具体使用情况视情况而定。


如有不足,望大家多多指点! 谢谢!

猜你喜欢

转载自blog.csdn.net/Zhuangvi/article/details/126808964