經過 vuex 實現 vue-echarts 圖表的手動 resize

背景:項目有用到 vue-echarts, 百度推出的 vue 版本的 Echarts,圖表自帶響應式屬性 auto-resize, 來實現窗口尺寸變化時,圖表的尺寸自適應,可是發現它是靠監聽 window 的 onresize 來實現的,而有時候當chart 容器 尺寸變化時,window 窗口大小是不變的,好比我此次遇到的,側邊菜單欄的顯示隱藏切換,致使內容區域總體部分寬度會變化,可是window 沒有變化,因此auto-resize 不能監聽這種狀況來實現 resize。javascript

解決思路:html

1、可否模擬監聽普通 dom 的尺寸變化,而後調用 echarts 的 resize 事件

具體作法有如下幾種:vue

  1. 初始化項目後,輪詢,反覆查看 dom 尺寸是否變化,這種一聽就感受很差,開銷太大。
  2. 監聽元素的滾動事件,在 目標 dom 裏面包裹一個同等大小的 div,是隱藏不可見的,當目標 dom 大小變化時,觸發滾動事件。參考文章
  3. 經過 MutationObserver 監聽dom 節點變化,MutationObserver 是在DOM4規範中定義的,它的前身是 MutationEvent 事件,該事件最初在 DOM2 事件規範中介紹,到來了 DOM3 事件規範中正式定義,可是因爲該事件存在兼容性以及性能上的問題被棄用;能夠用它來監聽 dom style 的變化, demo 代碼文檔
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="demo" style="background: blue; height: 200px; width: 100%">
        demo 內容
    </div>
    <script>
        var observer = new MutationObserver(function (mutations, observer) {
            mutations.forEach(function (mutation) {
                console.log(mutation);
            });
        });
        var config = {
            attributes: true,
            attributeOldValue: true,
            attributeFilter: [
                'style'
            ]
        };
        var el = document.getElementById('demo');
        
        observer.observe(el, config);
    </script>
</body>
</html>
  1. Ie9-10 默認支持 div 的 resize 事件,能夠直接經過 div.attachEvent('onresize', handler); 的方式實現;其它瀏覽器,經過在 div 中添加一個內置 object 元素實現監聽,設置 object 元素的 style 使其填充滿 div,這樣當 div 的 size 發生變化時,object 的 size 也會發生變化,而後監聽 object 元素的 contentDocument.defaultView(window對象)的 resize 事件。參考文章
2、vue 實現方案

斟酌了上面幾種方案後,結合具體案例,我以爲仍是用 vuex 寫全局數據更好更方便一些,具體步驟以下java

  1. 側邊欄展開和隱藏按鈕點擊 - 觸發事件 - 修改 store - ,在圖表組件裏面 watch store 的變化,而後執行 resize 函數。
  2. 關於 resize(), 由於vue-echarts 插件已是對 echarts 的封裝,若是不修改它的代碼的話,能夠經過 this.$ref 訪問子組件的實例,調用它的 resize()。文檔
// 注意的坑,1.要設置 width 2. width 變化有延遲,須要加個 timeout,否則看不到效果
    this.$refs.chart.resize({width: this.$refs.chart.offsetWidth})
總結:簡單記錄,以做備忘
相關文章
相關標籤/搜索