Vue渲染阶段如何正确访问$refs并用于其他元素的样式计算?
问题原因
Vue 中$refs的填充时机是在组件首次挂载完成之后,首次渲染模板时,DOM 节点还没生成,$refs.image自然为undefined,你的getBoxSize方法首次调用时没有返回有效的宽度样式,所以对应 div 不会显示。等你触发其他 UI 更新时,组件已经挂载完成,$refs已经被填充,就能正常拿到宽度渲染元素了。
可行解决方案
方案1:将图片宽度存入响应式变量(推荐,适配动态宽度场景)
不要直接在模板绑定的方法中读取$refs,而是在挂载完成后把需要的属性存入响应式变量,触发自动重渲染:
- 先在
data中定义存储宽度的响应式变量 - 在
mounted钩子中通过$nextTick确保 DOM 完全渲染后读取$refs赋值 - 样式计算方法直接读取响应式变量即可
修改后的代码示例:
// data 部分 data() { return { imgWidth: 0 } }, // mounted 钩子 mounted() { this.$nextTick(() => { if (this.$refs.image) { this.imgWidth = this.$refs.image.width } }) }, // 方法部分 methods: { getBoxSize(idx) { return { top: 50 * idx + 'px', left: '50px', width: this.imgWidth + 'px', height: '50px' } } }
方案2:直接使用固定宽度(适合静态尺寸场景)
你的模板中已经给 img 写死了width="500px",如果图片宽度不会动态变化,可以直接在getBoxSize中把宽度写为500px,不需要读取 DOM 属性,从根源上规避这个问题。
方案3:监听图片 load 事件
如果图片是动态传入的、宽度不固定,也可以给 img 绑定load事件,图片加载完成后再赋值宽度,注意需要处理缓存场景下 load 事件不触发的问题,优先推荐方案1。
内容的提问来源于stack exchange,提问作者Brother Eye
相关产品推荐
相关产品推荐

