如何控制Vue中计算属性刷新,当其依赖的状态在指定范围内变化是不重新计算(节约性能)

需求

今天遇到一个需要,地图中有将近几万个坐标点,当地图视野被缩放到指定大小(<14)范围内时,对所有坐标点按区域进行分组,标签重新渲染每个区域的密度最高点。

遇到的问题

由于地图缩放是一个过渡的过程(类似于浏览器滚动,会多次触发微小的变化来实现过渡),
每当地图缩放一次后,都会重新计算坐标点(无论是在指定范围类变化还是在范围之间变化),
这样就造成了大量的性能问题(我骁龙865都明显感觉到不流畅了,毕竟几万条数据)

希望的结果是当数据在14以下的范围内或者在<=14的范围内变化时才会重新计算

解释案例

以下是一个例子

<template >
  <div id="app" >
    num:{{num}} <button @click="num++">+1</button> <button @click="num--">-1</button>
    {{result}}
  </div >
</template >

<script >
  export default {
    data() {
      return {
        num: 0
      }
    },
    computed: {
      result() {
        console.log("result更新了");
        if(this.num>14){
          return "a"
        }else {
          return "b"
        }
      }
    }
  }
</script >

看起来很符合逻辑性的一段代码,当num>14是改变计算属性的返回值
但是看一下控制台,每当num变化一次,result都会被更新,这就是一个性能问题

解决方案

了解vue的人都知道,计算属性变化的条件是:当计算属性依赖的其他状态发生变化时,会重新计算结果。

所以这里num是一直变化的,必然会不断的触发result重新计算。

解决的方法是:新建一个变量,当num在两个范围之间变化时才改变这个新建变量,然后result中依赖这个新建的变量即可。

export default {
    data() {
      return {
        num: 0,
        numState: false//+
      }
    },
    computed: {
      result() {
        console.log("result更新了");
        if(this.numState){//+
          return "a"
        }else {
          return "b"
        }
      }
    },
    watch:{//+
      num(v){//+
        this.numState = v>14;//+
      }//+
    }//+
  }

tip

当你使用methods中的方法的结果作为计算属性使用时,是无法控制methods中的方法更新的,即无法使用此方法控制method刷新。只要当methods中依赖的状态在可能被改变时(例如b方法中依赖了A状态,a方法中可能在某些条件下对A进行修改,即使新值与旧值相同)都会触发该方法重新计算

话不多说,来一个案例一下使用方法尽量避免

<template >
  <div id="app" >
    num:{{num}} <button @click="num++">+1</button> <button @click="num--">-1</button>
    {{result()}}
  </div >
</template >

<script >
  export default {
    data() {
      return {
        num: 0,
        numState: false//+
      }
    },
    methods: {
      result() {
        console.log("result更新了");
        if(this.numState){//+
          return "a"
        }else {
          return "b"
        }
      }
    },
    watch:{//+
      num(v){//+
        this.numState = v>14;//+
      }//+
    }//+
  }
</script >

我丢,看完了就赶快加入讨论群:365399843

Logo

前往低代码交流专区

更多推荐