不良的观察者执行顺序

时间:2020-10-25 10:07:19

标签: vuejs2

我有一个下拉组件,它具有两个道具:“ val”,“ options”(对象数组)。该组件由这些值“ locVal”和“ locOptions”的本地版本驱动,这些版本通过两个受公众关注的道具进行更新。

父级需要能够在任何时间以任何顺序提供“选项”数组和/或“ val”,并且我的观察者决定如何更新内部值,以便它们始终处于一致状态:

watch: {
  val() {
    // validate 'val' against 'locOptions' and set 'locVal' if match
  },
  options() {
    // validate 'locVal' against 'options' and leave 'locVal' alone
    // if still match otherwise set to null
    // also set 'locOptions' to 'options'           
  }
},

但是,Vue调用受监视函数的顺序存在问题。不会按照更改值的顺序来调用它们,而是按照声明的顺序来调用它们。

假定初始内部值:

locOptions = [
   { val: 1, text: 'one' },
   { val: 2, text: 'two' )
];
locVal = 1;
// parent sets the props in this order
val = 3;
options = [
   { val: 3, text: 'three' },
   { val: 4, text: 'four' )
];
// desired outcome
'locVal' should be null
'val' is set to mirror 'locVal' with two way binding

此处,“ val”首先与“ locOptions”匹配。它无法匹配,因此为了强制验证组件将“ locVal”和“ val”设置为null(如果没有匹配,则是唯一可行的值)。之后,当“选项”与“ locVal”匹配时,由于“空”对于新集合仍然是可行的值,因此将其单独保留为“ locVal”。

// setting the props in opposite order
options = [
   { val: 3, text: 'three' },
   { val: 4, text: 'four' )
];
val = 3;
// desired outcome
'locVal' should be 3
'val' is set to mirror 'locVal' with two way binding

在这种情况下,“选项”首先与“ locVal”匹配。由于“ 1”不在新列表中,因此它失败,因此“ locVal”和“ val”设置为null。然后将“ val”与“ locOptions”匹配。因此,它将“ locVal”和“ val”设置为3。

我如何让Vue观察这些道具进行更改以获得所需行为的顺序?

1 个答案:

答案 0 :(得分:0)

Vue为观看者提供了一个undocumented API,叫sync

它没有等待下一个滴答呼叫呼叫观察者,而是立即呼叫了他们。不建议这样做,如果使用不当,可能会导致无限循环。

watch: {
  val: {
    handler () {
      // validate 'val' against 'locOptions' and set 'locVal' if match
    },
    sync: true
  }, 
  options() {
    handler() {
      // validate 'locVal' against 'options' and leave 'locVal' alone
      // if still match otherwise set to null
      // also set 'locOptions' to 'options'           
    },
    sync: true
  }
},