在vue项目中可能会遇到这种开发情景,如下一个公用的formData.vue组件:

<!--公用组件 formData.vue-->
<el-form ref="form" :model="form" label-width="80px">
	  <el-form-item label="活动名称">
	    <el-input v-model="form.name"></el-input>
	  </el-form-item>
	  <el-form-item label="活动区域">
	    <el-select v-model="form.region" placeholder="请选择活动区域">
	      <el-option label="区域一" value="shanghai"></el-option>
	      <el-option label="区域二" value="beijing"></el-option>
	    </el-select>
	  </el-form-item>
	  <el-form-item>
	    <el-button type="primary" @click="onSubmit">确认</el-button>
	    <el-button>取消</el-button>
	  </el-form-item>
</el-form>
// 省略后面的代码,这个组件是一个共用的提交数据组件
onSubmit() {
	// ...
	this.$emit('closeDialog'); // 发现调用不了传递过来的事件
}

我们在grandfather组件中做如下引入组件,发现触发不了组件传递过来的事件,奇了怪了。

<template>
    <el-card shadow='never' class='aui-card--fill'>
    <!-- ....省略 grandfather.vue-->
            <el-dialog
                title="检验"
                :visible.sync="dialogVisible"
                width="50%"
                show-close>
                <form-data :formType="formType" showType="dialog" :sendData="sendData" :closeDialog="closeDialog"></form-data>
            </el-dialog>
    </el-card>
</template>
// ...省略其他代码

仔细思考会发现,这个grandfather.vue组件中嵌套了一个el-dialogelement-ui的弹窗组件,所以现在形成了一个祖孙组件,而不是认为的父子组件。用父子组件事件传递被阻断不生效了。那下面可以使用$attrs$listenersgrandfather.vue爷爷组件的属性和监听传递个孙子from.vue组件,在grandfather.vue组件中做如下修改:

<template>
    <el-card shadow='never' class='aui-card--fill'>
    <!-- ....省略 grandfather.vue-->
            <el-dialog
                title="检验"
                :visible.sync="dialogVisible"
                width="50%"
                show-close>
                <form-data v-bind="$attrs" v-on="$listeners" :formType="formType" showType="dialog" :sendData="sendData" :closeDialog="closeDialog"></form-data>
            </el-dialog>
    </el-card>
</template>
// ...在form.vue组件中如下调用
onSubmit() {
	// ...
	this.$attrs.closeDialog(); // 成功关掉了弹窗;
}

还有其他方式也能处理,通过vue依赖注入的方式provideinject,因为组件我的组件在复用的时候有些场景不是祖孙传递,所以用依赖注入需要在引入子组件调用的地方注入相同的事件,在后面放弃了,如果组件复用层级时相同的不妨可以一试。

Logo

前往低代码交流专区

更多推荐