已知问题汇总.md
9.4 KB
已知问题汇总
最后更新: 2026-02-09 目的: 记录项目中的已知问题和解决方案,避免后续开发中重复踩坑
🔴 高优先级问题
1. 版本冲突
问题描述
项目中同时存在同一库的不同版本,可能导致兼容性问题。
具体案例
Photo Sphere Viewer:
// package.json
"photo-sphere-viewer": "^4.8.1",
"@photo-sphere-viewer/core": "^5.7.3",
影响:
- VR 全景功能可能不稳定
- 包体积增大
- API 不一致
解决方案:
// 统一使用 5.x 版本
// 1. 移除旧版本
npm uninstall photo-sphere-viewer
// 2. 更新导入语句
// 之前: import { Viewer } from 'photo-sphere-viewer';
// 之后: import { Viewer } from '@photo-sphere-viewer/core';
日期管理库:
// package.json
"dayjs": "^1.11.3",
"moment": "^2.29.3",
影响:
- 包体积增大
- API 不一致
解决方案:
// 统一使用 dayjs(更轻量)
// 1. 移除 moment
npm uninstall moment
// 2. 替换所有 moment 调用为 dayjs
// moment(date).format('YYYY-MM-DD')
// → dayjs(date).format('YYYY-MM-DD')
2. Keep-Alive 缓存问题
问题描述
keepPages 空数组会导致所有页面都被缓存。
具体案例
// src/store/index.js:25
keepPages: ['default'], // 很坑爹,空值全部都缓存
影响:
- 如果
keepPages为[],所有页面都会被缓存 - 页面状态不会重置
- 可能导致内存泄漏
解决方案:
// ✅ 正确:至少包含 'default' 作为占位符
keepPages: ['default']
// ❌ 错误:空数组
keepPages: [] // 会导致所有页面都被缓存
使用方法:
// 添加需要缓存的页面
const keepThisPage = () => {
const keepPages = [...mainStore.keepPages];
if (!keepPages.includes('PageName')) {
keepPages.push('PageName');
}
mainStore.keepPages = keepPages;
};
3. 路由 Hash 模式
问题描述
项目使用 Hash 模式,所有路由必须包含 #/index.html 前缀。
具体案例
// src/router/index.js
history: createWebHashHistory('/index.html')
影响:
- URL 格式:
http://localhost:8006/index.html#/index.html/views/page - 如果忘记前缀,路由无法匹配
解决方案:
// ✅ 正确:使用完整路径
router.push('/index.html/views/page')
// ❌ 错误:缺少前缀
router.push('/views/page')
// ✅ 推荐:使用路由名称
router.push({ name: 'PageName' })
🟡 中优先级问题
4. jQuery 依赖
问题描述
项目仍使用 jQuery,与 Vue 3 冲突。
具体案例
// src/components/VRViewer/index.vue:23
import $ from 'jquery';
// 使用 jQuery 操作 DOM
$('.psv-zoom-button').css('display', '');
影响:
- 不符合 Vue 3 理念
- 性能较差
- 不利于维护
解决方案:
// ❌ 错误:使用 jQuery
import $ from 'jquery';
$('.psv-zoom-button').css('display', '');
// ✅ 正确:使用 Vue 原生 API
import { ref, onMounted } from 'vue';
const zoomButton = ref(null);
onMounted(() => {
if (zoomButton.value) {
zoomButton.value.style.display = '';
}
});
迁移优先级:
- 新代码避免使用 jQuery
- 逐步重构现有 jQuery 代码
- 最终完全移除 jQuery 依赖
5. 全局样式注入
问题描述
Less 配置中全局注入 base.less,所有组件都会包含全局样式。
具体案例
// vite.config.js:107
additionalData: `@import "${path.resolve(__dirname, 'src/assets/styles/base.less')}";`
影响:
- 所有
.vue文件中的<style lang="less">都会包含全局样式 - 可能导致样式冲突
- 编译时间增加
解决方案:
/* ✅ 推荐:仅在需要时导入 */
@import './base.less';
/* ❌ 不推荐:重复导入 */
/* base.less 已经全局注入,无需重复导入 */
6. SVG 渲染性能
问题描述
复杂 SVG 可能导致渲染卡顿。
具体案例
<!-- src/components/Floor/index.vue -->
<div v-html="level.svg"></div>
影响:
- 楼层平面图 SVG 可能很复杂
- 渲染时间长
- 可能导致页面卡顿
解决方案:
// 1. 简化 SVG 路径
// 2. 使用懒加载
const loadFloorSVG = async (level) => {
const { data } = await mapAPI({ id: locationId, level });
return data.svg;
};
// 3. 使用 will-change 优化
.floor-svg {
will-change: transform;
}
7. XSS 风险
问题描述
使用 v-html 渲染 SVG 可能存在 XSS 风险。
具体案例
<div v-html="level.svg"></div>
风险:
- 如果 SVG 来自用户输入或不可信来源
- 可能包含恶意脚本
解决方案:
// 安装 DOMPurify
npm install dompurify
// 清理 SVG
import DOMPurify from 'dompurify';
const cleanSVG = DOMPurify.sanitize(svgString);
🟢 低优先级问题
8. 代码重复
问题描述
多个页面中存在重复的代码模式。
具体案例
信息窗口组件:
InfoWindowLite.vueInfoWindowWarn.vueInfoWindowYard.vueInfoPopupLite.vueInfoPopupWarn.vue
影响:
- 维护成本高
- 代码重复
解决方案:
// ✅ 推荐:合并为一个组件,使用 props 控制样式
<InfoWindow
:variant="'lite' | 'warn' | 'yard'"
:title="title"
:description="description"
/>
// ❌ 不推荐:维护多个相似组件
<InfoWindowLite :title="title" />
<InfoWindowWarn :title="title" />
<InfoWindowYard :title="title" />
9. 缺少类型定义
问题描述
项目使用 TypeScript,但缺少完整的类型定义。
具体案例
// src/auto-imports.d.ts(自动生成)
// 但很多组件和函数缺少类型定义
影响:
- IDE 提示不完整
- 容易出现类型错误
- 不利于重构
解决方案:
// 为组件添加类型定义
// src/components/Floor/index.vue
interface FloorData {
svg: string;
pin: PinData[];
}
interface PinData {
category: string;
space: string;
icon: string;
style: Record<string, string>;
info?: InfoData;
}
10. 测试覆盖不足
问题描述
项目缺少完整的测试覆盖。
具体案例
// src/test/mocha/test.js(仅有一个测试文件)
影响:
- 重构时容易引入 Bug
- 难以保证代码质量
解决方案:
// 补充单元测试
// tests/components/Floor.spec.js
import { mount } from '@vue/test-utils';
import { describe, it, expect } from 'vitest';
import Floor from '@/components/Floor/index.vue';
describe('Floor', () => {
it('should render floor list', () => {
const wrapper = mount(Floor, {
props: {
levelList: [...],
},
});
expect(wrapper.findAll('.level').length).toBe(4);
});
});
⚠️ 注意事项
1. 环境变量
问题: 环境变量必须以 VITE_ 开头
// ✅ 正确
VITE_PORT=8006
VITE_PROXY_TARGET=http://api.example.com
// ❌ 错误
PORT=8006
PROXY_TARGET=http://api.example.com
2. 路径别名
问题: 使用路径别名时必须使用绝对路径
// ✅ 正确
import Floor from '@components/Floor/index.vue';
// ❌ 错误
import Floor from '../../components/Floor/index.vue';
3. 组件命名
问题: 组件文件名必须使用 PascalCase
// ✅ 正确
audioList.vue
InfoWindowLite.vue
VRViewer/index.vue
// ❌ 错误
audio-list.vue
infoWindowLite.vue
vr-viewer/index.vue
4. API 响应检查
问题: 所有 API 调用必须检查 res.code === 1
// ✅ 正确
const { data } = await mapAPI(params);
if (res.code === 1 && res.data) {
// 处理数据
}
// ❌ 错误
const { data } = await mapAPI(params);
if (data) {
// res.code 未检查,可能处理错误数据
}
5. 异步错误处理
问题: 所有 async 函数必须有 try-catch
// ✅ 正确
const fetchData = async () => {
try {
const { data } = await mapAPI(params);
return data;
} catch (err) {
console.error('请求失败:', err);
return null;
}
};
// ❌ 错误
const fetchData = async () => {
const { data } = await mapAPI(params);
return data;
// 错误未处理,可能导致应用崩溃
};
📝 待解决问题
1. 多页面应用配置未清理
问题: src/packages/ 目录存在但未使用
影响:
- 代码混乱
- 构建时间增加
建议: 归档或删除未使用的多页面应用代码
2. 文件历史目录
问题: .history/ 目录存在
影响:
- Git 仓库混乱
- 磁盘空间浪费
建议: 添加到 .gitignore
3. 控制台调试代码
问题: 项目中可能存在 console.log 和 debugger
影响:
- 生产环境性能
- 可能泄露敏感信息
建议: 使用 ESLint 检测并移除调试代码
4. 图片优化
问题: 图片未压缩和优化
影响:
- 加载速度慢
- 流量消耗大
建议:
- 使用 WebP 格式
- 压缩图片
- 使用 CDN 优化