У меня есть кодовая база машинописного текста, в которой я создал рабочую доску судоку, просто работая с DOM напрямую и специально рисуя элемент HTML Canvas, используя его API.
Сейчас я хочу расширить свой проект до полноценного сайта и пытаюсь объединить то, что у меня уже есть, с проектом Vue3. Я использую Composition API с машинописным текстом. Я начал добиваться прогресса, но остановился на проблеме с обновлением доски.
Вот код для запуска моего компонента платы:
<template>
<button @click = "grow">Grow</button>
<br><br>
<div class = "board">
<canvas ref='myCanvas' :width = "size.w" :height = "size.h" tabindex='0'
style = "border:1px solid #000000;"
></canvas>
</div>
</template>
<script lang = "ts">
import { defineComponent, onMounted, ref, reactive } from 'vue'
import { CanvasManager } from '@/managers/canvasmanager'
export default defineComponent({
setup() {
let myCanvas = ref(null)
let myContext = ref(null)
let manager = ref(null)
let size = reactive({
w: 200,
h: 200
})
function grow() {
size.w += 10
size.h += 10
manager.drawGrid(4, 4, 1, 'black')
}
onMounted(() => {
myContext = myCanvas.value.getContext('2d')
manager = new CanvasManager(myContext, size.w, size.h)
manager.drawGrid(4, 4, 1, 'black')
})
return {
myCanvas,
size,
grow
}
}
})
</script>
Импортированный здесь CanvasManager — это написанный мной служебный класс, который содержит различные помощники рисования Canvas API.
Этот код работает при первой загрузке. Вызов manager.drawGrid(4, 4, 1, 'black') внутри onMounted работает и рисует сетку 4 на 4 на холсте.
Метод роста также увеличивает размер холста, и можно увидеть, как растет граница, однако вызов manager.drawGrid(4, 4, 1, 'black') внутри метода роста не имеет никакого эффекта. Сетка внутри границы исчезает и не перерисовывается.
Я использую Vue (любую версию) всего пару недель и сейчас не знаю, как заниматься отладкой.
Я не получаю никаких ошибок в консоли. Я добавил ведение журнала консоли к методу drawGrid в CanvasManager и вижу, что он определенно вызывается.
Любая помощь будет принята с благодарностью.
Ваше здоровье
Большинство руководств с Vue, которые я видел для холста, похоже, перерисовывают весь холст всякий раз, когда что-то меняется и т. д.
@DerekPollard Я слышу, что вы говорите, но удивляюсь, почему это работает в первый раз, поскольку это также внешний класс, выполняющий работу. Я мог бы попробовать переместить методы рисования внутри самого компонента платы.






Vue снова отображает компонент всякий раз, когда происходит изменение данных, но это не означает повторного монтирования, и ваш холст готов только к рисованию onMounted. Поэтому, когда компонент повторно отображает узел, предыдущий рисунок теряется. Один из быстрых способов исправить это — нарисовать onUpdated:
function draw() {
myContext = myCanvas.value.getContext('2d')
manager = new CanvasManager(myContext, size.w, size.h)
manager.drawGrid(4, 4, 1, 'black')
}
onMounted(draw);
onUpdated(draw);
Но я бы еще улучшил код, не создавая новый объект CanvasManager при каждом рендеринге, это можно сделать только один раз.
function draw() {
manager.drawGrid(4, 4, 1, 'black')
}
onMounted(() => {
myContext = myCanvas.value.getContext('2d')
manager = new CanvasManager(myContext, size.w, size.h)
draw();
});
onUpdated(() => {
draw();
});
Вот демо с некоторыми другими незначительными структурными улучшениями.
я предполагаю, что vue перерисовывает, и, поскольку нет ссылки на то, что на самом деле происходит внутри vue, сетка не перерисовывается