vue js使用单个处理程序监视多个属性

rah*_*ver 15 vue.js vue-loader

目前我要看几个属性.如果每个都改变了,我必须调用相同的函数:

export default{
    // ...... rest of code 
    watch: {
      propa: function(after,before) {
         doSomething(after,before);
      },
      propb: function(after,before) {
         doSomething(after,before);
      }
      // ... so on
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我不得不多次编写相同的代码.是否可以简单地监视所有属性并调用其更改处理程序而无需多次编写相同的代码?

PS:我正在使用vue 1.x.

gol*_*ree 19

像这样:

data() {
  return {
    propa: '',
    propb: ''
  }
},
computed: {
  changeData() {
    const { propa, propb } = this
    return {
      propa,
      propb
    }
  }
},
watch: {
  changeData: {
    handler: function(val) {
      console.log('value change: ', val)
    },
    deep: true
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 您只需返回要跟踪的项目数组即可。`changeData() { 返回 [this.propa, this.propb] }` (3认同)
  • 这是最好的答案。保留类型并且无需 this.$watch 即可简单实现。数组也可以工作,但是通过返回一个对象,您可以保持每个属性的名称完整,而不必依赖索引。 (2认同)

Yi *_*Xie 16

没有正式的方法来解决你的问题(见这个).但您可以使用计算属性作为技巧:

export default {
  // ...
  computed: {
    propertyAAndPropertyB() {
      return `${this.propertyA}|${this.propertyB}`;
    },
  },
  watch: {
    propertyAAndPropertyB(newVal, oldVal) {
      const [oldPropertyA, oldProvertyB] = oldVal.split('|');
      const [newPropertyA, newProvertyB] = newVal.split('|');
      // doSomething
    },
  },
}
Run Code Online (Sandbox Code Playgroud)

如果你只是想做某事而不关心什么是新的/旧的价值观.忽略两行

const [oldPropertyA, oldProvertyB] = oldVal.split('|');
const [newPropertyA, newProvertyB] = newVal.split('|');
Run Code Online (Sandbox Code Playgroud)

  • 截至您四月份的更新,我对使用这种方法很感兴趣,但无法找到文档,因为我无法获得正确的语法,只找到了 [v2](https://vuejs.org/v2 /api/#watch) 和 [v3](https://v3.vuejs.org/api/instance-methods.html#watch),但这些都没有显示我需要的语法。需要以下语法:`export default { watch:{ --watcher for multiple props here-- } }` (2认同)

acd*_*ior 6

另一种可能性:

new Vue({
  el: '#app',
  data: {
    name: 'Alice',
    surname: 'Smith',
    fullName: '' // IRL you would use a computed for this, I'm updating it using a watch just to demo how it'd be used
  },
  mounted() {
    this.$watch(vm => [vm.name, vm.surname], val => {
      
      this.fullName = this.name + ' ' + this.surname;
      
    }, {
      immediate: true, // run immediately
      deep: true // detects changes inside objects. not needed here, but maybe in other cases
    }) 
  }
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <div>
    name:<input v-model="name">
  </div>
  <div>
    surname:<input v-model="surname">
  </div>
  <div>
    full name: {{ fullName }}
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

有关的Vue API文档的vm.$watch更多信息。


Ber*_*ert 5

首先,您的定义可以简化。doSomething似乎不是 Vue 上的方法,因此您的手表可能只是

watch:{
    propa: doSomething,
    propb: doSomething
}
Run Code Online (Sandbox Code Playgroud)

其次,有时重要的是要记住 Vue 定义对象只是普通的 javascript 对象。它们可以被操纵。

如果您想查看数据对象中的每个属性,您可以执行以下操作

function doSomething(after, before){
  console.log(after,before);
}

function buildWatch(def){
  if (!def.watch)
    def.watch = {};
  for (let prop of Object.keys(def.data))
    def.watch[prop] = doSomething;
  return def;
}

let vueDefinition = {
  data:{
    propa: "testing",
    propb: "testing2",
    propc: "testing3"
  }
}

export default buildWatch(vueDefinition)
Run Code Online (Sandbox Code Playgroud)

如果您只想查看一些已定义的属性列表:

// First argument is the definition, the rest are property names
function buildWatch(def){
  if (!def.watch)
    def.watch = {};
  const properties = Array.prototype.slice.call(arguments,1); 
  for (let prop of properties)
    def.watch[prop] = doSomething;
  return def;
}

export default buildWatch(vueDefinition, "propa", "propb")
Run Code Online (Sandbox Code Playgroud)


Bin*_* Ho 5

对于 Vue typescript 你可以这样做。已测试。

  @Watch('varA')
  @Watch('varB')
  private oneOfAboveChanged(newVal) {
    console.log(newVal)
  }
Run Code Online (Sandbox Code Playgroud)


小智 5

我对 vue2 的决定:

export default {
  data() {
    return {
      status: null,
      name: null,
      date: null,
      mobile: null,
      page: 1,
    }
  },
  watch: {
    ...["status", "name", "date", "mobile", "page"].reduce((acc, currentKey) => {
      acc[currentKey] = (newValue) => {
        // doSomething
        // console.log(newValue, currentKey)
      }
      return acc
    }, {}),
  }
}
Run Code Online (Sandbox Code Playgroud)