vue使用canvas画图画不出来

Vue中Canvas画图遇到的诡异问题
在尝试使用Vue构建手势密码功能时,通过canvas进行全屏绘图。然而,将canvas宽度和高度设置为窗口尺寸后,canvas区域却显示为空白。经过排查,发现将`this.wid = window.innerWidth`和`this.hei = window.innerHeight`这两行代码放在组件初始化时会导致问题,但若将它们放在data属性或created钩子中则正常运行。这个问题的原因尚不清楚,寻求社区中大佬的帮助。
部署运行你感兴趣的模型镜像

使用vue做一个手势密码,相当于手机图案解锁
canvas要占全屏所以获取宽高赋值
使用canvas画图,绘制图案
代码

<template>
	<div id="handlogin">
		<canvas id="theone" ref="one" :width="wid" :height="hei" @mousedown="draw"></canvas>
		<canvas id="thetwo" ref="two" :width="wid" :height="hei"></canvas>
	</div>
</template>
data() {
			return {
				wid: null,
				hei: null,
				theone: null,
				thetwo: null,
				dots: []
			}
		},
		mounted() {
			this.init();
		},
		methods: {
			init() {
				this.wid = window.innerWidth;
				this.hei = window.innerHeight;
				console.log(window.innerWidth,window.innerHeight)
				for (let i = 1; i < 4; i++) {
					for (let j = 1; j < 4; j++) {
						let x = this.wid / 4 * j;
						let y = this.hei / 4 * i;
						this.dots.push({
							x,
							y,
							num: (i - 1) * 3 + j
						})
					}
				}
				this.theone = this.$refs.one; // eslint-disable-line no-unused-vars
				this.thetwo = this.$refs.two; // eslint-disable-line no-unused-vars
				let ctx = this.thetwo.getContext("2d");
				this.dots.forEach(item=>{
					ctx.beginPath();
					ctx.arc(item.x, item.y, this.radius, 0, 2 * Math.PI);
					ctx.fillStyle = "#000";
					ctx.fill();
					ctx.stroke();
				})
			},

奇怪的事发生了代码没有报错,但是页面就是啥也没有,查看标签都正常,就是canvas一片空白。检查几遍代码都没问题,就这么点代码我一直看不出问题在哪,后来干脆挨个注释看看到底哪出问题。结果居然是两句赋值出问题了
this.wid = window.innerWidth;
this.hei = window.innerHeight;
就这两句,没了这两句就没问题了,可是不赋值不行,事先在data里面写死值,没问题。说明可以绑定数据
换个地方,把这两句放到create函数里也没问题,就是不能直接放一起
有大佬知道为啥吗

		created() {
			this.wid = window.innerWidth;
			this.hei = window.innerHeight;
		},
		methods: {
			init() {			
				console.log(window.innerWidth,window.innerHeight)
				for (let i = 1; i < 4; i++) {
					for (let j = 1; j < 4; j++) {
						let x = window.innerWidth / 4 * j;
						let y = window.innerHeight / 4 * i;
						this.dots.push({
							x,
							y,
							num: (i - 1) * 3 + j
						})
					}
				}

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

Vue使用 Canvas 进行画图时,确保页面渲染完成后执行绘图操作是关键步骤之一。由于 Vue 的异步渲染机制,直接在 `mounted` 钩子中操作 DOM 可能会导致获取到元素或元素尚未完全渲染完成的问题。可以通过以下方法来确保绘图操作在页面渲染完成后执行。 ### 1. 使用 `nextTick()` 方法 Vue 提供了 `this.$nextTick()` 方法,用于在 DOM 更新后执行特定的代码。在组件挂载或数据更新之后调用此方法,可以确保当前操作是在 DOM 完全渲染完成后再执行[^2]。 例如: ```javascript mounted() { this.$nextTick(() => { const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); // 执行绘图逻辑 ctx.fillStyle = '#FF0000'; ctx.fillRect(0, 0, 150, 75); }); } ``` ### 2. 结合 `ref` 获取 Canvas 元素 通过 `ref` 属性可以直接访问到 DOM 元素,避免使用 `document.getElementById()` 等原生方法带来的确定性。在 Vue 模板中定义 `ref="myCanvas"` 后,在 JavaScript 中可通过 `this.$refs.myCanvas` 直接访问该元素[^1]。 示例模板部分: ```html <canvas id="myCanvas" width="444" height="500" ref="myCanvas"></canvas> ``` JavaScript 部分: ```javascript mounted() { this.$nextTick(() => { const canvas = this.$refs.myCanvas; const ctx = canvas.getContext('2d'); // 绘图逻辑 ctx.beginPath(); ctx.arc(100, 100, 50, 0, Math.PI * 2); ctx.stroke(); }); } ``` ### 3. 处理动态数据驱动的绘图 当 Canvas 的绘制依赖于某些动态数据(如从 API 获取的数据)时,应将绘图逻辑封装在一个独立的方法中,并在数据加载完成后调用该方法。此外,还可以监听数据变化并自动触发重绘操作。 示例代码如下: ```javascript data() { return { chartData: [] }; }, methods: { fetchData() { // 模拟异步请求 setTimeout(() => { this.chartData = [/* 数据 */]; this.drawChart(); }, 1000); }, drawChart() { this.$nextTick(() => { const canvas = this.$refs.myCanvas; const ctx = canvas.getContext('2d'); // 根据 chartData 绘制图形 ctx.clearRect(0, 0, canvas.width, canvas.height); // 示例:绘制一个矩形 ctx.fillStyle = 'blue'; ctx.fillRect(50, 50, 100, 100); }); } }, mounted() { this.fetchData(); } ``` ### 4. 考虑 Canvas 清晰度问题 在设置 Canvas 尺寸时,需要注意设备像素比 (`window.devicePixelRatio`),以确保图像在高分辨率屏幕上依然清晰。可以通过调整 Canvas 的物理像素大小和样式尺寸来实现这一点[^3]。 示例代码: ```javascript methods: { setCanvasResolution(canvas) { const scale = window.devicePixelRatio; canvas.width = Math.floor(canvas.clientWidth * scale); canvas.height = Math.floor(canvas.clientHeight * scale); const ctx = canvas.getContext('2d'); ctx.scale(scale, scale); }, drawChart() { this.$nextTick(() => { const canvas = this.$refs.myCanvas; this.setCanvasResolution(canvas); const ctx = canvas.getContext('2d'); // 绘图逻辑 ctx.fillStyle = 'green'; ctx.fillRect(0, 0, 100, 100); }); } } ``` ### 5. 使用 Vue 生命周期钩子控制绘图时机 除了 `mounted` 和 `updated` 钩子外,还可以根据具体情况选择合适的生命周期钩子。例如,在组件首次渲染完成后使用 `mounted`,而在数据变更导致 DOM 更新后使用 `updated` 来重新绘制图形[^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值