详情查看:Vue 之 组件之间的传值通信(多种方法,简洁而不失重点)
props
传参这里重点说明一下
特殊方式
,场景的不同决定传参的方式合适与否
比如自定义弹窗组件,需要的动态参数可能有:确定按钮的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)
// 取消的时候你如果想做点什么可以这里操作
}
})
},
},
}
代码中使用了两种不同的方式解决弹窗按钮回调的问题,具体使用情况视情况而定。
如有不足,望大家多多指点! 谢谢!