slot=“trigger“ 覆盖了组件内部的 ref=“trigger“【详细来龙去脉版 5min】
写后台管理项目的时候碰见这个问题的。
先看代码:
<div class="r-content"><el-dropdown><span class="el-dropdown-link"><img :src="getImageUrl" class="avatar"></span><template #dropdown><el-dropdown-menu><el-dropdown-item @click="handleUpdateAvatar">修改头像</el-dropdown-item><el-dropdown-item @click="handleLoginOut">退出登录</el-dropdown-item></el-dropdown-menu></template></el-dropdown><el-uploadclass="avatar-uploader"action="#":show-file-list="false":on-change="handleFileChange":before-upload="beforeAvatarUpload"style="display: none;"ref="uploadRef"><el-button slot="trigger" size="large" type="primary">选取文件</el-button></el-upload></div>
el-upload是根据style进行了隐藏操作,我误以为的实现修改头像的逻辑:
点击“修改头像”的按钮-->触发函数handleUpdateAvatar-->执行函数体uploadRef.value.$refs.trigger.click();-->我以为这算是点击了“选取文件”这个按钮-->然后触发el-upload的on-change事件,也就是handleFileChange函数。。。。。。
但是控制台报错了,我非常不解。
于是我问豆包ai,才发现这里按钮上写的的插槽slot是trigger,在el-upload的组件内部也有一个默认的按钮,它有个属性是ref,值是trigger,所以这个插槽在这里的作用就是替换el-upload内部的这个默认的按钮,那么原先的按钮是有ref属性的,但是替换后的这个新按钮是没有ref属性的,所以我的函数体想要执行uploadRef.value.$refs.trigger 发现根本没有ref值为trigger的实例对象啊,于是就报错。
我第一次深刻的认识到这问题,如此的复杂,给我整的怕怕的。。。。。算是我深刻认识到了slot的运行机制吧。
看一下豆包姐姐的原文:
这句话说的很好!组件内部的ref=trigger是硬编码的,不会因为你使用插槽而自动的把ref=trigger绑定在新添加进来的按钮上,换句话说就是非常的忠诚!跟着人家走了!一起消失!
反正这个refs和插槽我跟你没完。