[VUE] Vue.js 破圖處理

Vue.js 破圖處理

以前破圖都是寫個 onerror,怎麼用了Vue之後就不管用了?

前言

  • Vue.js 破圖處理

 

基本介紹

開發環境

  1. Vue.js 2.x

 

參考資料

  • (尚無)

常見作法

若剛好公司正處於Vue的導入期,以下是我們常看到的新舊併存的作法

HTML部份

  1. 直接寫一個<img> 並包含原先舊式的 onerror 事件。
<div class="flex-item img-area">
   <img :src="'image/' + VueData.ImgPath" onerror="ImgError(this);" />
</div>

 

JavaScript部份

  1. 宣告一個JavaScript的Function,用來處理所有<img> 觸發 onerror 時的補救辦法。
<script type="text/javascript">

   //破圖處理
   function ImgError(source) {

      source.src = "image/nopic.jpg";
      source.onerror = "";

      return true;
   }

</script>


但我們透過Vue,是可以不斷改變顯示路徑的呀...

後續要是圖片路徑變了,我們就沒辦法再觸發onerror事件了...

 

當然,改寫成 VUE 的 :onerror 也是可以

<img :onerror="Imgerror">

Imgerror : 'this.src="image/nopic.jpg"'

不過以我的習慣來說,既然會常常改變的話,

那應該是在Loading完成的時候,再把圖片換上去,才不會在載入時,在網頁上留下一些空白。

 

實作

我在這邊的作法是

  1. 先載入預設圖片(破圖時的預設圖片)
  2. 確認實際圖片存在並載入完成時,再換上去

 

HTML部份

  1. 我們稍候會在JS註冊real-img指令,所以在這邊就可以很簡單的使用v-real-img即可!!!
<div class="flex-item img-area">
   <img v-real-img="'image/' + VueData.ImgPath" />
</div>

 

JavaScript部份

  1. 註冊一個Vue的指令(my-img),並定義好相關的運作機制(確定圖片載入完成,才換上去)。
  2. 全域指令的部份,依我個人習慣,我會固定放在JS的最上方。
  3. 下面let vm = new Vue();部份可以忽略,我只是把完整的程式碼放上來而已。
<script type="text/javascript">

      /**********************************************************
       * 破圖處理 START
       **********************************************************/

      //註冊全域指令,用於判斷圖片是否能成功載入
      //指令名稱:real-img, 使用則為 v-real-img
      Vue.directive('real-img', async function (el, binding) { 
         let defaultImg = "nopic.jpg";   //預設圖片
         let newLoadImg = binding.value; //欲載入的新圖片

         if (newLoadImg) {
            //await : 等待判斷結果回傳
            let exist = await imageIsExist(newLoadImg);
            if (exist) {
               el.setAttribute('src', newLoadImg);
            }
            else {
               el.setAttribute('src', defaultImg);
            }
         }
      })

      //檢測圖片是否存在
      let imageIsExist = function(url) {
         return new Promise((resolve) => {
            var img = new Image();
            img.onload = function () {
               if (this.complete == true){
                  resolve(true);
                  img = null;
               }
            }
            img.onerror = function () {
               resolve(false);
               img = null;
            }
            img.src = url;
         })
      }

      /**********************************************************
       * 破圖處理 END
       **********************************************************/

      let vm = new Vue({
         el: '#vueapp',
         data: {

         ),
         methods: {

         }
      });//end new Vue
</script>


 

 

 Written By Felix Hsieh