记录vue响应式追踪次数过多报错

92 阅读1分钟

在一次表格渲染中,将表格的某一列全部都使用ant design的ToolTip组件时,使用了响应式数据绑定显示title。这些响应式数据都是通过方法来实现的。相当于每行的一个数据使用了几次,一个表格可视窗口渲染了十行,这就是渲染了几十次,而鼠标移动到某行数据触发ToolTip时必然会经过其他行,每一次都是几次,最多又渲染了几十次,而鼠标可能会上下晃动,又会触发n次,短短的时间内,顺便触发100+次,瞬间超过了vue响应式追踪次数,一下就触发了无数警告,生产环境会造成页面卡死。
解决方法,将方法中的响应式数据替换成静态数据。

 <a-tooltip v-if="(record['status'] === 'Completed' && record['standard'] == '0') || getCloudRoomConfirmTips(record)" overlayClassName="ant-tooltip-no-bg">
  <template #title>
    <div class="ant-tooltip-inner-content" v-if="getExpiredRoomTips(record)">
      <p>{{ getTipsStatusAndTitle('expiration', record).TipsTitle }}</p>
      {{ getExpiredRoomTips(record) }} 
      <span v-if="getTipsStatusAndTitle('expiration', record).TipsStatus === 'reminder'"></span>
    </div>
    <div class="ant-tooltip-inner-content" v-if="getCloudRoomConfirmTips(record)">
      <p>{{ getTipsStatusAndTitle('confirm', record).TipsTitle }}</p>
      {{ getCloudRoomConfirmTips(record) }}
    </div>
  </template>
  <InfoCircleFilled :class="getTipsStatusAndTitle('expiration', record).TipsStatus + '-icon'" v-if="getExpiredRoomTips(record)"></InfoCircleFilled>
  <WarningFilled :class="getTipsStatusAndTitle('confirm', record).TipsStatus + '-icon'" v-if="getCloudRoomConfirmTips(record)"></WarningFilled>
</a-tooltip>
export const getTipsStatusAndTitle = (type, record) => {
  let TipsTitle = ''
  let TipsStatus = ''
    const confirmTime = record['confirm_time']
    let diffDay = dayjs(new Date()).diff(confirmTime, 'day')
    if ( diffDay >= 83 && diffDay <= 90 ) {
      TipsTitle = ToolTipTitleMap['confirmReminder']  
      TipsStatus = TipsStatusMap['reminder']  
    } else if( diffDay > 90 ){
      TipsTitle = ToolTipTitleMap['confirmNotification']
      TipsStatus = TipsStatusMap['notification']  
    }
  

原先: title中使用到了getCloudRoomConfirmTips(record), getExpiredRoomTips(record)两个方法,在这两个方法中都是返回局部变量tips的。为了获取另外两个数据TipsTitle,TipsStatus,我将这两个数据定义为全局响应式变量,在上面两个方法的处理逻辑中改变。因此这两个方法只要一调用就会触发响应式追踪。
解决方法: 将getExpiredRoomTips(), getExpiredRoomTips(), getTipsStatusAndTitle()这几个方法内部都用静态变量来处理,去除响应式变量的做法,就算方法被调用很多次,静态变量也不会触发响应式追踪。