1
votes

propriété de nom de balise non définie à l'aide de Vue mais accessible dans le navigateur

Actuellement, j'ai un sélecteur qui renvoie undefined lors de l'utilisation de Vue pour le {{lens.price}}. Mais lorsque j'utilise a = lens [1] .getAttribute ('price') dans la console du navigateur, j'obtiens la valeur renvoyée correcte de "0" .

Pourquoi Est-ce que Vue rend ces données renvoyées non définies? La propriété fonctionne correctement dans le navigateur sur toutes les options renvoyées par la boucle for.

Dois-je transmettre les deux propriétés à un nom de balise à valeur unique?

HTML / LIQUID:

    <div>
  <label for="lens"></label>
  <select id="lens" onchange="xIs()" name="line_items[lens]" @change="handleChange('lens', $event);"
    class="mt-3 option-selector text-sm lg:text-base uppercase block appearance-none w-full bg-white text-gray-900 py-3 px-4 pr-8 rounded-sm leading-tight focus:outline-none focus:border-black font-bold">
    <option>Choose a lens</option>
    {% for lens in collections.lenses.products %}
    <option value="{{ lens.price }}">{{ lens.title }} |
      {{ lens.price | plus: product.price | money_without_trailing_zeros}}</option>
    {% endfor %}
  </select>
</div>
<h1 id="demo"></h1>
<script>
 const xIs = () => {
  var x = document.getElementById("lens").value;
   document.getElementById("demo").innerHTML = `x is: ${x}`;
}

</script>

RÉPARTITION DE VUE: (CODE NON COMPLET)

<div>
    <label for="lens"></label>
    <select id="lens" onchange="myFunction()" name="line_items[lens]" @change="handleChange('lens', $event);"
      class="mt-3 option-selector text-sm lg:text-base uppercase block appearance-none w-full bg-white text-gray-900 py-3 px-4 pr-8 rounded-sm leading-tight focus:outline-none focus:border-black font-bold">
    <option>Choose a lens</option>
    {% for lens in collections.lenses.products %}
    <option price="{{ lens.price }}" value="{{ lens.variants[0].id }}">{{ lens.title }} |
      {{ lens.price | plus: product.price | money_without_trailing_zeros}}</option>
    {% endfor %}
  </select>
</div >
    <h1 id="demo"></h1>
    <script>
        function myFunction() {
  var x = document.getElementById("lens").price;
        document.getElementById("demo").innerHTML = "You selected: " + x;
      }
</script>

J'ai essayé Javascript uniquement: (non défini) p>

