Vue js отслеживает несколько свойств с помощью одного обработчика

В настоящее время мне нужно посмотреть несколько свойств. И если каждый из них изменяется, я должен вызвать ту же функцию:

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

Поэтому мне приходится писать один и тот же код несколько раз выше. Можно ли просто просматривать все свойства и вызывать их обработчик изменений без необходимости писать один и тот же код несколько раз?

PS: Я использую vue 1.x

Ответ 1

нет официального способа решить ваш вопрос (см.). но вы можете использовать вычисленное свойство как трюк:

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

если вы просто хотите что-то сделать и не заботитесь о том, какие новые/старые значения. игнорировать две строки

const [oldPropertyA, oldProvertyB] = oldVal.split('|');
const [newPropertyA, newProvertyB] = newVal.split('|');

Ответ 2

Другая возможность:

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
  }
});
<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>

Ответ 3

Во-первых, ваше определение может быть упрощено. doSomething не является методом на Vue, поэтому ваши часы могут быть

watch:{
    propa: doSomething,
    propb: doSomething
}

Во-вторых, иногда важно помнить, что объекты определения 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)

Если вы хотите посмотреть только определенный список своих свойств:

// 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")

Ответ 4

как это:

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
  }
}