URL参数解析全流程详解 URL 参数解析说明需求系统支持三种方式从 URL 中传递数据按优先级依次尝试。分别是?programId — 查询参数传递节目 ID例如 ?programId2200通过 /promotion/program/get 接口获取全部页面数据?data — 查询参数传递 JSON 配置例如 ?data{“qrCode”:“xxx”,“swaperList”:[“img1.jpg”]}绕过 API 直接覆盖页面内容Pathname路径参数 — URL 路径最后一段例如 /proTemp1/ABC提取 ABC 作为备用方案解析流程┌──────────────────────────────────────────────────┐ │ 用户访问 URL │ │ http://localhost:5173/proTemp1?programId123 │ └────────────────────┬─────────────────────────────┘ │ ▼ ┌─────────────────────────┐ │ parseUrlParam() │ │ 按优先级依次读取 │ └──────────┬──────────────┘ │ ┌─────────┴─────────┐ ▼ ▼ ┌──────────┐ ┌──────────────────┐ │ ?data │ │ ?programId │ │ JSON配置 │ │ 节目ID │ │ 高优先级 │ │ 中优先级 │ └────┬─────┘ └────────┬─────────┘ │ │ ▼ ▼ ┌──────────────────────────────┐ │ 最后回退: pathname │ │ /proTemp1/ABC → ABC │ └──────────────────────────────┘第一步从 URL 中提取参数在src/composables/useDeviceData.ts中调用parseUrlParam()优先级优先级来源示例 URL提取的值1?programId?programId1231232?data?data{qrCode:...}{qrCode:...}3pathname 最后一段/proTemp1/ABCABC// 源码useDeviceData.tsexportfunctionparseUrlParam():string|null{// 优先读 programId查询参数constpnewURLSearchParams(location.search).get(programId)if(p)returnp// 其次读 data查询参数传递 JSON 配置constqnewURLSearchParams(location.search).get(data)if(q)returnq// 最后从路径中取returnwindow.location.pathname.split(/).filter(Boolean).pop()||null}第二步判断参数类型拿到原始参数后判断是 JSON 配置还是节目 IDconsturlRawDataparseUrlParam()// 拿到原始字符串consturlJsonConfigurlRawData?tryParseJsonConfig(urlRawData):null// 尝试解析 JSON方案 AJSON 配置模式当 URL 携带?data{qrCode:xxx,swaperList:[img1.jpg,img2.mp4]}时exportfunctiontryParseJsonConfig(raw:string):{qrCode:string;swaperList:string[]}|null{try{constconfigJSON.parse(raw)// 尝试解析 JSONif(config.qrCodeArray.isArray(config.swaperList)){return{qrCode:config.qrCode,swaperList:config.swaperList}}}catch{}// 解析失败说明不是 JSON返回 nullreturnnull}JSON 模式直接覆盖页面数据不再调用 APIswaperList→ 轮播图列表qrCode→ 二维码图片方案 B节目 ID 模式当参数不是 JSON 时例如?programId123作为节目 ID 存储setDeviceId(urlRawData)// 存储到 deviceId.ts第三步ID 传递到 API3.1 存储 ID存储在src/utils/deviceId.ts中letdeviceIdexportfunctionsetDeviceId(id:string){deviceIdid}exportfunctiongetDeviceId():string{returndeviceId}3.2 请求拦截器自动附加在src/utils/request.ts的 Axios 拦截器中每次请求自动带上id参数service.interceptors.request.use((config){constdeviceIdgetDeviceId()if(deviceId){config.params{...config.params,id:deviceId// 自动附加到所有 API 请求}}returnconfig})例如请求/promotion/program/get时实际发出GET /admin-api/promotion/program/get?id1233.3 发起数据请求在页面onMounted时调用fetchAllDeviceData()asyncfunctionfetchAllDeviceData(){constdeviceIdgetDeviceId()if(!deviceId)return// 没有节目 ID 就不请求constresawaitrequest.get({url:/promotion/program/get})constdres.data// 将接口返回的字段映射到页面组件mediaData.valuetoArray(d.headerBannerUrls)// → 轮播图textData.value[d.remark]// → 滚动文字qrCodeData.valued.qrcodeUrl// → 二维码musicData.valuetoArray(d.audioUrls)[0]// → 背景音乐bgImage.valued.baseMapUrl// → 背景图}路由说明src/router/index.ts中路由配置支持可选参数{path:/:deviceId?,name:Display,component:...}{path:/proTemp1/:deviceId?,name:proTemp1,component:...}{path:/proTemp2/:deviceId?,name:proTemp2,component:...}:声明动态参数?表示可选不传时也匹配路由但目前的parseUrlParam()优先从查询参数取programId所以路径段中的 deviceId 只在极少数情况下被用到。完整流程示例用户访问http://localhost:5173/proTemp1?programId2200路由匹配 → 渲染proTemp1/Index.vueparseUrlParam()→?programId2200→ 返回2200tryParseJsonConfig(2200)→ 解析 JSON 失败 → 返回null不是 JSON 模式 →setDeviceId(2200)onMounted→fetchAllDeviceData()请求拦截器自动附加 →GET /admin-api/promotion/program/get?id2200获取数据 → 映射到各页面组件数据格式处理接口返回的字段可能为逗号分隔的字符串或数组用toArray()统一处理functiontoArray(data:string|string[]):string[]{if(Array.isArray(data))returndata.filter(Boolean)// 已经是数组returndata?data.split(,).map(ss.trim()).filter(Boolean):[]// 逗号拆分}