日常开发记录-radioGroup组件

embedded/2025/3/14 11:13:37/

日常开发记录-radioGroup组件

  • 1.前提
  • 2.问题:无限循环调用
  • 3.解释
  • Vue 事件传播机制分析与无限循环原因解释
  • 4.解决

1.前提

在上一章的,我们实现了radio组件。从这进入了解
新增个radioGroup组件呢。

javascript"><template><divclass="q-radio-group"role="radiogroup"><slot></slot></div>
</template><script>export default {name: 'MyRadioGroup',componentName: 'MyRadioGroup',props: {value: {},disabled: Boolean,name: String},created() {this.$on('change', value => {this.$emit('change', value);});},watch: {value(value) {// 当值变化时,通知子组件this.$nextTick(() => {// this.$children.forEach(child => {//   if (child.$options.name === 'MyRadio') {//     child.$refs.radio.checked = child.label === value;//   }// });});}}};
</script><style>
.q-radio-group {display: inline-block;
}
</style>

原来的radio组件改写成

javascript"><template><labelclass="q-radio":class="{'is-disabled': isDisabled,'is-checked': model === label}"><span class="q-radio__input":class="{'is-disabled': isDisabled,'is-checked': model === label}"><span class="q-radio__inner"></span><inputref="radio"type="radio"class="q-radio__original":value="label":name="name":disabled="isDisabled"v-model="model"@change="handleChange"/></span><span class="q-radio__label"><slot></slot><template v-if="!$slots.default">{{label}}</template></span></label>
</template><script>export default {name: 'MyRadio',props: {value: {},name: String,label: {},disabled: Boolean,},data() {return {// 预先定义 _radioGroup,提高代码可读性_radioGroup: null};},computed: {isGroup() {let parent = this.$parent;while (parent) {if (parent.$options.name !== 'MyRadioGroup') {parent = parent.$parent;} else {this._radioGroup = parent;return true;}}return false;},model: {get() {return this.isGroup ? this._radioGroup.value : this.value;},set(val) {if (this.isGroup) {// 使用 $emit 向上传递事件this._radioGroup.$emit('input', val);} else {this.$emit('input', val);}}},isDisabled() {// 考虑组的禁用状态return this.isGroup ? this._radioGroup.disabled || this.disabled : this.disabled;}},methods: {handleChange() {// 使用 $nextTick 确保状态已更新this.$nextTick(() => {// 触发 change 事件this.$emit('change', this.model);// 如果在组中,也通知组if (this.isGroup) {this._radioGroup.$emit('change', this.model);}});}}}
</script>

引用:

javascript"><template><div id="app"><el-container><el-header><h1>Vue 2 + Element UI Template</h1></el-header><el-main><el-row><el-col :span="12" :offset="6"><el-card><div slot="header"><span>欢迎使用</span></div><el-button type="primary">点击我</el-button></el-card></el-col></el-row></el-main><input type="radio" id="contactChoice1" name="contact" value="email" /><label for="contactChoice1">电子邮件</label><input type="radio" id="contactChoice2" name="contact" value="phone" /><label for="contactChoice2">电话</label><input type="radio" id="contactChoice3" name="contact2" value="mail" /><label for="contactChoice3">邮件</label><MyRadio v-model="currentValue.aaa" name="aaa" @input="handleInput" @change="handleChange" label="男"></MyRadio><MyRadio v-model="currentValue.aaa" name="aaa" @input="handleInput" @change="handleChange" label="女"></MyRadio><MyRadio v-model="currentValue2" name="bbb" @input="handleInput" @change="handleChange" label="未知">未知</MyRadio><MyRadioGroup v-model="currentValue.bbb" name="bbb" @change="handleGroupChange"><MyRadio label="男"></MyRadio><MyRadio label="女"></MyRadio></MyRadioGroup><el-button @click="changeGroupVal">改变group的绑定值</el-button><el-radio v-model="radio" label="1" @input="change">备选项</el-radio><el-radio v-model="radio" label="2">备选项</el-radio></el-container></div>
</template><script>
import MyRadio from './components/myRadio.vue'
import MyRadioGroup from './components/myRadioGroup.vue'
export default {name: 'App', data () {return {currentValue: {aaa: '男',bbb: ''},currentValue2: '',radio: '1'}},components: {MyRadio,MyRadioGroup},methods: {handleInput (event) {console.log('input event', event)},changeGroupVal () {this.currentValue.bbb = '女'},handleChange (val) {console.log('change event', val)},change (val) {console.log(val)},handleGroupChange (val) {console.log('group', val)}}
}
</script>

主要在于radio的isGroup和原绑定值的改变,radiogroup就是个插槽。

2.问题:无限循环调用

在这里插入图片描述
会出现无限调用radiogroup组件emit出来的change事件。为什么呢?感觉没问题的应该。
原有的逻辑,事件传递链分析:
当您点击 RadioGroup 中的一个选项时,事件流程如下:
MyRadio 的 model setter 被触发,它调用 this._radioGroup. e m i t ( ′ i n p u t ′ , v a l ) 同时, M y R a d i o 的 h a n d l e C h a n g e 方法被触发,它调用 t h i s . emit('input', val) 同时,MyRadio 的 handleChange 方法被触发,它调用 this. emit(input,val)同时,MyRadiohandleChange方法被触发,它调用this.emit(‘change’, this.model) 和 this._radioGroup. e m i t ( ′ c h a n g e ′ , t h i s . m o d e l ) M y R a d i o G r o u p 监听 到 ′ c h a n g e ′ 事件,它又调用 t h i s . emit('change', this.model) MyRadioGroup 监听到 'change' 事件,它又调用 this. emit(change,this.model)MyRadioGroup监听change事件,它又调用this.emit(‘change’, value)。
感觉这样就完了呀。怎么会一直重复的调用change事件呢。
??????

3.解释

Vue 事件传播机制分析与无限循环原因解释

分析为什么修改事件名可以解决无限循环问题,并解释 Vue 中 $emit 和 $on 的工作原理。
问题根源: 组件自我监听
查看自己的 MyRadioGroup 组件代码:
这里发现了关键问题 - 组件正在监听自己发出的事件,并且在监听器中又发出同名事件,创建了一个经典的无限循环:
步骤1.MyRadio 组件触发 change 事件,并将值发送给 MyRadioGroup
步骤2.MyRadioGroup 接收 change 事件,通过 o n 监听器处理它步骤 3. 处理器调用 t h i s . on 监听器处理它 步骤3.处理器调用 this. on监听器处理它步骤3.处理器调用this.emit(‘change’, value),再次向自己发送 change 事件
步骤4.这又激活了同一个监听器,返回步骤 3,形成无限循环
Vue 事件机制解析
基本工作流程:
$on 将事件处理器存储在组件实例的 _events 对象中
$emit 查找并调用存储在 _events[eventName] 中的处理器
关键点: 当组件对自己发出的事件设置监听器时,每次调用 $emit 都会触发这些监听器,包括那些由同一组件设置的监听器。

4.解决

所以我们只要抛出的方法名变一下就行

javascript">this._radioGroup.$emit('handleChange', this.model);//接受created() {this.$on('handleChange', value => {this.$emit('change', value);});}
文章来源:https://blog.csdn.net/qq_45030898/article/details/146159698
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ppmy.cn/embedded/172474.html

相关文章

并行算法_第十章_《C++并发编程实战》笔记

并行算法 1. 核心知识点2. 使用并行算法3. 数据竞争与线程安全4. 性能优化5. 常见问题与陷阱6. 最佳实践7. 多选题7.1 题目7.2 多选答案 9. 设计题目10. 设计题目答案 1. 核心知识点 执行策略&#xff08;Execution Policies&#xff09; C17引入的执行策略允许开发者指定算法…

亚马逊COSMO算法解读:新搜索时代的流量分配与DeepBI AI驱动的智能优化策略

亚马逊COSMO算法的推出&#xff0c;标志着其搜索和推荐系统进入了智能化、个性化的新阶段。该算法通过分析用户购物习惯、搜索历史、浏览行为等数据&#xff0c;为买家提供精准推荐&#xff0c;同时对卖家的运营策略提出了更高的要求。在这一背景下&#xff0c;AI驱动的DeepBI能…

探索 PyTorch 中的 ConvTranspose2d 及其转置卷积家族

探索 PyTorch 中的 ConvTranspose2d 及其转置卷积家族 在深度学习领域&#xff0c;尤其是图像处理任务中&#xff0c;卷积神经网络&#xff08;CNN&#xff09;扮演着重要角色。而当我们需要在网络中进行上采样&#xff08;Upsampling&#xff09;时&#xff0c;转置卷积&…

【CSS3】元婴篇

目录 定位相对定位绝对定位定位居中固定定位堆叠层级 z-index CSS 精灵字体图标下载字体使用字体 垂直对齐方式过渡修饰属性透明度光标类型 定位 作用&#xff1a;灵活的改变盒子在网页中的位置 实现&#xff1a; 定位模式&#xff1a;position边偏移&#xff1a;设置盒子的…

全链条自研可控|江波龙汽车存储“双轮驱动”体系亮相MemoryS 2025

3月12日&#xff0c;MemoryS 2025在深圳盛大开幕&#xff0c;汇聚了存储行业的顶尖专家、企业领袖以及技术先锋&#xff0c;共同探讨存储技术的未来发展方向及其在商业领域的创新应用。江波龙董事长、总经理蔡华波先生受邀出席&#xff0c;并发表了题为《存储商业综合创新》的主…

地理信息系统(ArcGIS)在水文水资源及水环境中的应用:空间数据管理‌、空间分析功能‌、‌可视化表达‌

随着全球工业化和经济的快速发展&#xff0c;水资源短缺、水污染等问题日益严峻&#xff0c;成为制约可持续发展的重大瓶颈。地理信息系统&#xff08;GIS&#xff09;以其强大的空间数据管理和分析能力&#xff0c;在水文水资源及水环境的研究和管理中展现出独特优势。本文将深…

仓库管理系统(WMS)系统的基本流程

WMS&#xff08;仓库管理系统&#xff0c;Warehouse Management System&#xff09;是用于管理和优化仓库操作的系统&#xff0c;旨在提高库存准确性、提高仓库效率和降低成本。WMS的基本流程包括以下几个主要步骤&#xff1a; 收货&#xff08;Receiving&#xff09;&#xff…

OpenCV连续数字识别—可运行验证

前言 ​ 文章开始&#xff0c;瞎说一点其他的东西&#xff0c;真的是很离谱&#xff0c;找了至少两三个小时&#xff0c;就一个简单的需求&#xff1a; 1、利用OpenCV 在Windows进行抓图 2、利用OpenCV 进行连续数字的检测。 3、使用C&#xff0c;Qt 3、将检测的结果显示出来 …