gpt4 book ai didi

javascript - Vue Canvas $ref 未在调整大小时定义。抛出错误但作品似乎仍然有效?

转载 作者:行者123 更新时间:2023-12-01 16:16:55 24 4
gpt4 key购买 nike

在我的应用程序中,我有一个选项卡式界面,在选项卡的“窗口”之一中,有一个 Canvas ,每次调整窗口大小时都会自动适应窗口大小。一切正常,但当我切换选项卡并切换回来,然后尝试调整窗口大小时,它仍然有效但会抛出“this.$refs.canvas is undefined”错误。

我设置了一个简化的示例,用于打开和关闭 Canvas 元素。如果您想尝试调试代码,则代码已完成。如果您在加载后立即调整窗口大小没有问题,并且它可以正常工作,但是如果您打开和关闭 Canvas ,它将引发错误

主应用文件:

<template>
<div id="app">
<button class="toggleBtn" @click="toggleCanvas()">Toggle Canvas</button>
<component class="canvasBox" :is="canvasElX" />
</div>
</template>

<script>
import ResizeCanvas from './components/ResizeCanvas.vue'

export default {
name: 'App',
components: {
ResizeCanvas
},
data(){
return {
canvasShow: true,
canvasEl: null
}
},
computed: {
canvasElX(){
if (this.canvasShow){
return ResizeCanvas;
}
else{
return null;
}
}
},
methods: {
toggleCanvas(){
this.canvasShow = !this.canvasShow;
}
}
}
</script>

<style>
html, body{
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
}

#app {
display: flex;
width: 100%;
height: 100%;
}

.toggleBtn{
width: 150px;
}

.canvasBox{
flex-grow: 1;
}
</style>

ResizeCanvas 组件:

<template>
<div ref="resizeCanvas" class="resizeCanvas">
<canvas ref="canvas" class="canvas">
//Error loading canvas
</canvas>
</div>
</template>

<script>
export default {
name: 'ResizeCanvas',
mounted(){
window.addEventListener('resize', ()=>{this.resizeCanvas()});

this.resizeCanvas();
this.drawCanvas();
},
beforeDestroy(){
window.removeEventListener('resize', ()=>{this.resizeCanvas()});
},
methods: {
resizeCanvas(){
let canvas = this.$refs.canvas;

canvas.width = this.$refs.resizeCanvas.clientWidth;
canvas.height = this.$refs.resizeCanvas.offsetHeight;

this.drawCanvas();
},
drawCanvas(){
let canvas = this.$refs.canvas;
let ctx = canvas.getContext('2d');

ctx.fillStyle = 'black';
ctx.fillRect(0, 0, 50, 50);
ctx.fillRect(canvas.width - 50, canvas.height - 50, 50, 50);
}
}
}
</script>

<style scoped>
.resizeCanvas{
position: relative;
width: 100%;
height: 100%;
}

.canvas{
position: absolute;
}
</style>

这是一个非常令人费解的问题。虽然它似乎无论如何都可以工作,但我担心这可能会在后台引起一些偷偷摸摸的问题,我将不得不在未来找到困难的方法。

最佳答案

这里的问题是您将不断添加新的事件监听器,而旧的事件监听器仍在运行,并带有对 this.$refs 的陈旧引用。 .

这是因为您很遗憾没有使用 removeEventListener 正确(这是一个非常容易犯的错误)。为了正常工作,您需要向它传递您在 addEventListener 中注册的完全相同的功能。 .

如果您传入对组件的引用 methods , 你可以去掉匿名箭头函数

mounted() {
window.addEventListener('resize', this.resizeCanvas) // pass a method reference
this.resizeCanvas()
this.drawCanvas()
},
beforeDestroy() {
window.removeEventListener('resize', this.resizeCanvas) // same function reference
},

如果您不想在每次激活选项卡时都重新加载 Canvas ,您可能会对 <keep-alive> component 感兴趣.

关于javascript - Vue Canvas $ref 未在调整大小时定义。抛出错误但作品似乎仍然有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63066656/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com