javascript - Dibujo sobre un lienzo con vue.js




canvas (2)

No creo que esto sea necesariamente un problema basado en Vue, pero estoy teniendo algunos problemas.

Me gustaría escribir en el lienzo una variable de Vue. Si elimino vue, mi código inicial funciona bien, sin embargo, si agrego Vue, el lienzo no se inicia realmente.

Aqui esta mi codigo

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

ctx.fillStyle = "black";
ctx.font="20px Georgia";
ctx.fillText("Hello World!",10,50);

var v = new Vue({
  el: '#app',
  data: {
    'exampleContent': 'This is TEXT'
  },
  watch: {
    exampleContent: function(val, oldVal) {
      ctx.clearRect(0,0,canvas.width,canvas.height);
      ctx.fillStyle = "black";
      ctx.font="20px Georgia";
      ctx.fillText(this.exampleContent,10,50);
    }
  }
});

Si comento /* var v = new Vue({ ... el bit inicial funciona. Si registro el valor de exampleContent en el observador también funciona. Pero algo sobre el lienzo no funciona.

Demostración para jugar con: http://codepen.io/EightArmsHQ/pen/EgGbgR?editors=1010


Aquí hay una manera fácil que funciona con Vuejs 2:

  1. Agrega el lienzo a tu plantilla con un atributo de referencia:

    ref="myCanvas"

  2. Luego puede acceder a él desde cualquier lugar dentro de su componente usando

    var canvas = this. $ refs.myCanvas


Como se detalla en la Respuesta de @Mani, Vue elimina y vuelve a representar el elemento DOM sobre el que se invoca una instancia de Vue.

Si abstraes la actualización de tu lienzo en un method instancia de Vue, puedes activarlo en el gancho del ciclo de vida mounted (para obtener el valor inicial de exampleContent ), y volver a invocarlo en tu watch cuando exampleContent cambie.

var v = new Vue({
  el: '#app',
  data: {
    'exampleContent': 'This is TEXT'
  },
  methods: {
    updateCanvas: function (){
      var canvas = document.getElementById('canvas'),
          ctx = canvas.getContext('2d');
      ctx.clearRect(0,0,canvas.width,canvas.height);
      ctx.fillStyle = "black";
      ctx.font="20px Georgia";
      ctx.fillText(this.exampleContent,10,50);
    }
  },
  watch: {
    exampleContent: function(val, oldVal) {
      this.updateCanvas();
    }
  },
  mounted: function (){
    this.updateCanvas();
  }
});
canvas{
  background:red;
  width:800px;
  height:600px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.1/vue.min.js"></script>
<div id="app">
  <canvas id="canvas" width="800" height="600"></canvas>
  <input type="text" v-model="exampleContent" />
  <span>{{ exampleContent }}</span>
</div>

El fragmento de código SO anterior se creó a partir de una versión bifurcada de CodePen de OP





vue.js