需求
‘保存’按钮在祖辈组件中, 孙辈组件有表单数据,点击保存按钮需要先校验表单数据,校验通过才能过走后续的逻辑。
问题
校验方法是在孙辈组件中写的,祖辈组件在保存是需要调用孙辈组件的方法?
解决
祖孙组件的通信方法:
- listeners
- on
- provide 和 inject
- 中央事件总线$eventBus
最终选择的是中央事件总线$eventBus
首先需要创建事件总线并将其导出,以便其它模块可以使用或者监听它。创建一个 .js 文件,比如 eventBus.js
其次组件中使用on方法
发布事件$emit-传递值-祖辈组件
import EventBus from '@eventBus.js'
methods:{
//点击保存按钮
handleClickSave(){
EventBus(this).$emit('validateElementForm',()=>{
// callback
this.save()
})
},
//验证通过后续操作
save(){
//...
if(!this.save){
this.$message.confirm('确定提交吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
//接口请求
console.log('确定保存')
})
.catch(() => {
console.log('取消保存')
});
}
}
}
接 收(订阅)事件$on-接收值-孙辈组件
import EventBus from '@eventBus.js'
//需要初始化的时候接收事件
created(){
//接收事件
EventBus(this).$on('validateElementForm',(callback)=>{
//验证通过就callback
//验证不通过就不调callback
//验证不通过就不调callback
if(this.validateForm()){
callback && callback()
}
})
},
beforeDestory(){
EventBus(this).$off('validateElementForm')
},
methods:{
validateForm(){
let flag = true
this.$refs.formRef.validate((valid =>{
flag = valid
if(!valid){
this.$message.warning('表单有未填写数据')
}
})
return flag;
}
}
后续问题
自测的时候又发现个问题,孙辈组件,条件不满足的时候是不做展示的,有进行v-if的判断,此时eventBus.$emit (‘valid’)就不会触发。
怎么判断eventBus是否有valid事件呀?
解决:将孙辈组件v-if判断的showFlag条件通过$emit传给父辈组件
data(){
return{
showFlag:false
}
},
//=====修改保存方法=====
methods:{
//记录孙辈组件是否显示
recordShowFlag(flag){
this.showFlag = flag
},
//点击保存按钮需要进行判断
handleClickSave(){
const that = this
if(that.showFlag){
EventBus(that).$emit('validateElementForm',()=>{
that.save()
})
}else{
that.save()
}
}
}
<FatherDiablogCom
@recordShowFlag="recordShowFlag"
/>
data(){
return{
showFlag:false
}
},
created(){
api().then(res=>{
...
this.showFlag = true
this.$emit('recordShowFlag',this.showFlag)
})
},
beforeDestory(){
this.showFlag = false
this.$emit('recordShowFlag',this.showFlag)
}
//-------------
<ChildrenDiablogCom
v-if="showFlag"
/>
参考文献: