使用場景:在 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 也不是響應式的,因此你不應該試圖用它在模板中做數據綁定。