data: function () {
    return {
        buttonText: false,
        slideOut: false,
        disableAddToCart: true,
        chosenLens: '',
        chosenFilter: '',
        lensPrice: ''
    }

handleChange(type, e) {
        if (type === 'lens') {
            if (e.target.value) {
                this.chosenLens = e.target.value;
            }
            else {
                this.chosenLens = ''
            }
        }
        if (type === 'filter') {
            this.chosenFilter = e.target.value || ''
        }
        this.disableAddToCart = !(this.chosenLens && this.chosenFilter);
    },
    secondChange(e) {
        this.lensPrice = `${e.target.price}`;
    },

Seul le nom d'attribut 'valeur': (fonctionne)

    <div>
      <label for="lens"></label>
      <select id="lens" name="line_items[lens]" @change="handleChange('lens', $event); secondChange($event);"
        class="mt-3 option-selector text-sm lg:text-base uppercase block appearance-none w-full bg-white text-gray-900 py-3 px-4 pr-8 rounded-sm leading-tight focus:outline-none focus:border-black font-bold">
        <option>Choose a lens</option>
        {% for lens in collections.lenses.products %}
        <option price="{{ lens.price }}" value="{{ lens.variants[0].id }}">{{ lens.title }} |
          {{ lens.price | plus: product.price | money_without_trailing_zeros}}</option>
        {% endfor %}
      </select>
    </div>


8 commentaires

Curieux, quelle est cette syntaxe appelée {% for lens dans collections.lenses.products%} dans Vue?


C'est liquide. Les valeurs de propriété renvoyées sont normales. Je cherche juste à obtenir les valeurs renvoyées au lieu de non définies. Comme je l'ai dit, le navigateur obtient le prix des données, bien que Vue ne le fasse pas.


Quelle est la valeur de e.target à ce moment-là? Vous pourriez devenir indéfini car il n'est plus disponible.


À ce stade, en utilisant console.log, seule la valeur de la sélection renvoie une valeur, le lens.price est instantanément indéfini. Les deux avant de définir this.lensPrice ou après.


Il n'y a pas assez de contexte pour voir le problème. lens est défini à la fois dans votre modèle liquide et le modèle Vue, mais on ne sait pas comment lens est défini dans votre script Vue.


Je crois que c'est peut-être autre chose comme si je fais value = "{{lens.price}}" je reçois les valeurs correctes. Seul un autre nom d'attribut ne fonctionne pas.


Quelque chose d'autre à quoi? Comment lens est-il défini dans le contexte de Vue?


ce problème est principalement lorsque votre modèle est rendu avant que les données ne soient remplies, une astuce simple serait d'utiliser un v-if autour de l'élément où vous imprimez le prix. par exemple. v-fi = "" lense && lense.price "


3 Réponses :


0
votes

Commençons ici:

<select id="lens">
  <option value="A" price="1">First</option>
  <option value="B" price="2">Second</option>
</select>

e est l'objet d'événement du navigateur.

e.target va être l'élément .

Un élément a une propriété intégrée appelée valeur qui reflète la valeur actuellement sélectionnée. Cette valeur est tirée de l'attribut value du actuellement sélectionné .

Donc ce qui se passe est:

  1. L'utilisateur clique sur une .
  2. Le navigateur définit l'attribut value de comme étant égal à l'attribut value de l'option .
  3. Le navigateur déclenche l'événement change pour le .

L'attribut value a une signification particulière en HTML. D'autres attributs de , tels que price , ne le font pas.

Voici un exemple qui n'utilise pas du tout Vue qui présente cela même comportement:

document.getElementById('lens').addEventListener('change', function (ev) {
  const target = ev.target
  console.log(target.tagName, target.value, target.price)
})
e.target.value

Vue a une gestion spéciale pour lier des valeurs non-chaîne à des éléments à utiliser avec v-model mais le problème est voir n'est pas spécifique à Vue.


1 commentaires

Merci, je vais faire plus de lecture sur le sujet. J'ai essayé d'utiliser l'attribut dataset de data-price et toujours rien.



0
votes

Je sais que ce n'est peut-être pas une solution appropriée, mais j'ai pu simplement faire un hack pour l'instant en utilisant split (): le problème est que Vue semble vouloir que les données proviennent de Value et de tout autre nom d'attribut cela ne fonctionnait pas avec.

<option value="{{ filter.variants[0].id }}-{{ filter.price }}"><span>{{ filter.title }} +
  </span><span>{{ filter.price | money_without_trailing_zeros }}</span></option>

priceMethod(type, e) {
        if(type === 'lens')
        if (e.target.value) {
            let a = e.target.value
            a = a.split("-")[1]
            a = a.replace('00', '')
            console.log(a)
            a = parseInt(a)
            this.lensPrice = a;
        } 
        if (type === 'filter') {
            let b = e.target.value
                b = b.split("-")[1]
                b = b.replace('00', '')
                b = parseInt(b)
                console.log(b)
            this.filterPrice = b || ''
        }


2 commentaires

C'est un comportement standard pour un HTML lorsqu'une valeur est choisie. Du point de vue de Vue, la bonne façon de gérer cela serait de garder les données JS comme source de vérité plutôt que d'essayer de tout stocker dans le DOM. Si vous avez la valeur comme une sorte d'identifiant unique, vous pouvez trouver l'objet correspondant dans le tableau d'origine. Ou utilisez v-model et la prise en charge spéciale de la valeur non-string de Vue pour utiliser des objets comme valeurs.


Oui tu as raison. Ce n'est pas la bonne manière et j'essaierai d'en savoir plus pour comprendre cela.



0
votes

En fin de compte, j'ai réussi avec la même technique que ci-dessous.

<select id="app"  @change="deleteItem()">
      <option type="button" data-price="$149">
          $149
      </option>
      <option type="button" data-price="$409">
           $409
      </option>
    </select>

new Vue({
  el: '#app',
  methods:{
    deleteItem: function(){
        var carList = document.getElementById("app");
        var selCar = carList.options[carList.selectedIndex].dataset.price;
        alert(selCar)
    }
  },
})

Le résultat est une alerte de l'attribut de données de 149 $ en cas de modification ou de 409 $ en cas de modification. @click fonctionne également.


0 commentaires