<el-radio-group v-model
时间: 2024-05-19 17:09:14 浏览: 165
<el-radio-group v-model>是一个用于Vue.js框架的Element UI组件库中的单选按钮组件。它是基于radio input元素实现的,可以在多个选项中选择一个选项。其中,v-model是用于绑定数据的指令,可以将选中的值与数据进行双向绑定,从而实现数据的动态更新。在使用<el-radio-group v-model>时,需要设置options属性来定义可选项列表,并通过label属性来指定每个选项对应的值。此外,还可以通过disabled属性来禁用某些选项,通过size属性来设置单选按钮的尺寸。如果需要对单选按钮组件进行进一步的样式定制,可以通过CSS样式来实现。
相关问题
<template> <div> <el-dialog :title="!dataForm.id ? '指令生成' : '修改'" :close-on-click-modal="false" v-dialogDrag :visible.sync="visible" id="myOrder"> <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="80px" style="margin-top: -0.275rem;background-color: #fff;border: 0px solid #DCDFE6;"> <!-- 升级类型 1-BMS升级 2-Tracker通讯板升级 --> <el-form-item label="升级类型" size="mini" prop="type"> <el-radio-group v-model="dataForm.type" :disabled="dataForm.id ? 'disabled' : null"> <el-radio :label="1">BMS升级</el-radio> <el-radio :label="2">Tracker通讯板升级</el-radio> <!-- <el-radio :label="2">参数设置</el-radio> --> </el-radio-group> </el-form-item> <el-form-item label="项目" prop="projectParameter"> <el-select v-model="dataForm.projectParameter" placeholder="请选择项目" @change="blurSelect" style="width:6rem" clearable> <el-option v-for="item in projectIds" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> <el-form-item label="项目名称" prop="projectRef"> <el-input v-model="dataForm.projectRef" placeholder="项目简称" style="width:6rem" readonly></el-input> </el-form-item> <el-form-item label="升级模式" size="mini" prop="orderType"> <el-radio-group v-model="dataForm.orderType" :disabled="dataForm.id ? 'disabled' : null"> <el-radio :label="1" @change="typeChange(1)">指定设备升级</el-radio> <el-radio :label="0" @change="typeChange(0)">所有设备升级</el-radio> </el-radio-group> </el-form-item> <el-form-item label="设备导入" v-if="showotaall"> <!-- <el-button v-if="isAuth('maya:myotarequest:batchUpgrade')" type="success" @click="otaBatchUpgradeHandle()" :disabled="dataListSelections.length != 2">批量升级</el-button> --> <el-button type="success" @click="otaBatchUpgradeHandle()" >Excel导入</el-button> </el-form-item> <el-form-item label="设备编号" prop="deviceCodes" v-if="showotaall"> <!-- <el-input v-model="dataForm.deviceCodes" placeholder="设备编号。多个用“;”隔开,如下224042102999025;411219000005615;411219000005617"></el-input> --> <el-autocomplete style="width:10rem" size="normal" v-model="dataForm.deviceCodes" :popper-append-to-body="false" :fetch-suggestions="querySearchAsync" @select="handleSelect" placeholder="请输入设备编号。多个用“;”隔开,如下224042102999025;411219000005615;411219000005617"> </el-autocomplete> </el-form-item> <el-form-item label="Topic" prop="topic"> <el-select v-model="dataForm.topic" placeholder="请选择topic" style="width:6rem" > <el-option v-for="item in topics" :key="item.value" :label="item.label" :value="item.value" :disabled="item.disabled" > </el-option> </el-select> </el-form-item> <!-- <el-form-item label="通讯方式" prop="communicationMode"> <el-input v-model="dataForm.communicationMode" placeholder="通讯方式 0:暂无 1:串口 2:can 3:i2c"></el-input> </el-form-item> --> <!-- <el-form-item label="通讯类型" size="mini" prop="communicationMode"> <el-radio-group v-model="dataForm.communicationMode" :disabled="dataForm.id ? 'disabled' : null"> <el-radio :label="1">串口</el-radio> <el-radio :label="2">can</el-radio> <el-radio :label="3">i2c</el-radio> </el-radio-group> </el-form-item> --> <!-- <el-form-item label="can通讯的帧id" prop="frameIdCan"> <el-input v-model="dataForm.frameIdCan" placeholder="can通讯的帧id"></el-input> </el-form-item> <el-form-item label="通讯数据" prop="payload"> <el-input v-model="dataForm.payload" placeholder="通讯的数据"></el-input> </el-form-item> --> <!-- <el-form-item label="升级固件地址" prop="url"> <el-input v-model="dataForm.url" placeholder="升级时的固件地址"></el-input> </el-form-item> --> <!-- <el-form-item label="*固件地址" prop="url" v-if="showota"> --> <el-form-item label="*固件地址" prop="url"> <el-select v-model="dataForm.url" placeholder="升级固件地址" style="width:10rem"> <el-option v-for="item in uploadurls" :key="item.value" :label="item.label" :value="item.value" :disabled="item.disabled" > </el-option> </el-select> </el-form-item> <el-form-item label="硬件版本" prop="hardwareversion"> <el-input v-model="dataForm.hardwareversion" placeholder="要升级的目标电池硬件版本" style="width:6rem;padding-left:0.0rem;"></el-input> <br/><span style="color:blue;font-size:13px">✸ 可不填写,若指定要升级的目标电池硬件版本,填写请在前面请带上“V”,如V1.00,V1.02</span> </el-form-item> <el-form-item label="*软件版本" prop="softwareversion"> <el-input v-model="dataForm.softwareversion" placeholder="当前升级的固件的软件版本" style="width:6rem"></el-input> </el-form-item> <el-form-item label="是否执行" size="mini" prop="todoNow"> <el-radio-group v-model="dataForm.todoNow"> <el-radio :label="0">等待</el-radio> <el-radio :label="1">立即执行</el-radio> </el-radio-group> </el-form-item> <!-- <el-form-item label="固件MD5" prop="md5"> <el-input v-model="dataForm.md5" placeholder="固件MD5"></el-input> </el-form-item> <el-form-item label="固件大小" prop="size"> <el-input v-model="dataForm.size" placeholder="固件大小"></el-input> </el-form-item> <el-form-item label="配置是否处理 " prop="handled"> <el-input v-model="dataForm.handled" placeholder="配置是否处理 1:已处理 0:待处理"></el-input> </el-form-item> <el-form-item label="是否立即执行" prop="todoNow"> <el-input v-model="dataForm.todoNow" placeholder="是否立即执行 0:等待执行 1:立即执行"></el-input> </el-form-item>--> <!-- <el-form-item label="是否执行" size="mini" prop="todoNow"> <el-radio-group v-model="dataForm.todoNow"> <el-radio :label="0">等待</el-radio> <el-radio :label="1">执行</el-radio> </el-radio-group> </el-form-item> --> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="visible = false">取消</el-button> <el-button type="primary" @click="dataFormSubmit()">生成指令</el-button> </span> </el-dialog> <!-- 弹窗, Excel导入--> <ota-batch-upgrade v-if="otaBatchUpgradeVisible" ref="otaBatchUpgrade" @refreshDataList="onSubmit(1)"></ota-batch-upgrade> </div> </template> <script> import OtaBatchUpgrade from './myotabatchupgrade' export default { data () { return { visible: false, showotaall: true, otaBatchUpgradeVisible: false, projectIds:[], uploadurls:[], topics: [{ value: '/{productKey}/{deviceId}/maya7026/ota/upgrade/push', label: '固件升级(ota/upgrade/push)' } // , { // value: '/{productKey}/{deviceId}/upgradebox/{projectRef}/property/get', // label: '电池数据获取(property/get)' // } ], dataForm: { id: 0, type: 1, orderType: 1, projectParameter: '', deviceCodes: '', projectRef: '', topic: '', // communicationMode: 1, // frameIdCan: '', payload: '', url: '', hardwareversion: '', softwareversion: '', md5: '', size: '', handled: '', todoNow: 0, createTime: '', updateTime: '' }, dataRule: { type: [ { required: true, message: '升级类型 1-BMS升级 2-Tracker通讯板升级 不能为空', trigger: 'blur' } ], orderType: [ { required: true, message: '升级模式勾选 不能为空', trigger: 'blur' } ], projectParameter: [ { required: true, message: '不能为空', trigger: 'blur' } ], // deviceCodes: [ // { required: true, message: '设备编号不能为空', trigger: 'blur' } // ], // projectRef: [ // { required: true, message: '项目简称(用于topic)不能为空', trigger: 'blur' } // ], topic: [ { required: true, message: 'mqtt发送主题,如:battery/{batteryCode}/down/upgrade不能为空', trigger: 'blur' } ], // communicationMode: [ // { required: true, message: '通讯方式 0:暂无 1:串口 2:can 3:i2c不能为空', trigger: 'blur' } // ], // frameIdCan: [ // { required: true, message: 'can通讯的帧id不能为空', trigger: 'blur' } // ], // payload: [ // { required: true, message: '通讯的数据不能为空', trigger: 'blur' } // ], // url: [ // { required: true, message: '升级时的固件地址不能为空', trigger: 'blur' } // ], // md5: [ // { required: true, message: '固件MD5不能为空', trigger: 'blur' } // ], // size: [ // { required: true, message: '固件大小不能为空', trigger: 'blur' } // ], // handled: [ // { required: true, message: '配置是否处理 1:已处理 0:待处理不能为空', trigger: 'blur' } // ], todoNow: [ { required: true, message: '是否立即执行 0:等待执行 1:立即执行不能为空', trigger: 'blur' } ], // createTime: [ // { required: true, message: '不能为空', trigger: 'blur' } // ], // updateTime: [ // { required: true, message: '更新时间不能为空', trigger: 'blur' } // ] } } }, components: { OtaBatchUpgrade, }, methods: { typeChange(val){ // alert('packageChange') if(val=='1'){ // 指定电池升级,打开电池编号输入框 this.showotaall = true }else if(val=='0'){ // ota升级项目下所有电池 this.showotaall = false } }, // el-select失去焦点必填校验 blurSelect() { var project_name = this.dataForm.projectParameter.substring(this.dataForm.projectParameter.lastIndexOf("::")+2) this.$set(this.dataForm,'projectRef', project_name) }, querySearchAsync(queryString, cb) { clearTimeout(1000); var results = [] // alert('queryString='+queryString) if (queryString == '') { cb(results); } else { //掉接口需要的参数 this.$http({ url: this.$http.adornUrl('/mqtt/mqtttriad/getDeviceIds'), method: 'get', params: this.$http.adornParams({ 'deviceId': queryString, 'projectParameter': this.dataForm.projectParameter }) }).then(({data}) => { if (data && data.code === 0) { // alert(data.data.length) var result = data.data //循环放到一个远程搜索需要的数组 for (let i = 0; i < result.length; i++) { const element = result[i]; // alert(element) results.push({ value: element, id: i }) } cb(results); } else { console.log('没有数据的显示') results = [] cb(results); } }) } }, //点击出现搜索后点击的每一项 handleSelect(item) { this.id = item.id this.name = item.value }, init (id) { this.dataForm.id = id || 0 this.showotaall = true this.visible = true this.$nextTick(() => { this.$refs['dataForm'].resetFields() if (this.dataForm.id) { this.$http({ url: this.$http.adornUrl(`/maya/myotarequest/info/${this.dataForm.id}`), method: 'get', params: this.$http.adornParams() }).then(({data}) => { if (data && data.code === 0) { this.projectIds = data.data.projectMenus.projectIds this.uploadurls = data.data.OtaUrlMenus.uploads const socitem = data.data.mqttSends this.dataForm.type = socitem.type this.dataForm.projectParameter = socitem.projectParameter this.dataForm.deviceCodes = socitem.deviceCodes this.dataForm.projectRef = socitem.projectRef this.dataForm.topic = socitem.topic // this.dataForm.communicationMode = socitem.communicationMode // this.dataForm.frameIdCan = socitem.frameIdCan // this.dataForm.payload = socitem.payload this.dataForm.url = socitem.url this.dataForm.md5 = socitem.md5 this.dataForm.size = socitem.size this.dataForm.handled = socitem.handled this.dataForm.todoNow = socitem.todoNow this.dataForm.createTime = socitem.createTime this.dataForm.updateTime = socitem.updateTime } }) }else{ this.$http({ url: this.$http.adornUrl(`/maya/myotarequest/getOtaAndProjectMenus`), method: 'get', params: this.$http.adornParams() }).then(({data}) => { if (data && data.code === 0) { this.projectIds = data.data.projectMenus.projectIds this.uploadurls = data.data.OtaUrlMenus.uploads } }) } }) }, /** * 设备导入弹窗触发方法 */ otaBatchUpgradeHandle(){ this.otaBatchUpgradeVisible=true this.$nextTick(()=>{ this.$refs.otaBatchUpgrade.init() }) }, // 表单提交 dataFormSubmit () { if(this.dataForm.orderType==='1' || this.dataForm.orderType===1){ if(this.dataForm.deviceCodes === '' || this.dataForm.deviceCodes === undefined || this.dataForm.deviceCodes === null){ this.$message.warning('选择指定电池升级的,设备编号不能为空!') return } } // if(this.dataForm.type==='0' || this.dataForm.type===0){ if(this.dataForm.url === '' || this.dataForm.url === undefined || this.dataForm.url === null){ this.$message.warning('升级固件地址不能为空!') return } // if(this.dataForm.hardwareversion === '' || this.dataForm.hardwareversion === undefined || this.dataForm.hardwareversion === null){ // this.$message.warning('升级硬件版本不能为空!') // return // } if(this.dataForm.softwareversion === '' || this.dataForm.softwareversion === undefined || this.dataForm.softwareversion === null){ this.$message.warning('升级软件版本不能为空!') return } // } this.$refs['dataForm'].validate((valid) => { if (valid) { this.$http({ url: this.$http.adornUrl(`/maya/myotarequest/create`), method: 'post', data: this.$http.adornData({ 'id': this.dataForm.id || undefined, 'type': this.dataForm.type, 'orderType': this.dataForm.orderType, 'projectParameter': this.dataForm.projectParameter, 'deviceCodes': this.dataForm.deviceCodes, 'projectRef': this.dataForm.projectRef, 'topic': this.dataForm.topic, // 'communicationMode': this.dataForm.communicationMode, // 'frameIdCan': this.dataForm.frameIdCan, // 'payload': this.dataForm.payload, 'url': this.dataForm.url, 'hardwareversion': this.dataForm.hardwareversion, 'softwareversion': this.dataForm.softwareversion, 'md5': this.dataForm.md5, 'size': this.dataForm.size, 'handled': this.dataForm.handled, 'todoNow': this.dataForm.todoNow, 'createTime': this.dataForm.createTime, 'updateTime': this.dataForm.updateTime }) }).then(({data}) => { if (data && data.code === 0) { this.$message({ message: '操作成功', type: 'success', duration: 1500, onClose: () => { this.visible = false this.$emit('refreshDataList') // this.$emit('refreshDataList', this.dataForm.type,this.dataForm.communicationMode,this.dataForm.deviceCodes); } }) } else { this.$message.error(data.msg) } }) } }) } } } </script> <style> #myOrder element.style { width: 150px; } </style>父组件是这样的
<think>我们有一个父组件(包含弹窗的组件)和一个子组件(Excel导入弹窗组件)。在父组件中,我们通过`otaBatchUpgradeHandle`方法打开子组件(Excel导入弹窗)。子组件在解析Excel后,通过`$emit`触发事件将解析结果传递给父组件。父组件需要接收这个结果并填充到表单的“设备编号”字段(多个设备编号用分号隔开)。
根据提供的父组件代码,我们需要做以下调整:
1. 在父组件中,当子组件(Excel导入弹窗)触发事件时,将解析得到的设备编号字符串赋值给`dataForm.deviceCodes`。
2. 同时,关闭Excel导入弹窗。
具体步骤:
1. 在父组件的`methods`中,定义一个方法(例如`handleExcelParsed`)来处理子组件传递过来的数据。
2. 在子组件(`OtaBatchUpgrade`)被引入的地方,监听子组件发出的事件(例如`excel-parsed`),并绑定到`handleExcelParsed`方法。
3. 在`handleExcelParsed`方法中,将传递过来的字符串赋值给`this.dataForm.deviceCodes`,并关闭Excel导入弹窗。
修改父组件的代码:
在父组件的模板中,已经有一个子组件的引用:
```vue
<ota-batch-upgrade v-if="otaBatchUpgradeVisible" ref="otaBatchUpgrade" @refreshDataList="onSubmit(1)"></ota-batch-upgrade>
```
我们需要修改这个引用,添加一个事件监听(例如`excel-parsed`):
将`@refreshDataList="onSubmit(1)"`改为(或者同时添加):
```vue
<ota-batch-upgrade v-if="otaBatchUpgradeVisible" ref="otaBatchUpgrade" @refreshDataList="onSubmit(1)" @excel-parsed="handleExcelParsed"></ota-batch-upgrade>
```
然后,在父组件的`methods`中添加`handleExcelParsed`方法:
```javascript
handleExcelParsed(data) {
// 将解析的设备编号字符串赋值给表单字段
this.dataForm.deviceCodes = data;
// 关闭Excel导入弹窗
this.otaBatchUpgradeVisible = false;
}
```
同时,注意子组件(Excel导入弹窗)在点击确定按钮时,需要触发`excel-parsed`事件,并传递解析结果。
但是,我们之前已经修改过子组件,在确定按钮点击时触发了`excel-parsed`事件(见之前的代码)。因此,我们只需要在父组件中监听这个事件即可。
另外,在父组件中,我们还需要确保在打开Excel导入弹窗时,将当前选中的项目(`projectParameter`)传递给子组件,因为子组件在解析Excel后可能需要这个项目信息(如果需要的话)。但根据当前需求,我们只需要将设备编号字符串传递回来,所以暂时不需要传递项目信息。
但是,请注意:在子组件中,我们读取的是Excel的第一列,并不依赖项目信息。所以,我们直接传递字符串即可。
修改后的父组件代码片段:
1. 在子组件标签上添加事件监听:
```vue
<ota-batch-upgrade
v-if="otaBatchUpgradeVisible"
ref="otaBatchUpgrade"
@refreshDataList="onSubmit(1)"
@excel-parsed="handleExcelParsed"
></ota-batch-upgrade>
```
2. 在父组件的methods中添加handleExcelParsed方法:
```javascript
handleExcelParsed(data) {
this.dataForm.deviceCodes = data; // 将解析的设备编号字符串赋值给表单
this.otaBatchUpgradeVisible = false; // 关闭Excel导入弹窗
}
```
3. 注意:在父组件中,我们可能已经有一个`onSubmit`方法用于刷新列表,但这里我们不需要改变它。
4. 另外,在子组件中,我们之前已经实现了在点击确定按钮时触发`excel-parsed`事件,并传递`this.resultStr`(即解析的字符串)。
这样,当用户在Excel导入弹窗中上传文件并点击确定后,解析的设备编号字符串就会自动填充到父组件表单的“设备编号”输入框中。
但是,我们还需要注意一点:在父组件中,打开Excel导入弹窗的方法是`otaBatchUpgradeHandle`,这个方法只是设置了`otaBatchUpgradeVisible`为true,然后调用子组件的`init`方法。我们不需要修改它。
完整修改后的父组件代码:
由于原始父组件代码较长,我只展示修改的部分:
在模板中修改子组件的引用:
```vue
<ota-batch-upgrade
v-if="otaBatchUpgradeVisible"
ref="otaBatchUpgrade"
@refreshDataList="onSubmit(1)"
@excel-parsed="handleExcelParsed"
></ota-batch-upgrade>
```
在methods中添加:
```javascript
methods: {
// ... 其他方法
// 处理Excel解析完成事件
handleExcelParsed(data) {
this.dataForm.deviceCodes = data;
this.otaBatchUpgradeVisible = false; // 关闭弹窗
// 可以在这里给出提示
this.$message.success('设备编号已导入');
},
// ... 其他方法
}
```
这样,我们就完成了将Excel导入的设备编号回填到父组件表单的功能。
注意:如果子组件中同时需要触发两个事件(`refreshDataList`和`excel-parsed`),那么需要确保在子组件的`handleConfirm`方法中触发这两个事件。但是根据之前的子组件代码,我们只触发了`excel-parsed`事件。如果不需要在导入后刷新列表,那么可以去掉`refreshDataList`事件。
但是,在父组件中,子组件的引用上同时监听了两个事件。如果子组件只触发`excel-parsed`事件,那么`refreshDataList`事件不会被触发,所以不会影响。
另外,在子组件中,我们关闭了对话框(`dialogVisible = false`),但是父组件中控制子组件显示的是`otaBatchUpgradeVisible`,所以我们在父组件的`handleExcelParsed`方法中设置`otaBatchUpgradeVisible = false`来关闭弹窗。
最后,由于在子组件中,我们关闭了自己的对话框(通过`dialogVisible = false`),但父组件中控制子组件显示的是`otaBatchUpgradeVisible`,所以子组件关闭自己的对话框并不会影响父组件的状态。因此,我们需要在父组件中主动关闭弹窗(设置`otaBatchUpgradeVisible = false`)。
这样,当子组件触发`excel-parsed`事件后,父组件会关闭子组件的弹窗,并将数据回填。
如果子组件在触发事件后没有关闭自己的弹窗,那么它还会显示。所以,我们可以在子组件中触发事件后关闭自己的弹窗(之前已经做了),但父组件也需要关闭(通过设置`otaBatchUpgradeVisible`为false)。这样双重保障。
但是,在子组件中,我们触发事件后关闭了自己的弹窗(`dialogVisible = false`),而父组件在事件处理中又设置`otaBatchUpgradeVisible = false`,这样是安全的。
因此,按照上述修改即可。
由于父组件代码较长,这里不提供完整代码,只提供修改点。</think>我将帮助您将Excel导入功能集成到父组件中,实现设备编号的自动填充。下面是修改后的完整代码:
```vue
<template>
<div>
<el-dialog
:title="!dataForm.id ? '指令生成' : '修改'"
:close-on-click-modal="false"
v-dialogDrag
:visible.sync="visible"
id="myOrder"
>
<!-- 对话框内容 -->
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="80px"
style="margin-top: -0.275rem; background-color: #fff; border: 0px solid #dcdfe6"
>
<!-- 升级类型 -->
<el-form-item label="升级类型" size="mini" prop="type">
<el-radio-group v-model="dataForm.type" :disabled="dataForm.id ? 'disabled' : null">
<el-radio :label="1">BMS升级</el-radio>
<el-radio :label="2">Tracker通讯板升级</el-radio>
</el-radio-group>
</el-form-item>
<!-- 项目选择 -->
<el-form-item label="项目" prop="projectParameter">
<el-select
v-model="dataForm.projectParameter"
placeholder="请选择项目"
@change="blurSelect"
style="width: 6rem"
clearable
>
<el-option
v-for="item in projectIds"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<!-- 项目名称 -->
<el-form-item label="项目名称" prop="projectRef">
<el-input v-model="dataForm.projectRef" placeholder="项目简称" style="width: 6rem" readonly></el-input>
</el-form-item>
<!-- 升级模式 -->
<el-form-item label="升级模式" size="mini" prop="orderType">
<el-radio-group v-model="dataForm.orderType" :disabled="dataForm.id ? 'disabled' : null">
<el-radio :label="1" @change="typeChange(1)">指定设备升级</el-radio>
<el-radio :label="0" @change="typeChange(0)">所有设备升级</el-radio>
</el-radio-group>
</el-form-item>
<!-- Excel导入区域 -->
<el-form-item label="设备导入" v-if="showotaall">
<el-button type="success" @click="openExcelImportDialog">Excel导入</el-button>
<span v-if="importedDeviceCount > 0" class="import-success">
<i class="el-icon-success"></i> 已导入 {{ importedDeviceCount }} 台设备
</span>
</el-form-item>
<!-- 设备编号 -->
<el-form-item label="设备编号" prop="deviceCodes" v-if="showotaall">
<el-autocomplete
style="width: 10rem"
size="normal"
v-model="dataForm.deviceCodes"
:popper-append-to-body="false"
:fetch-suggestions="querySearchAsync"
@select="handleSelect"
placeholder="请输入设备编号,多个用分号隔开"
></el-autocomplete>
</el-form-item>
<!-- Topic选择 -->
<el-form-item label="Topic" prop="topic">
<el-select v-model="dataForm.topic" placeholder="请选择topic" style="width: 6rem">
<el-option
v-for="item in topics"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
<!-- 固件地址 -->
<el-form-item label="*固件地址" prop="url">
<el-select v-model="dataForm.url" placeholder="升级固件地址" style="width: 10rem">
<el-option
v-for="item in uploadurls"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
<!-- 硬件版本 -->
<el-form-item label="硬件版本" prop="hardwareversion">
<el-input
v-model="dataForm.hardwareversion"
placeholder="要升级的目标电池硬件版本"
style="width: 6rem; padding-left: 0rem"
></el-input>
<br />
<span style="color: blue; font-size: 13px"
>✸ 可不填写,若指定要升级的目标电池硬件版本,填写请在前面请带上“V”,如V1.00,V1.02</span
>
</el-form-item>
<!-- 软件版本 -->
<el-form-item label="*软件版本" prop="softwareversion">
<el-input
v-model="dataForm.softwareversion"
placeholder="当前升级的固件的软件版本"
style="width: 6rem"
></el-input>
</el-form-item>
<!-- 是否执行 -->
<el-form-item label="是否执行" size="mini" prop="todoNow">
<el-radio-group v-model="dataForm.todoNow">
<el-radio :label="0">等待</el-radio>
<el-radio :label="1">立即执行</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<!-- 对话框底部 -->
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="dataFormSubmit()">生成指令</el-button>
</span>
</el-dialog>
<!-- Excel导入弹窗 -->
<el-dialog
title="Excel导入设备"
:visible.sync="excelDialogVisible"
width="600px"
:close-on-click-modal="false"
>
<div class="dialog-content">
<div class="action-section">
<div class="upload-section">
<el-upload
action="#"
:auto-upload="false"
:before-upload="beforeExcelUpload"
:on-change="handleExcelFileChange"
:limit="1"
:on-exceed="handleExcelExceed"
:file-list="excelFileList"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
<div>点击或拖拽Excel文件到此处上传</div>
<div class="el-upload__tip">支持.xlsx、.xls格式文件</div>
</div>
</el-upload>
</div>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="excelDialogVisible = false">取 消</el-button>
<el-button
type="primary"
@click="processExcelFile"
:disabled="!excelFileList.length || excelLoading"
>
{{ excelLoading ? "处理中..." : "确 定" }}
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import * as XLSX from "xlsx";
export default {
data() {
return {
visible: false,
excelDialogVisible: false, // Excel导入弹窗可见性
excelFileList: [], // Excel文件列表
excelLoading: false, // Excel处理中状态
importedDeviceCount: 0, // 导入的设备数量
showotaall: true,
projectIds: [],
uploadurls: [],
topics: [
{
value: "/{productKey}/{deviceId}/maya7026/ota/upgrade/push",
label: "固件升级(ota/upgrade/push)",
},
],
dataForm: {
id: 0,
type: 1,
orderType: 1,
projectParameter: "",
deviceCodes: "",
projectRef: "",
topic: "",
payload: "",
url: "",
hardwareversion: "",
softwareversion: "",
md5: "",
size: "",
handled: "",
todoNow: 0,
createTime: "",
updateTime: "",
},
dataRule: {
type: [
{
required: true,
message: "升级类型 1-BMS升级 2-Tracker通讯板升级 不能为空",
trigger: "blur",
},
],
orderType: [
{ required: true, message: "升级模式勾选 不能为空", trigger: "blur" },
],
projectParameter: [
{ required: true, message: "不能为空", trigger: "blur" },
],
topic: [
{
required: true,
message: "mqtt发送主题,如:battery/{batteryCode}/down/upgrade不能为空",
trigger: "blur",
},
],
todoNow: [
{
required: true,
message: "是否立即执行 0:等待执行 1:立即执行不能为空",
trigger: "blur",
},
],
},
};
},
methods: {
// 打开Excel导入对话框
openExcelImportDialog() {
this.excelDialogVisible = true;
this.excelFileList = [];
},
// Excel上传前验证
beforeExcelUpload(file) {
const validTypes = [
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-excel",
];
if (!validTypes.includes(file.type)) {
this.$message.error("请上传Excel格式的文件 (.xlsx 或 .xls)");
return false;
}
return true;
},
// Excel文件变化处理
handleExcelFileChange(file) {
if (!file) return;
const validTypes = [
"application/vnd.ms-excel", // .xls
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // .xlsx
];
if (!validTypes.includes(file.raw.type)) {
this.$message.error("请上传Excel格式的文件 (.xlsx 或 .xls)");
this.excelFileList = [];
return;
}
this.excelFileList = [file];
},
// 处理Excel文件
processExcelFile() {
if (!this.excelFileList.length) {
this.$message.warning("请先上传Excel文件");
return;
}
const file = this.excelFileList[0].raw;
this.readExcelFirstColumn(file);
},
// 读取Excel第一列数据
readExcelFirstColumn(file) {
this.excelLoading = true;
const reader = new FileReader();
reader.onload = (e) => {
try {
const data = new Uint8Array(e.target.result);
const workbook = XLSX.read(data, { type: "array" });
// 获取第一个工作表
const firstSheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[firstSheetName];
// 获取工作表范围
const range = XLSX.utils.decode_range(worksheet["!ref"]);
const firstColumn = [];
// 遍历所有行的第一列(列索引0)
for (let row = range.s.r; row <= range.e.r; row++) {
const cellAddress = XLSX.utils.encode_cell({ r: row, c: 0 }); // 固定列索引为0(A列)
const cell = worksheet[cellAddress];
// 处理空单元格情况
if (cell && cell.v) {
firstColumn.push(cell.v);
}
}
// 统计导入的设备数量
this.importedDeviceCount = firstColumn.length;
// 用分号拼接第一列数据
const deviceCodes = firstColumn.join(";");
// 填充到表单
this.dataForm.deviceCodes = deviceCodes;
this.$message.success(`成功导入 ${this.importedDeviceCount} 台设备`);
this.excelDialogVisible = false;
} catch (error) {
console.error("Excel解析错误:", error);
this.$message.error("Excel文件解析失败,请检查文件格式");
} finally {
this.excelLoading = false;
}
};
reader.onerror = () => {
this.$message.error("文件读取失败");
this.excelLoading = false;
};
reader.readAsArrayBuffer(file);
},
// Excel文件超出限制
handleExcelExceed() {
this.$message.warning("每次只能上传一个文件");
},
// 其他方法保持不变...
typeChange(val) {
if (val === "1" || val === 1) {
this.showotaall = true;
} else if (val === "0" || val === 0) {
this.showotaall = false;
}
},
blurSelect() {
var project_name = this.dataForm.projectParameter.substring(
this.dataForm.projectParameter.lastIndexOf("::") + 2
);
this.$set(this.dataForm, "projectRef", project_name);
},
querySearchAsync(queryString, cb) {
clearTimeout(1000);
var results = [];
if (queryString == "") {
cb(results);
} else {
this.$http({
url: this.$http.adornUrl("/mqtt/mqtttriad/getDeviceIds"),
method: "get",
params: this.$http.adornParams({
deviceId: queryString,
projectParameter: this.dataForm.projectParameter,
}),
}).then(({ data }) => {
if (data && data.code === 0) {
var result = data.data;
for (let i = 0; i < result.length; i++) {
const element = result[i];
results.push({
value: element,
id: i,
});
}
cb(results);
} else {
results = [];
cb(results);
}
});
}
},
handleSelect(item) {
this.id = item.id;
this.name = item.value;
},
init(id) {
this.dataForm.id = id || 0;
this.showotaall = true;
this.visible = true;
this.$nextTick(() => {
this.$refs["dataForm"].resetFields();
if (this.dataForm.id) {
this.$http({
url: this.$http.adornUrl(`/maya/myotarequest/info/${this.dataForm.id}`),
method: "get",
params: this.$http.adornParams(),
}).then(({ data }) => {
if (data && data.code === 0) {
this.projectIds = data.data.projectMenus.projectIds;
this.uploadurls = data.data.OtaUrlMenus.uploads;
const socitem = data.data.mqttSends;
this.dataForm.type = socitem.type;
this.dataForm.projectParameter = socitem.projectParameter;
this.dataForm.deviceCodes = socitem.deviceCodes;
this.dataForm.projectRef = socitem.projectRef;
this.dataForm.topic = socitem.topic;
this.dataForm.url = socitem.url;
this.dataForm.md5 = socitem.md5;
this.dataForm.size = socitem.size;
this.dataForm.handled = socitem.handled;
this.dataForm.todoNow = socitem.todoNow;
this.dataForm.createTime = socitem.createTime;
this.dataForm.updateTime = socitem.updateTime;
}
});
} else {
this.$http({
url: this.$http.adornUrl(`/maya/myotarequest/getOtaAndProjectMenus`),
method: "get",
params: this.$http.adornParams(),
}).then(({ data }) => {
if (data && data.code === 0) {
this.projectIds = data.data.projectMenus.projectIds;
this.uploadurls = data.data.OtaUrlMenus.uploads;
}
});
}
});
},
dataFormSubmit() {
if (this.dataForm.orderType === "1" || this.dataForm.orderType === 1) {
if (
this.dataForm.deviceCodes === "" ||
this.dataForm.deviceCodes === undefined ||
this.dataForm.deviceCodes === null
) {
this.$message.warning("选择指定电池升级的,设备编号不能为空!");
return;
}
}
if (
this.dataForm.url === "" ||
this.dataForm.url === undefined ||
this.dataForm.url === null
) {
this.$message.warning("升级固件地址不能为空!");
return;
}
if (
this.dataForm.softwareversion === "" ||
this.dataForm.softwareversion === undefined ||
this.dataForm.softwareversion === null
) {
this.$message.warning("升级软件版本不能为空!");
return;
}
this.$refs["dataForm"].validate((valid) => {
if (valid) {
this.$http({
url: this.$http.adornUrl(`/maya/myotarequest/create`),
method: "post",
data: this.$http.adornData({
id: this.dataForm.id || undefined,
type: this.dataForm.type,
orderType: this.dataForm.orderType,
projectParameter: this.dataForm.projectParameter,
deviceCodes: this.dataForm.deviceCodes,
projectRef: this.dataForm.projectRef,
topic: this.dataForm.topic,
url: this.dataForm.url,
hardwareversion: this.dataForm.hardwareversion,
softwareversion: this.dataForm.softwareversion,
md5: this.dataForm.md5,
size: this.dataForm.size,
handled: this.dataForm.handled,
todoNow: this.dataForm.todoNow,
createTime: this.dataForm.createTime,
updateTime: this.dataForm.updateTime,
}),
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.visible = false;
this.$emit("refreshDataList");
},
});
} else {
this.$message.error(data.msg);
}
});
}
});
},
},
};
</script>
<style>
#myOrder element.style {
width: 150px;
}
/* Excel导入成功提示样式 */
.import-success {
margin-left: 10px;
color: #67c23a;
font-size: 14px;
}
.import-success i {
margin-right: 5px;
}
/* 对话框样式调整 */
.dialog-content {
padding: 20px;
}
.upload-section {
margin: 0 auto;
width: 80%;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
padding: 10px 20px;
border-top: 1px solid #ebeef5;
}
</style>
```
### 主要修改说明:
1. **Excel导入功能集成**:
- 将Excel导入功能直接集成到父组件中,无需单独子组件
- 添加了`excelDialogVisible`控制Excel导入弹窗的显示
- 添加了`excelFileList`存储上传的Excel文件
- 添加了`excelLoading`处理加载状态
- 添加了`importedDeviceCount`显示导入设备数量
2. **Excel处理流程**:
- `openExcelImportDialog()`:打开Excel导入对话框
- `beforeExcelUpload()`:验证文件类型
- `handleExcelFileChange()`:处理文件选择变化
- `processExcelFile()`:触发Excel处理
- `readExcelFirstColumn()`:读取Excel第一列数据
3. **设备编号自动填充**:
```javascript
// 读取Excel第一列数据后
const deviceCodes = firstColumn.join(";");
this.dataForm.deviceCodes = deviceCodes;
```
4. **用户体验优化**:
- 添加导入成功提示:`已导入 X 台设备`
- 显示导入设备数量统计
- 优化了样式和布局
5. **错误处理**:
- 文件类型验证
- 空文件处理
- 异常捕获和错误提示
### 使用流程:
1. 点击"Excel导入"按钮打开导入弹窗
2. 上传Excel文件(支持.xlsx和.xls格式)
3. 点击"确定"处理文件
4. 系统自动解析Excel第一列数据
5. 解析结果自动填充到"设备编号"字段
6. 显示导入的设备数量
7. 完成表单其他部分并提交
### 优势:
1. **简化架构**:不再需要单独的子组件,所有功能集成在一个组件中
2. **直接数据绑定**:解析结果直接填充到表单,无需事件传递
3. **更直观的用户反馈**:实时显示导入的设备数量
4. **更好的错误处理**:统一的错误处理机制
5. **减少代码复杂度**:减少了组件间通信的复杂性
<el-radio-group v-model="roleType"> <el-radio label="1">管理员</el-radio> <el-radio label="2">教师</el-radio> <el-radio label="3">学生</el-radio> </el-radio-group>
<think>嗯,用户想了解如何正确使用 Element UI 的 el-radio-group 和 el-radio 组件。首先,我得回忆一下 Element UI 的文档结构,确保提供的信息准确。记得这两个组件通常一起使用,el-radio-group 包裹多个 el-radio,用来管理单选状态。可能需要解释 v-model 的绑定方式,以及 label 属性的作用。
用户提供的参考引用里有提到 el-radio 无法选择的问题,可能涉及 v-model 绑定错误或者 label 类型不匹配。比如,如果 status 是数字类型,但 label 用了字符串,就会有问题。需要提醒用户注意数据类型一致。
另外,引用中还提到禁用属性和样式覆盖的问题。应该说明如何通过 disabled 属性禁用单选项,以及如何自定义禁用样式,可能需要使用 CSS 覆盖默认样式。比如使用 !important 来提升优先级。
还有,用户可能需要示例代码来展示基本用法、禁用状态、样式自定义以及如何获取选中的值。代码示例要简洁,同时说明关键点,比如 v-model 绑定的变量、label 的值类型、事件处理等。
还要考虑常见问题,比如选项无法选择的情况,可能的原因有哪些,比如数据类型不一致、v-model 未正确初始化、作用域问题等。需要逐一列出,帮助用户排查。
可能需要补充如何动态生成选项,比如用 v-for 循环数组来创建 el-radio,这样更实用。同时,提醒在 el-radio-group 中使用 @change 事件来处理选择变化,获取选中的值。
最后,生成相关问题时要覆盖组件的其他功能,比如禁用、样式修改、与其他组件配合使用,以及常见错误的解决方法。确保用户能全面了解组件的使用和问题排查。</think>### Element UI el-radio-group 和 el-radio 使用方法及示例
#### 一、基础用法
1. **组件结构**
使用`el-radio-group`包裹多个`el-radio`实现单选组,通过`v-model`绑定选中值:
```html
<el-radio-group v-model="selectedValue">
<el-radio label="A">选项A</el-radio>
<el-radio label="B">选项B</el-radio>
<el-radio label="C">选项C</el-radio>
</el-radio-group>
```
- `v-model`绑定的是当前选中的`label`值
- `label`属性定义选项的唯一标识,支持字符串或数字类型
2. **数据初始化**
需在 Vue 实例的`data`中初始化`selectedValue`:
```javascript
data() {
return {
selectedValue: '' // 默认未选中,可设置初始值如 'A'
};
}
```
#### 二、进阶功能
1. **禁用选项**
通过`disabled`属性控制单个选项是否禁用:
```html
<el-radio label="D" :disabled="true">禁用选项</el-radio>
```
或动态绑定:
```html
<el-radio :label="item.value" :disabled="item.disabled" v-for="item in list" :key="item.value">
{{ item.label }}
</el-radio>
```
2. **样式自定义**
覆盖默认禁用样式需添加 CSS:
```css
.el-radio.is-disabled .el-radio__label {
color: #999 !important;
}
```
#### 三、完整示例
```html
<template>
<div>
<el-radio-group v-model="status" @change="handleChange">
<el-radio label="1" :disabled="isDisabled">停用</el-radio>
<el-radio label="2">启用</el-radio>
<el-radio label="3">待审核</el-radio>
</el-radio-group>
<p>当前状态:{{ status }}</p>
</div>
</template>
<script>
export default {
data() {
return {
status: '2', // 默认选中"启用"
isDisabled: true
};
},
methods: {
handleChange(val) {
console.log('选中值:', val);
}
}
};
</script>
```
#### 四、常见问题
1. **选项无法选择**
- 检查`v-model`绑定变量是否已初始化
- 确保`label`值的类型(字符串/数字)与`v-model`变量类型一致[^1]
- 避免在组件作用域外访问`v-model`变量
2. **动态选项渲染**
使用`v-for`动态生成选项:
```html
<el-radio-group v-model="selectedCity">
<el-radio v-for="city in cities" :label="city.value" :key="city.value">
{{ city.name }}
</el-radio>
</el-radio-group>
```
阅读全文
相关推荐













