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

Posted zhuangwei_8256

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)
          // 取消的时候你如果想做点什么可以这里操作
        
      )
    ,
  ,

  • 效果如下(样式有点难看暂请忽略……)

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


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

以上是关于Vue 之 父组件给子组件传参实现自定义弹窗组件的主要内容,如果未能解决你的问题,请参考以下文章

Vue 之 父组件给子组件的传参的另类方式实现自定义弹窗组件

vue父子传参

Vue 组件之间传参!

vue-自定义组件传

vue-自定义组件传

vue-自定义组件传