日常开发记录-radioGroup组件

日常开发记录-radioGroup组件

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

1.前提

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

<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组件改写成

<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>

引用:

<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.解决

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

this._radioGroup.$emit('handleChange', this.model);//接受created() {this.$on('handleChange', value => {this.$emit('change', value);});}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/35406.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

API调用comfyui工作流,做一个自己的app,chatgpt给我写的前端,一键创建自己的卡通形象,附源码

前言 工具介绍 首先 comfyui你是少不了的&#xff0c;这个是工作流的后端支持&#xff0c;用这个去调试工作流和生成API可调用文件 前端我们就用很流行的gradio吧&#xff0c;什么你一时半会没有学gradio的计划&#xff0c;没事&#xff0c;笔者也没系统学过&#xff0c;我干…

【网络】数据流(Data Workflow)Routes(路由)、Controllers(控制器)、Models(模型) 和 Middleware(中间件)

在图片中&#xff0c;数据流&#xff08;Data Workflow&#xff09;描述了应用程序中数据的流动过程&#xff0c;涉及 Routes&#xff08;路由&#xff09;、Controllers&#xff08;控制器&#xff09;、Models&#xff08;模型&#xff09; 和 Middleware&#xff08;中间件&…

【通义千问】蓝耘智算 | 智启未来:蓝耘MaaS×通义QwQ-32B引领AI开发生产力

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈人工智能与大模型应用 ⌋ ⌋ ⌋ 人工智能&#xff08;AI&#xff09;通过算法模拟人类智能&#xff0c;利用机器学习、深度学习等技术驱动医疗、金融等领域的智能化。大模型是千亿参数的深度神经网络&#xff08;如ChatGPT&…

Scratch 3.0安装包,支持Win7/10/11、Mac电脑手机平板、少儿便编程的启蒙软件。

Scratch是一款由麻省理工学院&#xff08;MIT&#xff09; 设计开发的少儿编程工具。其特点是&#xff1a;使用者可以不认识英文单词&#xff0c;也可以不使用键盘&#xff0c;就可以进行编程。构成程序的命令和参数通过积木形状的模块来实现。用鼠标拖动指令模块到脚本区就可以…

Deepseek学习--工具篇之Ollama

Deepseek学习--工具篇之Ollama 用途特点简化部署‌轻量级与可扩展性‌API支持‌预构建模型库‌模型导入与定制‌跨平台支持‌命令行工具与环境变量‌ 来源缘起诞生爆发持续 安装使用方法下载安装安装模型调用API 用途 我们在进行Deepseek本地部署的时候&#xff0c;通常会用到…

Flask多参数模版使用

需要建立目录templates&#xff1b; 把建好的html文件放到templates目录里面&#xff1b; 约定好参数名字&#xff0c;单个名字可以直接使用&#xff1b;多参数使用字典传递&#xff1b; 样例&#xff1a; from flask import render_template # 模板 (Templates) #Flask 使用…

LabVIEW旋转设备状态在线监测系统

为了提高大型旋转设备如电机和水泵的监控效率和故障诊断能力&#xff0c;用LabVIEW软件开发了一套实时监测与故障诊断系统。该系统集成了趋势分析、振动数据处理等多项功能&#xff0c;可实时分析电机电流、压力、温度及振动数据&#xff0c;以早期识别和预报故障。 ​ 项目背…

汽车PKE无钥匙进入系统一键启动系统定义与原理

汽车智能钥匙&#xff08;PKE无钥匙进入系统&#xff09;一键启动介绍 系统定义与原理 汽车无钥匙进入系统&#xff0c;简称PKE&#xff08;Passive Keyless Entry&#xff09;&#xff0c;该系统采用了RFID无线射频技术和车辆身份编码识别系统&#xff0c;率先应用小型化、小…

【Idea】 xml 文本粘贴保持原有文本的缩进格式

Idea xml 文本粘贴保持原有文本的缩进格式 在使用 IntelliJ IDEA 2018 版本中的 MyBatis 时&#xff0c;粘贴 SQL 语句会自动对齐&#xff0c;此时需要进行相关设置来禁用此功能。 setting——>Editor——>Code Style——>XML 勾选“Keep white spaces”

Unity 和 Python 的连接(通过SocketIO)附源码

