使用场景:在 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 也不是响应式的,因此你不应该试图用它在模板中做数据绑定。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。