iview-admin(cli3 + webpack4 )解決兼容ie9+ 方案


前言:經過多次試驗終於可以讓iview-admin兼容ie9+了,直接往下看↓↓↓

 

一、准備工作

  (建議node版本安裝到8.2以上)

  1.從github上下載或Clone iview-admin 項目

    github地址: https://github.com/iview/iview-admin 

    Clone地址:https://github.com/iview/iview-admin.git

  2.初始化項目

    npm install     或     npm install --registry=https://registry.npm.taobao.org

  3.啟動項目
    npm run dev


二、處理兼容

  (項目起來后我們會發現在 Chrome、Firefox 的高級瀏覽器上是正常的,但在ie9~ie11  上面顯示是一片空白,打開控制台,發現報錯如下圖:)
    

    問題原因:ie11-  不兼容 es6 語法 

    解決法案:

      方案一:安裝"@babel/polyfill" 

          然后發現依然不起作用,折騰了好久出來是出來了,但舍去和調改了好多東西,所以最終放棄這種方法

      方案二:安裝 "babel-loader"  

         1.安裝依賴

             (webpack官方安裝地址:  https://webpack.docschina.org/loaders/babel-loader/#%E5%AE%89%E8%A3%85  

                              npm install -D babel-loader @babel/core @babel/preset-env webpack 

        安裝成功之后package.json 配置文件如下:     

            "devDependencies": {
              "@babel/core": "^7.4.5",
              "@babel/preset-env": "^7.4.5",
              "@vue/cli-plugin-babel": "^3.0.1",
              "@vue/cli-plugin-eslint": "^3.0.1",
              "@vue/cli-plugin-unit-mocha": "^3.0.1",
              "@vue/cli-service": "^3.0.1",
              "@vue/eslint-config-standard": "^3.0.0-beta.10",
              "@vue/test-utils": "^1.0.0-beta.10",
              "babel-loader": "^8.0.6",
              "chai": "^4.1.2",
              "eslint-plugin-cypress": "^2.0.1",
              "less": "^2.7.3",
              "less-loader": "^4.0.5",
              "lint-staged": "^6.0.0",
              "mockjs": "^1.0.1-beta3",
              "vue-template-compiler": "^2.5.13",
              "webpack": "^4.34.0"
            },

        2.在vue.config.js 配置weibpack

        (Cli 官方webpack配置地址:  https://cli.vuejs.org/zh/guide/webpack.html

 

 
         
module.exports = {
          //...
          configureWebpack:{
              
                  module:{
                    rules: [
                      {
                        test: /\.m?js$/,
                        //exclude用下面配置的話,默認是過濾不編譯node_modules 路徑下的文件
                        //exclude: /(node_modules|bower_components)/,
                        //include 指定需要編譯的文件路徑
                        include: [
                          resolve('src'),
                          resolve('node_modules/tree-table-vue/lib'),
                          resolve('node_modules/v-org-tree/dist'),
                          resolve('node_modules/iview/src/locale')
                        ],
                        use: {
                          loader: 'babel-loader',
                          options: {
                            presets: ['@babel/preset-env']
                          }
                        }
                      }
                    ]
                  }
                },
                chainWebpack: config => {
                  config.resolve.alias
                    .set('@', resolve('src')) // key,value自行定義,比如.set('@@', resolve('src/components'))
                    .set('_c', resolve('src/components'))
                }
        //...

         }

 

 

 

        按上面的配置,然后重啟項目,你會發現在ie9+ 都可以正常預覽了,看下圖↓↓↓

                            

 

        補充說明下,為什么我們使用@babel/polyfill 是ie下然后會報錯的原因,是因為iview date 組件i18n 及 v-org-tree 和tree-table-vue組件里面有es6的語法,而他們都在"node_modules"路徑下,而編譯工具默認是不編譯這個文件下文件的

        所以所以使用 include 指定 node_modules 路徑需要編譯文件路徑

 三、Bug 處理

  1.ie11 下 點擊右上角全屏 圖標后,再次點擊不退出全屏bug

    將src/components/main/components/fullscreen/fullscreen.vue  里的全屏事件監聽事件名糾正為MSFullscreenChange即可正常監聽事件變化,功能恢復正常。   具體代碼如下:

                  document.addEventListener('msfullscreenchange', () => {
                    this.$emit('input', !this.value)
                    this.$emit('on-change', !this.value)
                  })

                //更改為
                  document.addEventListener('MSFullscreenChange', () => {
                    this.$emit('input', !this.value)
                    this.$emit('on-change', !this.value)
                  })

  2.ie9下右側內容下墜問題

    在src/components/main/main.vue   添加 float:left  樣式

    <Sider hide-trigger collapsible :width="256" :collapsed-width="64" v-model="collapsed" class="left-sider" :style="{overflow: 'hidden'}">
      <side-menu accordion ref="sideMenu" :active-name="$route.name" :collapsed="collapsed" @on-select="turnToPage" :menu-list="menuList">
        <!-- 需要放在菜單上面的內容,如Logo,寫在side-menu標簽內部,如下 -->
        <div class="logo-con">
          <img v-show="!collapsed" :src="maxLogo" key="max-logo" />
          <img v-show="collapsed" :src="minLogo" key="min-logo" />
        </div>
      </side-menu>
    </Sider>

        //修改后

    <Sider hide-trigger collapsible :width="256" :collapsed-width="64" v-model="collapsed" class="left-sider" :style="{overflow: 'hidden',float:'left'}">
      <side-menu accordion ref="sideMenu" :active-name="$route.name" :collapsed="collapsed" @on-select="turnToPage" :menu-list="menuList">
        <!-- 需要放在菜單上面的內容,如Logo,寫在side-menu標簽內部,如下 -->
        <div class="logo-con">
          <img v-show="!collapsed" :src="maxLogo" key="max-logo" />
          <img v-show="collapsed" :src="minLogo" key="min-logo" />
        </div>
      </side-menu>
    </Sider>

  修改后效果 如下,剩下還需要修改一下css樣式

 

   3.ie下其他報錯處理代碼,在src/view/main.js   new Vue({})下方添加以下代碼

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  i18n,
  store,
  render: h => h(App)
})
////////////////////下面是需要添加內容///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
*作用:兼容dataset
*問題:[Vue warn]: Error in directive transfer-dom inserted hook: "TypeError: 無法獲取未定義或 null 引用的屬性“transfer”"
*說明:ie10及以下不支持dataset,以下代碼處理兼容
* */
if (window.HTMLElement) {
  if (Object.getOwnPropertyNames(HTMLElement.prototype).indexOf('dataset') === -1) {
    Object.defineProperty(HTMLElement.prototype, 'dataset', {
      get: function () {
        var attributes = this.attributes; // 獲取節點的所有屬性
        var name = [];
        var value = []; // 定義兩個數組保存屬性名和屬性值
        var obj = {}; // 定義一個空對象
        for (var i = 0; i < attributes.length; i++) { // 遍歷節點的所有屬性
          if (attributes[i].nodeName.slice(0, 5) === 'data-') { // 如果屬性名的前面5個字符符合"data-"
            // 取出屬性名的"data-"的后面的字符串放入name數組中
            name.push(attributes[i].nodeName.slice(5));
            // 取出對應的屬性值放入value數組中
            value.push(attributes[i].nodeValue);
          }
        }
        for (var j = 0; j < name.length; j++) { // 遍歷name和value數組
          obj[name[j]] = value[j]; // 將屬性名和屬性值保存到obj中
        }
        return obj; // 返回對象
      },
    });
  }
}

