js中可以給window去綁定縮放事件,從而去監(jiān)聽窗口大小的變化:
window.addEventListener('resize', () => {})
但是有時(shí)候窗口的大小并不會(huì)變化,變的是元素的大小,好像是沒有方法是可以直接監(jiān)聽元素的大小變化的,那如果有這個(gè)需求呢?
這次超人鴨也從一個(gè)真實(shí)需求講解,如何去監(jiān)聽一個(gè)元素的寬高變化,看圖:

image.png
在切換側(cè)邊欄的收縮時(shí),右邊的內(nèi)容的寬度就會(huì)變化,此時(shí)我右邊是echart,echarts在初始化畫完之后,當(dāng)容器改變大小的時(shí)候,echart并不會(huì)響應(yīng)式的重新畫圖,需要我們手動(dòng)去調(diào)用繪制echart的方法,所以,監(jiān)聽元素的寬度變化是關(guān)鍵。
- 下面超人鴨介紹使用自定義指令的方式,去監(jiān)聽元素的寬高變化:
directives: { // 使用局部注冊(cè)指令的方式
resize: { // 指令的名稱
bind(el, binding) { // el為綁定的元素,binding為綁定給指令的對(duì)象
let width = '', height = '';
function isReize() {
const style = document.defaultView.getComputedStyle(el);
if (width !== style.width || height !== style.height) {
binding.value(); // 關(guān)鍵
}
width = style.width;
height = style.height;
}
el.__vueSetInterval__ = setInterval(isReize, 300);
},
unbind(el) {
clearInterval(el.__vueSetInterval__);
}
}
}
//然后在html中
<div v-resize="resize"></div> // 綁定的resize是一個(gè)函數(shù)
//在methods中
resize() { // 當(dāng)寬高變化時(shí)就會(huì)執(zhí)行
//執(zhí)行某些操作
}
- 上面就是實(shí)現(xiàn)的方法,下面講一下這個(gè)自定義指令的實(shí)現(xiàn):
- 首先我采用局部注冊(cè)的方法,然后操作基本都放到bind這個(gè)鉤子函數(shù)中,看一下官方的解釋:bind:只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用。在這里可以進(jìn)行一次性的初始化設(shè)置。這個(gè)鉤子函數(shù)只會(huì)執(zhí)行一次,我們這個(gè)例子沒有涉及到數(shù)據(jù)的變化,如果有涉及到數(shù)據(jù)的變化,就應(yīng)該使用update:所在組件的 VNode 更新時(shí)調(diào)用
- 然后我定義兩個(gè)變量用來存儲(chǔ)寬高,并在isReize這個(gè)方法中去獲取寬高,這里用到document.defaultView.getComputedStyle(el),這個(gè)方法可以獲取元素的樣式,不局限寫在行內(nèi)的style。然后去跟原來的寬高比較,如果不同就執(zhí)行下面的 binding.value();
- binding.value就是我們?cè)趆tml中綁定給指令的值,<div v-resize="resize"></div>也就是resize,是個(gè)函數(shù)。這里很容易以為只能綁定字符串變量,但其實(shí)自定義指令的綁定值很強(qiáng)大,可以玩很多種花樣,大家可以看看官方文檔:自定義指令
- 最后我再下面賦值了定時(shí)器,每300毫秒去執(zhí)行一次,在unbind這個(gè)鉤子函數(shù)中清除定時(shí)器
到這里就實(shí)現(xiàn)了監(jiān)聽一個(gè)元素的寬高變化,并執(zhí)行相應(yīng)的操作,但如果是針對(duì)于echart,還需要在echart實(shí)例添加一個(gè)方法:
const myChart = echarts.init(document.getElementById(id))
****
myChart.resize()
超人鴨也是第一次嘗試vue中的自定義指令,如果有更好的解決方法歡迎指教哦。