<el-upload
action="#"
accept=".xml"
:show-file-list="false"
:before-upload="handleImport"
>
<el-button type="primary">导入(XML)</el-button>
</el-upload>
action="#"
:禁用默认上传行为accept=".xml"
:限制只能选择XML文件:show-file-list="false"
:隐藏文件列表显示:before-upload="handleImport"
:上传前触发处理函数
<el-row :gutter="10">
<el-col :span="4"></el-col>
<el-col :span="8"> FTP服务器地址 </el-col>
<el-col :span="4"> 用户名 </el-col>
<el-col :span="4"> 密码 </el-col>
<el-col :span="4"> 是否发送 </el-col>
</el-row>
<el-form :disabled="userStore.token == null" class="mt10">
<el-row :gutter="10" v-for="(item, index) of formData.ftpInfoList" :key="index" class="mt10">
<el-col :span="4" style="font-size: 12px;">
{{ item.ftpSvrType }}
</el-col>
<el-col :span="8">
<el-input v-model="item.ftpAddress" placeholder="" clearable />
</el-col>
<el-col :span="4">
<el-input v-model="item.username" placeholder="" clearable />
</el-col>
<el-col :span="4">
<el-input v-model="item.password" placeholder="" clearable type="password" />
</el-col>
<el-col :span="4">
<el-checkbox v-model="item.send" label="" :true-label="'1'" :false-label="'0'" />
</el-col>
<!-- <el-col :span="2">
<el-button type="primary" @click="test(formData.ftpImportweather)">测试</el-button>
</el-col> -->
</el-row>
</el-form>
const handleImport = (file) => {
// 文件类型校验
if (file.type !== 'text/xml') {
ElMessage.error('只支持XML文件格式')
return false
}
// 创建文件阅读器
const reader = new FileReader()
// 文件读取完成回调
reader.onload = (e) => {
try {
// 获取XML内容
const xmlContent = e.target.result
// 解析XML文档
const parser = new DOMParser()
const xmlDoc = parser.parseFromString(xmlContent, "text/xml")
// 创建新的配置数组
const newFtpInfoList = [
{
ftpSvrType: '平行观测数据',
ftpAddress: getXmlValue(xmlDoc, 'tbFTPPXGC'),
username: getXmlValue(xmlDoc, 'tbFTPPXGCUser'),
password: getXmlValue(xmlDoc, 'tbFTPPXGCPassWord'),
send: getXmlValue(xmlDoc, 'cbFTPPXGC') === '1' ? 'Y' : 'N'
},
// 其他配置项类似结构...
]
// 更新响应式数据
formData.value.ftpInfoList = newFtpInfoList
ElMessage.success('导入成功')
} catch (error) {
ElMessage.error('解析XML文件失败')
console.error(error)
}
}
// 开始读取文件
reader.readAsText(file)
return false
}
XML节点与表单字段的映射关系:
表单字段 | XML节点名称 | 示例XML结构 |
---|---|---|
ftpAddress | tbFTPPXGC | <c name="tbFTPPXGC" value="ftp.example.com"/> |
username | tbFTPPXGCUser | <c name="tbFTPPXGCUser" value="admin"/> |
password | tbFTPPXGCPassWord | <c name="tbFTPPXGCPassWord" value="123456"/> |
send | cbFTPPXGC | <c name="cbFTPPXGC" value="1"/> → 转换为 "Y" |
、数据绑定原理
- 响应式数据:使用Vue 3的
ref
创建响应式对象formData
- 结构对应:
formData.value.ftpInfoList = [ { ftpSvrType: '平行观测数据', ... }, { ftpSvrType: '气溶胶数据', ... }, // ...其他类型配置 ]
- 模板绑定:在模板中(虽然代码未完整展示),通常会通过
v-model
绑定到表单输入框,例如:<el-input v-for="(item, index) in formData.ftpInfoList" :key="index" v-model="item.ftpAddress" />
五、辅助函数解析
function getXmlValue(xmlDoc, name) {
const node = xmlDoc.querySelector(`c[name="${name}"]`)
return node ? node.getAttribute('value') : ''
}
作用:从XML文档中查询指定name属性的节点,返回其value属性值
六、完整流程
- 用户点击"导入(XML)"按钮
- 选择符合要求的XML文件
- 前端读取并解析XML文件
- 提取关键配置参数
- 构造新的ftpInfoList数组
- 更新响应式数据formData.value.ftpInfoList
- Vue自动触发视图更新,表单输入框显示最新数据
七、技术亮点
- 文件处理:使用FileReader API实现前端文件读取
- XML解析:通过DOMParser解析XML结构
- 响应式更新:利用Vue 3的ref实现数据双向绑定
- 错误处理:完善的类型校验和异常捕获机制
- 数据转换:将XML中的"1"/"0"转换为"Y"/"N"等业务逻辑处理
这种方式实现了配置数据的快速导入和可视化编辑,避免了手动输入的繁琐,同时保证了数据类型和格式的正确性。