J'ai eu du mal à utiliser Vue et MathLive pour gérer la composition de nombres générés aléatoirement et leurs carrés. La fonction du programme est de générer un entier aléatoire de 1 à 35, de calculer le carré et de le composer avec MathLive. Il y a deux boutons qui ajoutent un à l'entier ou en créent un autre au hasard. Je n'ai aucun problème à composer la valeur initiale, mais lorsque je crée un entier différent ou que j'ajoute 1 à la page, elle ne se re-compose jamais. J'essaie d'implémenter ce programme en tant que composant dans Vue. Voici mon MWE (composant uniquement) :

<template lang="html">
  <div class="problem">
    <p id="math">$${{num}}^2 = {{square()}}$$</p>
    <button @click="addOne">Add One</button>
    <button @click="randomInt">Random Number</button>
  </div>
</template>

<script>
import math from 'mathjs'
import MathLive from 'mathlive'

export default {
  name: 'Problem',
  data: function () {
    return {
      num: math.randomInt(1,35)
    }
  },
  watch: {
    num: function () {
      console.log("Data changed");
      // this.renderMath();
    }
  },
  created: function () {
    console.log("Hello This is created!");
    this.renderMath();
  },
  beforeMount: function () {
    console.log("This is beforeMount");
  },
  mounted: function () {
    console.log("This is mounted!");
  },
  beforeUpdate: function () {
    console.log("This is beforeUpdate");
    this.renderMath();
  },
  methods: {
    addOne: function() {
      this.num++
    },
    randomInt: function () {
      this.num = math.randomInt(1,35)
    },
    square: function () {
      return this.num**2
    },
    renderMath: function (event) {
      this.$nextTick(function(){
        MathLive.renderMathInElement("math");
      })
    }
  }
}
</script>

<style lang="css" scoped>
@import url("../../node_modules/mathlive/dist/mathlive.core.css");
@import url("../../node_modules/mathlive/dist/mathlive.css");
p {
  color: white;
}
</style>

Edit : pour clarifier lorsque je charge la page, la valeur initiale est correctement composée à l'aide de MathLive, comme indiqué ci-dessous : entrez la description de l'image ici Ensuite, après avoir cliqué sur le bouton Ajouter un ou Nombre aléatoire, le programme doit générer une nouvelle valeur, calculer son carré et mettre à jour cette valeur à l'écran comme indiqué ci-dessous : entrez la description de l'image ici

3
1028 19 mars 2019 à 02:56

2 réponses

Meilleure réponse

Il semble que la manipulation du DOM de MathLive entre en conflit avec le DOM virtuel de Vue, empêchant Vue de corriger le DOM avec le nœud de texte mis à jour.

Une solution de contournement consiste à appliquer un key pour forcer le MathLive p élément à recréer lorsque le key change. Nous pourrions utiliser num comme clé, car elle change à chaque pression de bouton :

<p :key="num">...</p>

L'observateur actuel sur num devrait être mis à jour pour appeler renderMath() afin d'actualiser l'élément MathLive :

watch: {
  num() {
    this.renderMath();
  }
},

Vous devriez également envisager de faire de square() une propriété calculée pour rendu plus efficace :

// script
computed: {
  square() {
    return this.num ** 2
  }
}
// template
<p :key="num">$${{num}}^2 = {{square}}$$</p>

Edit MathLive in Vue component

2
tony19 30 mars 2019 à 19:57

Vous devez utiliser les propriétés vue.js calculées

new Vue({
  name: 'Problem',
  data: function () {
    return {
      num: math.randomInt(1,35)
    }
  },
  watch: {
    num: function () {
      console.log("Data changed");
      this.renderMath();
    }
  },
  computed: {
     square: function () {
        return this.num**2;
     }
  },
  created: function () {
    console.log("Hello This is created!");
    this.renderMath();
  },
  beforeMount: function () {
    console.log("This is beforeMount");
  },
  mounted: function () {
    console.log("This is mounted!");
  },
  beforeUpdate: function () {
    console.log("This is beforeUpdate");
    //this.renderMath();
  },
  methods: {
    addOne: function() {
      this.num++
    },
    randomInt: function () {
      this.num = math.randomInt(1,35)
    },
    renderMath: function (event) {
      this.$nextTick(function(){
        MathLive.renderMathInElement("math");
      })
    }
  }
}).$mount("#app")
<script src="https://unpkg.com/mathjs/dist/math.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mathlive@0.26.0/dist/mathlive.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <span>$${{num}}^2 = {{square}}$$</span>
  <span id="math"></span>
  <button @click="addOne">Add One</button>
  <button @click="randomInt">Random Number</button>
</div>
2
Alex 20 mars 2019 à 06:53