在游戏或者项目开发中&#xff0c;Unity 通常用于创建前端&#xff0c;而 Python 则因其强大的数据处理能力常被用作后端。通过 Socket.IO&#xff0c;我们可以轻松地实现 Unity 和 Python 的实时通信。本文将介绍如何通过 Socket.IO 连接 Unity 和 Python&#xff0c;并附上完…

[IP]UART

UART 是一个简易串口ip&#xff0c;用户及配置接口简单。 波特率从9600至2000000。 该 IP 支持以下特性&#xff1a; 异步串行通信&#xff1a;标准 UART 协议&#xff08;1 起始位&#xff0c;8 数据位&#xff0c;1 停止位&#xff0c;无奇偶校验&#xff09;。 参数化配置…

vue2实现可拖拽菜单栏,及根据菜单内容自动扩展宽度

分为两个功能 基本的html: <el-scrollbarid"leftmenu"v-resize"MuneResize"wrap-class"scrollbar-wrapper"><el-menu:default-active"activeMenu":collapse"isCollapse":background-color"variables.menuBg&…

【软件工程】03_软件需求分析

3.1 系统分析 1. 系统分析概述 系统分析是一组统称为计算机系统工程的活动。它着眼于所有的系统元素,而非仅仅局限于软件。系统分析主要探索软件项目的目标、市场预期、主要的技术指标等,其目的在于帮助决策者做出是否进行软件项目立项的决定。 2. 可行性分析(Feasibility …

父组件中循环生成多个子组件时,有且只有最后一个子组件的watch对象生效问题及解决办法

提示&#xff1a;父组件中循环生成多个子组件时&#xff0c;有且只有最后一个子组件的watch对象生效问题及解决办法 文章目录 [TOC](文章目录) 前言一、问题二、解决方法——使用function函数代替箭头函数()>{}总结 前言 ‌‌‌‌‌问题&#xff1a;子组件用that解决watch无…

SpringMVC(八)Knife4j 接口文档

目录 一 基础使用 1 配置pom.xml相关依赖 2 项目配置 3 输入指定路径&#xff08;http://localhost:8080/doc.html&#xff09; 二 一些使用方法 1 Tag 2 Operation 3 Schema 4 Parameter 5 可以根据需求来设置 补充&#xff1a;日期的格式化 Knife4j 是基于 Swag…

二分算法--整数二分

二分算法–整数二分 假如给定一个整数序列&#xff0c;{ a 1 a_1 a1​, a 2 a_2 a2​, a 3 a_3 a3​, …, a n a_n an​} 我们将整个数列根据某个元素 a x a_x ax​将数列分成左右两个部分&#xff08;某一部分可以包含 a x a_x ax​&#xff09; 首先我们定义一个mid 如…

有效的括号 力扣20

一、题目 二、思路 这题算是栈的经典应用。 主要有三种情况&#xff1a; 第一种情况&#xff1a;已经遍历完了字符串&#xff0c;但是栈不为空&#xff0c;说明有相应的左括号没有右括号来匹配&#xff0c;所以return false 第二种情况&#xff1a;遍历字符串匹配的过程中&…

Nuxt3 使用 ElementUI Plus报错问题

本地正常&#xff0c;打包上线异常 解决方式&#xff1a;官方组件需要被包裹一层&#xff0c;如以下示例&#xff1a; <ClientOnly> </ClientOnly>

uniapp vue3项目定义全局变量,切换底部babar时根据条件刷新页面

前言 uniapp项目中&#xff0c;每个tabbar页面来回点时候&#xff0c;不会触发页面更新。但是有时页面上有数据发生改变需要更新模版时&#xff0c;就得能及时的通知到页面。如果在onshow生命周期里每次都调用异步请求更新数据&#xff0c;有些不合理&#xff0c;况且页面有时…

vulnhub-Hackme-隧道建立、SQL注入、详细解题、思路清晰。

vulnhub-Hackme-隧道建立、SQL注入、详细解题、思路清晰。 一、信息收集 2025.3.14 PM 12&#xff1a;18 1、主机发现 arp-scan -l nmap -sn 192.168.66.0/24 2、端口扫描 1、nmap --min-rate 10000 -p- 192.168.66.182 -oA port 查看所有开放端口2、map -sS -sV 192.168.6…