2

我一直在努力使用 Vue 和 MathLive 来处理排版随机生成的数字及其正方形。程序的功能是生成一个1到35的随机整数,计算平方,用MathLive排版。有两个按钮可以将一个添加到整数或创建另一个随机按钮。我排版初始值没有问题,但是当我创建一个不同的整数或在页面上加 1 时,它永远不会重新排版。我正在尝试将此程序作为 Vue 中的一个组件来实现。这是我的 MWE(仅限组件):

<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>

编辑:为了澄清当我加载页面时,初始值是使用 MathLive 正确排版的,如下所示:在此处输入图像描述 然后在我单击Add OneRandom Number按钮后,程序应该生成一个新值,计算它的平方,然后更新屏幕上的该值如下所示:在此处输入图像描述

4

2 回答 2

2

您需要使用vue.js 计算属性

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>

于 2019-03-19T06:29:25.370 回答
2

MathLive 的 DOM 操作似乎与 Vue 的虚拟 DOM 冲突,从而阻止了 Vue 使用更新的文本节点修补 DOM。

一种解决方法是应用 akey来强制在更改p时重新创建 MathLive 元素key。我们可以num用作键,因为它会随着每次按下按钮而改变:

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

当前的观察者num需要更新以调用renderMath()以刷新 MathLive 元素:

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

您还应该考虑为更有效的渲染square()创建一个计算属性:

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

在 Vue 组件中编辑 MathLive

于 2019-03-30T09:12:25.610 回答