1
votes

Vue: v-model non défini ou default / fallback

Est-il possible de définir une valeur par défaut pour une entrée sur la valeur d'un autre champ d'entrée au cas où elle serait laissée vide. Il semble que je ne puisse pas le spécifier dans les données ni dans l'attribut v-model:

<template>
    <div>
        <input type="number" v-model="font1 || 14"> <!-- gives error -->
        <input type="number" v-model="font2 || font1"> <!-- gives error -->
        <input type="number" v-model="font3 || font1"> <!-- gives error -->
    </div>
</template>

<script>
export default {
    data() {
        return {
            font1: 14,
            font2: this.font2 || this.font1, // this approach also gives error
            font3: this.font3 || this.font1 // this approach also gives error
        }
    }
}
</script>

Toute aide est la bienvenue. Merci.


2 commentaires

essayez-vous de définir une valeur par défaut de la variable (font1) ou du champ de saisie?


Salut @Daniel, je veux juste vous assurer que la première entrée n'est pas laissée vide et que les 2 autres seraient facultatives avec un retour à l'entrée de (font1), donc en fait aucune ne peut être vide, donc font1 aurait une valeur par défaut set, et font1 et font2 auraient la valeur font1 par défaut, et modéliseront cette police1 au cas où elle changerait et qu'elles ne seraient pas définies elles-mêmes. J'espère que cela a du sens.


3 Réponses :


1
votes

Vous pouvez utiliser un booléen défini sur false pour les éléments input 1 et input 2 et le mettre à jour sur true lorsqu'une valeur est saisie.

p >

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input type="number" v-model="font1">
  <input type="number" v-model="font2.value" @input="Chg(font2)">
  <input type="number" v-model="font3.value" @input="Chg(font3)">
</div>
new Vue({
  el: '#app',
  data: {
    font1: 14,
    font2: {
      value: 14,
      defined: false
    },
    font3: {
      value: 14,
      defined: false
    }
  },
  methods: {
    Chg(font) {
      if (font.value.length) {
        font.defined = true;
        return;
      }
      font.value = this.font1;
    }
  },
  watch: {
    font1() {
      if (this.font2.defined === false) this.font2.value = this.font1
      if (this.font3.defined === false) this.font3.value = this.font1
    }
  }
});


7 commentaires

Merci, dans ce cas, il héritera toujours des modifications apportées à la première entrée, mais je voudrais que la deuxième et la troisième soient autonomes, mais si rien ne leur est ajouté, hériter de la valeur de input1.


Devraient-ils hériter de input1 lors d'un événement particulier? (Au cas où ils seraient vides).


Salut @Quentin, ils devraient hériter au cas où ils seraient laissés vides (inchangés), si l'entrée 1 change, les deux autres devraient se mettre à jour en reflétant cette valeur, à moins qu'ils ne soient définis indépendamment avant ou après. J'espère que cela a du sens.


Presque, il semble que cette fois, les champs peuvent être laissés vides, ce que je veux éviter. Mais c'est comme 90% correct, donc je devrais être capable de comprendre ces derniers 10% :)


On dirait que les champs peuvent toujours être laissés vides, non?


En effet, c'est corrigé.


Merci beaucoup :)



1
votes

Vous devrez utiliser une combinaison de v-model et des getters et setters des propriétés calculées pour obtenir ce que vous voulez.

  1. Déclarez un magasin de données interne pour les polices, appelons f1 , f2 et f3 . Donnez à f1 votre valeur par défaut de 14:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <test />
    </div>
    <script type="text/x-template" id="test">
        <div>
            <input type="number" v-model.number="font1">
            <input type="number" v-model.number="font2">
            <input type="number" v-model.number="font3">
        </div>
    </script>
  2. Maintenant, lorsque le composant est monté, vous voudrez interpoler les valeurs en conséquence. Cela peut être fait dans le rappel vm.mounted () :

    Vue.component('test', {
      template: '#test',
      data: function() {
        return {
          f1: 14,
          f2: null,
          f3: null,
        };
      },
      mounted: function() {
        this.f2 = this.f2 || this.f1;
        this.f3 = this.f3 || this.f2;
      },
      computed: {
        font1: {
          set: function(val) {
            if (val)
              this.f1 = val;
          },
          get: function() {
            return this.f1;
          }
        },
        font2: {
          set: function(val) {
            this.f2 = val || this.f1;
          },
          get: function() {
            return this.f2;
          }
        },
        font3: {
          set: function(val) {
            this.f3 = val || this.f2;
          },
          get: function() {
            return this.f3;
          }
        }
      }
    });
    
    new Vue({ el: '#app' });
  3. La dernière étape consiste à configurer vos propriétés calculées, de sorte que chaque fois que font1 , font2 ou font3 change, elles mettre à jour le magasin de données de police interne de manière appropriée:

    computed: {
      font1: {
        set: function(val) {
          if (val)
            this.f1 = val;
        },
        get: function() {
          return this.f1;
        }
      },
      font2: {
        set: function(val) {
          this.f2 = val || this.f1;
        },
        get: function() {
          return this.f2;
        }
      },
      font3: {
        set: function(val) {
          this.f3 = val || this.f2;
        },
        get: function() {
          return this.f3;
        }
      }
    }
    

Voir la preuve de concept ci-dessous:

mounted: function() {
  // f2 takes the value of f1, if itself is falsy
  this.f2 = this.f2 || this.f1;

  // f3 takes the value of f2, if itself is falsy
  this.f3 = this.f3 || this.f2;
}
data: function()  {
  return {
    f1: 14,
    f2: null,
    f3: null,
  };
}


1 commentaires

merci, le seul problème avec ceci est que par défaut les entrées 2 et 3 sont `` vides '' et héritent de la valeur de l'entrée 1, si l'entrée 1 est modifiée -> les entrées 2 et 3 héritent également de la valeur mise à jour, sauf si elles ont été modifiées indépendamment. C'est un peu déroutant, je crois.



2
votes

Il existe probablement 37 façons différentes de le faire.

La question est de savoir ce qui est important, la robustesse, la maintenabilité, la facilité de mise en œuvre, l'évolutivité etc.

Voici une solution qui priorise la facilité de mise en œuvre . Il repose sur l'utilisation de @change et : value au lieu de la magie v-model .

Cela laissera font2 et font3 comme nulles si elles ne sont pas modifiées.

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <input type="number" v-model="font1">
  <input type="number" @change="font2 = $event.target.value" :value="isNumber(font2)?font2:font1">
  <input type="number" @change="font3 = $event.target.value" :value="isNumber(font3)?font3:font1">
<pre>{{ {font1:font1, font2:font2, font3:font3} }}</pre>
</div>
new Vue({
  el: '#app',
  data: {
    font1: 14,
    font2: null,
    font3: null,
  },
  methods: {
    isNumber(n) { return !isNaN(parseFloat(n)) && !isNaN(n - 0) }
  }
});


3 commentaires

Mais dans ce cas, les champs peuvent être laissés vides, si le champ est laissé vide, il devrait être remis par défaut à la valeur d'entrée 1. C'est probablement parce qu'il renvoie une chaîne vide qui n'est pas égale à null.


réponse mise à jour pour inclure la valeur d'effacement à l'aide de la méthode isNumber


Oui, c'est certainement l'une des 37 façons d'y parvenir, merci :)