/**
 *作用:兼容requestAnimationFrame(ie9)
 *問題:
 *說明:ie9是不支持requestAnimationFrame的,以下代碼處理兼容
 * */
(function () {
  var lastTime = 0;
  var vendors = ['ms', 'moz', 'webkit', 'o'];
  for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
    window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||
      window[vendors[x] + 'CancelRequestAnimationFrame'];
  }

  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = function (callback, element) {
      var currTime = new Date().getTime();
      var timeToCall = Math.max(0, 16 - (currTime - lastTime));
      var id = window.setTimeout(function () { callback(currTime + timeToCall); },
        timeToCall);
      lastTime = currTime + timeToCall;
      return id;
    };
  }

  if (!window.cancelAnimationFrame) {
    window.cancelAnimationFrame = function (id) {
      clearTimeout(id);
    };
  }
}());

/**
 *作用:兼容classList(ie9)
 *錯誤信息: 無法獲取未定義或 null 引用的屬性“add”/  無法獲取未定義或 null 引用的屬性“remove”
 *說明:ie9以下代碼處理兼容
 * */
if (!('classList' in document.documentElement)) {
  Object.defineProperty(HTMLElement.prototype, 'classList', {
    get: function () {
      var self = this;
      function update(fn) {
        return function (value) {
          var classes = self.className.split(/s+/g);
          var index = classes.indexOf(value);

          fn(classes, index, value);
          self.className = classes.join(' ');
        };
      }

      return {
        add: update(function (classes, index, value) {
          if (!~index) classes.push(value);
        }),

        remove: update(function (classes, index) {
          if (~index) classes.splice(index, 1);
        }),

        toggle: update(function (classes, index, value) {
          if (~index) { classes.splice(index, 1); } else { classes.push(value); }
        }),

        contains: function (value) {
          return !!~self.className.split(/s+/g).indexOf(value);
        },

        item: function (i) {
          return self.className.split(/s+/g)[i] || null;
        },
      };
    },
  });
}

  4.ie下報vue  {description: "無法獲取未定義或 nu...", message: "無法獲取未定義或 nu...", name: "TypeError", number: -21468232

    清除瀏覽器緩存即可,快捷鍵  Ctrl + Shift +Delete

        

好了,暫時就這樣,后面有新解決方法再更新,大家如果有其他簡單好用的方法也可以留言給我❤


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM