web-dev-qa-db-fra.com

vue js regarder plusieurs propriétés avec un seul gestionnaire

Actuellement, je dois regarder quelques propriétés. Et si chacun d'entre eux change, je dois invoquer la même fonction:

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

Je dois donc écrire le même code plusieurs fois au-dessus de ... .. Est-il possible simplement de surveiller toutes les propriétés et d’appeler leur gestionnaire de modification sans avoir à écrire le même code plusieurs fois?

PS: J'utilise la vue 1.x

6
rahulserver

il n’existe aucun moyen officiel de résoudre votre question ( voyez ceci ). mais vous pouvez utiliser la propriété calculée comme une astuce:

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

si vous voulez juste faire quelque chose et ne vous souciez pas de ce qui est nouveau/ancien valeurs. ignorer deux lignes

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

Premièrement, votre définition pourrait être simplifiée. doSomething ne semble pas être une méthode sur le Vue, votre montre pourrait donc simplement être

watch:{
    propa: doSomething,
    propb: doSomething
}

Deuxièmement, il est parfois important de se rappeler que les objets de définition Vue sont simplement des objets javascript. Ils peuvent être manipulés.

Si vous voulez regarder chaque propriété dans votre objet de données, vous pouvez faire quelque chose comme ceci

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)

Si vous ne souhaitez visionner qu'une liste définie de vos propriétés:

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

Une autre possibilité:

new Vue({
  el: '#app',
  data: {
    name: 'Alice',
    surname: 'Smith',
    fullName: '' // this should be a computed!! but bear with me, it's just a demo
  },
  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>

1
acdcjunior