项目复盘之实用小妙招

305 阅读3分钟

前言

对项目中遇到的问题做简要记录,为日后避坑。本次项目是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);
}

后记

每做一个项目都需要把项目中遇到的问题进行记录,复盘,既是为了巩固基础也是为以后避坑,当然面试中也用的到撒!持续更新,持续记录!