2
votes

Définition de la propriété d'objet imbriqué par chemin de chaîne

J'ai 3 boîtes de sélection et j'aimerais qu'elles réinitialisent un certain champ lors de la sélection. Comment puis-je le rendre dynamique, afin qu'il soit réutilisable?

Voici un extrait de mon code:

v-on:select="getDate('{{ route('api.v1.get.date') }}', 'input1', ['form.company.input2', 'form.company.input3'], $event)"

getDate(url, obj, obj2, event){

     let current = this

     current[obj] = ''
     current[obj2[0]] = ''
     current[obj2[1]] = ''

}

Quand obj est à la niveau racine de l'instance de Vue (c'est-à-dire current [obj] ), il définit la propriété correctement; mais pas lorsque obj est un objet imbriqué.


0 commentaires

3 Réponses :


2
votes

Essayez d'utiliser la fonction this. $ set comme suit:

  this.$set(current,obj,'');
 this.$set(current,obj2[0],'');
 this.$set(current,obj2[1],'');

en savoir plus sur cette fonction ici


3 commentaires

Il semble que je rencontre cette erreur lors de l'utilisation de la méthode set, les données ont déjà été définies mais j'obtiens toujours cette erreur "[Vue warn]: évitez d'ajouter des propriétés réactives à une instance Vue ou à ses données racine $ au moment de l'exécution - déclarez-le dès l'option de données. "


current [obj] est passé via les accessoires?


la fonction est dans le même cas, je l'ai passée sur v-select "form.company.input2"



3
votes

En JavaScript, accesseurs de propriété a> n'autorisez pas les chemins d'objet imbriqués, ce que vous avez dans la chaîne séparée par des points. En utilisant cette chaîne, vous créez en fait une propriété sur l'instance racine de Vue au lieu de définir une propriété imbriquée, similaire à ceci:

<script src="https://unpkg.com/lodash@4.17.11/lodash.js"></script>
<script src="https://unpkg.com/vue@2.6.10"></script>

<div id="app">
  <input v-model="input1">
  <input v-model="form.company.input2">
  <input v-model="form.company.input3">

  <button @click="getDate(route('api.v1.get.date'), 'input1', ['form.company.input2', 'form.company.input3'], $event)">
    Reset data
  </button>
</div>

Pour définir la valeur de l'objet par chemin, vous pouvez créer une méthode qui utilise le chemin de l'objet pour parcourir les propriétés de données de l'instance Vue actuelle via this:

new Vue({
  el: '#app',
  data() {
    return {
      input1: 'input1',
      form: {
        company: {
          input2: 'input2',
          input3: 'input3'
        }
      }
    }
  },
  methods: {
    getDate(url, obj, obj2, event) {
      _.set(this, obj, '')
      _.set(this, obj2[0], '')
      _.set(this, obj2[1], '')
    },
    route(prop) {
      return prop
    }
  }
})

methods: {
  getDate(url, obj, obj2, event) {
    _.set(this, obj, '')
    _.set(this, obj2[0], '')
    _.set(this, obj2[1], '')
  }
}
<script src="https://unpkg.com/vue@2.6.10"></script>

<div id="app">
  <input v-model="input1">
  <input v-model="form.company.input2">
  <input v-model="form.company.input3">

  <button @click="getDate(route('api.v1.get.date'), 'input1', ['form.company.input2', 'form.company.input3'], $event)">
    Reset data
  </button>
</div>

Vous pouvez également utiliser une bibliothèque (telle que _.set ):

new Vue({
  el: '#app',
  data() {
    return {
      input1: 'input1',
      form: {
        company: {
          input2: 'input2',
          input3: 'input3'
        }
      }
    }
  },
  methods: {
    getDate(url, obj, obj2, event) {
      this.setValue(obj, '')
      this.setValue(obj2[0], '')
      this.setValue(obj2[1], '')
    },
    setValue(path, value) {
      let obj = this
      const parts = path.split('.')
      while (parts.length > 1 && obj.hasOwnProperty(parts[0])) {
        obj = obj[parts.shift()]
      }
      obj[parts[0]] = value
    },
    route(prop) {
      return prop
    }
  }
})

methods: {
  getDate(url, obj, obj2, event) {
    this.setValue(obj, '')
    this.setValue(obj2[0], '')
    this.setValue(obj2[1], '')
  },
  setValue(path, value) {
    let obj = this
    const parts = path.split('.')
    while (parts.length > 1 && obj.hasOwnProperty(parts[0])) {
      obj = obj[parts.shift()]
    }
    obj[parts[0]] = value
  }
}
this['form.company.input2'] = ''  // XXX: creates `form.company.input2` prop
this.form.company.input2 = ''     // sets `input2`


1 commentaires

@KarlWong Pas de problème :)



0
votes

Cette bibliothèque vous permet d'utiliser des chemins d'objets imbriqués.

https: //www.npmjs.com/package/vue-data-object-path

Votre extrait ressemblerait à ceci:

v-on:select="getDate('{{ route('api.v1.get.date') }}', 'input1', ['form.company.input2', 'form.company.input3'], $event)"

getDate(url, obj, obj2, event){

     let current = this

     current.$op.set(obj, '')
     current.$op.set(obj2[0], '')
     current.$op.set(obj2[1], '')

}

p >


0 commentaires