前言
对项目中遇到的问题做简要记录,为日后避坑。本次项目是vue3 + antdesign + vite
遇到的问题
用户登录以后界面卡死
通过代码分析,发现登录页面,对密码输入框绑定了keyup.enter事件,在回车登录时候同时触发本次绑定 事件以及表单提交finsh事件,导致触发两次重复请求,第二次重复请求未得服务器响应,导致浏览器页面卡死。
<a-form
:model="loginForm"
:rules="loginRules"
@finish="handleFinish"
>
<a-form-item name="password">
<a-input-password
clearable
v-model:value="loginForm.password"
placeholder="密码"
autocomplete="on"
@keyup.enter.native="handleFinish"
/>
</a-form-item>
</a-form>
解决方案:不用重复绑定enter事件,ant的表单组件自带该功能,回车以后会触发表单的finsh事件,因此我们只要删除input上绑定的事件即可。
图表组件echarts第一次渲染,再次进入不渲染
图表组件echart在首次初始化的时候会给容器加上_echarts_instance_属性,作为唯一id,当页面被缓存时候,从其他页面再次进入的时候如果没有清除该id,会导致图表空白,开发环境没有该问题,打包后会有此问题。
const chartdom= document.getElementById("main");
chartdom.removeAttribute("_echarts_instance_");
const myChart = echarts.init(chartdom);
myChart.setOption(option)
解决方案:在初始化之前先清除父容器的id。
基于echarts实现的图表不显示toolTip控件
从官网上cv过来的示例可以正常显示,用vue3的方式改造后就不显示
解决方案:echarts实例在vue3中不能为响应式对象。因此从这方面入手,有三种解决方案。
//方案一:不把echarts实例进行代理
const chartdom= document.getElementById("main");
const myChart = echarts.init(chartdom);
myChart.setOption(option);
//方案二:echarts实例用shallowRef包裹
const chartdom= document.getElementById("main");
const mychart = shallowRef(null);
nextTick(() => {
mychart.value = echarts.init(chartdom);
myChart.setOption(option);
})
//方案三:在reactive中用markRaw将echarts实例标记为不可被转为代理的对象
const chartReactive = reactive({
mychart:null
});
const chartdom= document.getElementById("main");
chartReactive.mychart = markRaw(echarts.init(chartdom));
chartReactive.myChart.setOption(option);
echarts图表渲染的数据和服务器不符,包含历史数据
如题,因为没有清除画布的数据,渲染的时候会包含历史数据,导致渲染异常
//数据改变后先清空画布数据再去初始化echarts
chartReactive.myChart?.clear();
initEchart();
解决方案:数据改变后先清空画布数据再去初始化echarts
antdesign的a-cascader回显问题
项目中后端只会返回最子级的id,父级链路没有,但是cascader必须要是全链路的id组成的数组才能正常显示
{
id:'1',
name:'祖父',
children:[
{
id:'1-1',
name:'父亲',
children:[
{
id:'1-1-1',
name:'孙子',
}
]
}
]
}
解决方案:后端只返回'1-1-1',导致控件展示'1-1-1',期望展示 祖父/父亲/孙子这个时候期望数据是 ['1','1-1','1-1-1'] 这样控件才会正常展示,为了解决该问题,我们需要一个函数根据指定id返回全链路的id数组
//完整的节点数组
let emitPathNodes = [];
function _getParentNodesArr(history, targetId, tree) {
tree.some((item) => {
const children = item.children || [];
if (item.id == targetId) {
emitPathNodes = history;
emitPathNodes.push(item);
return true;
} else if (children?.length) {
const his = [...history];
his.push(item);
return _getParentNodesArr(his, targetId, children);
}
});
}
function getParentNodesArr(id, tree) {
_getParentNodesArr([], id, tree);
return emitPathNodes.map((o) => o.id);
}
后记
每做一个项目都需要把项目中遇到的问题进行记录,复盘,既是为了巩固基础也是为以后避坑,当然面试中也用的到撒!持续更新,持续记录!