vuejs如何在-vfor-列表中动态添加-ref-并获取对应元素dom

33次阅读

共计 1478 个字符,预计需要花费 4 分钟才能阅读完成。

使用场景: 在 vue 中, 我们需要直接操作 DOM 的时候, 可以使用 ref 及 $ref 来实现

也就是说我们在原生 js 中获取 dom 元素, 需要使用
document.getElementById("name")
现在可以直接使用
this.$refs.name

$refs 相对于 document.getElementById,减少了获取 dom 节点的消耗

项目需求:使用 v-for 循环数个 div 区块, 需要实现使用鼠标滚轮监听对每个区块进行自由缩放

需求分析: 我的思路是, 利用 vue 的 ref 属性, 获取对应 dom 节点的 zoom 属性(这个 zoom 属性是用来展示区块缩放倍数的), 最后根据区块的原宽高来计算缩放后的宽高

初步解决方法:

<div
   class="block"
   v-for="(item,index) in charts.blockdata"
   :key="index"
   @mousewheel="rollImg(item.id,index)"
   :ref="`list${index}`"
>

这里使用 ES6 的模板字符串, 用占位符的方式来拼接字符串
给每一个 div 添加不同的 ref 属性
如果对模板字符串的使用方法不清楚的, 可以查看文档
http://es6.ruanyifeng.com/#docs/string# 模板字符串

@mousewheel 监听鼠标滚轮时间, 触发 rollImg 方法

 rollImg(id, index) {
        /* 获取当前页面的缩放比
            若未设置 zoom 缩放比,则为默认 100%,即 1,原图大小 */
        var zoom = parseInt(this.$refs[`list${index}`][0].style.zoom) || 100;
        /* event.wheelDelta 获取滚轮滚动值并将滚动值叠加给缩放比 zoom
            wheelDelta 统一为±120,其中正数表示为向上滚动,负数表示向下滚动 */
        zoom += event.wheelDelta / 12;
        console.log(zoom);
        /* 最小范围 和 最大范围 的图片缩放尺度 */
        this.$refs[`list${index}`][0].style.zoom = zoom + "%";
        this.onResizstop(id, index, 1, parseFloat(zoom / 100));

        return false;
    }

其中获取 dom 节点的核心代码是这一句
this.$refs[list${index}][0].style.zoom

我们仍然是使用模板字符串的方法来获取 dom 节点, 从而得到 zoom 的更新值

这么看我们已经实现这个需求了, 但我在官方文档中看到这样一句话

当 v-for 用于元素或组件时, 引用信息将是包含 DOM 节点或组件实例的数组

所以我们或许可以用更简单的方法来实现这个功能

直接给每一个 div 组件设置相同名称的 ref, 根据此 ref 获取到的是一个包含 DOM 节点或组件实例的数组列表,然后根据 index 即可定位该元素

  <div
     class="block"
     v-for="(item,index) in charts.blockdata"
     :key="index"
     @mousewheel="rollImg(item.id,index)"
     :ref="blocklist"
>
 rollImg(id, index) {
     ......
     this.$refs.blocklist[index].style.zoom = zoom + "%";
     ......
    }

最后需要注意的是:

因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 – 它们还不存在!$refs 也不是响应式的,因此你不应该试图用它在模板中做数据绑定。

正文完
 0