工作感觉有坑点的第一个问题

102 阅读2分钟

工作感觉有坑点的第一个问题:

  1. 如果监听a的变化,然后再a变化之后需要更新一个东西
export default {
  watch: {
    a(newVal) {
      // update a
    }
  }
};
  1. 如果起初a会发生一次赋值,那么我们需要区分是否是第一次赋值, 那么我们使用isFirstChange来区分是不是第一次赋值
export default {
  data() {
    isFirstChange: false;
  },
  watch: {
    a(newVal) {
      if (!this.isFirstChange) {
        this.isFirstChange = true;
      } else {
        // update a;
      }
    }
  },
  created() {
    this.a = 'a1';
  }
};
  1. 如果需要监听a, b, c, d, e, 然后情况如 2, 并且在所有值发生变化之后,执行的update逻辑都是一样的,如果采用 2 的方式
export default {
  data() {
    isAFirst: false;
    isBFirst: false;
    isCFirst: false;
    isDFirst: false;
    isEFirst: false;
  },
  watch: {
    a(newVal) {
      if (!this.isAFirst) {
        this.isAFirst = true;
      } else {
        this.update()
      }
    },
    b(newVal) {
      if (!this.isBFirst) {
        this.isBFirst = true;
      } else {
        this.update()
      }
    },
    c(newVal) {
      if (!this.isCFirst) {
        this.isCFirst = true;
      } else {
        this.update()
      }
    },
    d(newVal) {
      if (!this.isDFirst) {
        this.isDFirst = true;
      } else {
        this.update()
      }
    },
    e(newVal) {
      if (!this.isEFirst) {
        this.isEFirst = true;
      } else {
        this.update()
      }
    }
  },
  methods: {
    update() {
      // run update 使用了 lodash.debounce
    }
  }
  created() {
    this.a = 'a1';
    this.b = 'b1';
    this.c = 'c1';
    this.d = 'd1';
    this.e = 'e1';
  }
};

上述代码写起来好像有点沙雕

  1. 上述只用类似于isAFirst这种东西,因为isAFirst值只可能有两个,所以我们需要监听几个变量,那么就要再添加几个变量,所以我们用一个数组flags来记录状态
export default {
  data() {
    return {
      a: '',
      b: '',
      c: '',
      d: '',
      e: '',
      flags: [] // 用来记录所有值的第一次赋值有没有结束
    };
  },
  watch() {
    a () {
      this._update()
    },
    b () {
      this._update()
    },
    c () {
      this._update()
    },
    d () {
      this._update()
    },
    e () {
      this._update()
    },
  },
  methods: {
    _update () {
      if (this.flags.length !== 5) {
        this.flags.push(1)
      } else {
        this.update()
      }
    }
    update() {
      // update 的逻辑, 使用了 lodash.debounce
    }
  },
  created() {
    this.a = 'a1';
    this.b = 'b1';
    this.c = 'c1';
    this.d = 'd1';
    this.e = 'e1';
  }
};
  1. 另一个问题又出现了,如果假设我们用了一个自定义组件,然后和a进行双向绑定,会将a的值格式化之后,然后赋值给a
<template>
  <div>
    {{b}} - {{c}} - {{d}} - {{e}}
    <comp v-model="a"></comp>
  </div>
</template>
export default {
  components: {
    comp //
  },
  data() {
    return {
      a: '',
      b: '',
      c: '',
      d: '',
      e: '',
      flags: [] // 用来记录所有值的第一次赋值有没有结束
    };
  },
  watch() {
    a () {
      this._update()
    },
    b () {
      this._update()
    },
    c () {
      this._update()
    },
    d () {
      this._update()
    },
    e () {
      this._update()
    },
  },
  methods: {
    _update () {
      if (this.flags.length !== 5) {
        this.flags.push(1)
      } else {
        this.update()
      }
    }
    update() {
      // update 的逻辑, 使用了 lodash.debounce
    }
  },
  created() {
    this.a = 'a1';
    this.b = 'b1';
    this.c = 'c1';
    this.d = 'd1';
    this.e = 'e1';
  }
};

上述虽然我们在created的时候给a赋值了,但是comp组件中会将a的内容格式化之后,然后会将a再次赋值,这就导致了a的监听器会多执行一次,所以导致即使我们只是在初始化的时候就会触发update

  1. 上述问题的解决方法呢?a会被多一次触发赋值是已知问题,那我们可以单独给a设置一个标志
<template>
  <div>
    {{b}} - {{c}} - {{d}} - {{e}}
    <comp v-model="a"></comp>
  </div>
</template>
export default {
  components: {
    comp //
  },
  data() {
    return {
      isAFirst: false;
      a: '',
      b: '',
      c: '',
      d: '',
      e: '',
      flags: [] // 用来记录所有值的第一次赋值有没有结束
    };
  },
  watch() {
    a () {
      this._update()
    },
    b () {
      this._update()
    },
    c () {
      this._update()
    },
    d () {
      this._update()
    },
    e () {
      this._update()
    },
  },
  methods: {
    _update () {
      if (this.isAFirst) {
        this.isAFirst = false
        return
      }
      if (this.flags.length !== 5) {
        this.flags.push(1)
      } else {
        this.update()
      }
    }
    update() {
      // update 的逻辑, 使用了 lodash.debounce
    }
  },
  created() {
    this.a = 'a1';
    this.isAFirst = true
    this.b = 'b1';
    this.c = 'c1';
    this.d = 'd1';
    this.e = 'e1';
  }
};

  1. 那么问题又来了,如果b, c, d, e如果都像a一样出现这样的情况,那么我们岂不是会产生类似于2的情况,那么我们岂不是🤡,后续有想其他的解决方案?持续优化中