import 和組件庫按需引入


概述

今天查資料查到了一些有趣的東西,記錄下來,供以后開發時參考,相信對其他人也有用。

參考資料:

import、require、export、module.exports 混合使用詳解

從 import 講起

import { button, Select } from 'element-ui'這段代碼到底發生了什么?

babel 會將這段代碼進行轉碼,轉碼之后是這個樣子:

var a = require('element-ui');
var Button = a.Button;
var Select = a.Select;

所以,就算我們只想使用 element-ui 的 button 和 Select 這2個組件,但是實際上,我們把整個 elment-ui 庫引入進來了。

babel-plugin-component 做了什么

我們知道,在 element-ui 的文檔里面強調,如果要使用按需加載,就要使用 babel-plugin-component 庫。那么 babel-plugin-component 庫又做了什么?簡單來說,它把上面的代碼轉化成了下面的樣子:

import Button from 'element-ui/lib/button'
import Select from 'element-ui/lib/select'

這樣就只會引入 Button 和 Select 這兩個組件了。

類似的,e-charts 在按需引入組件的時候是這么引入的,也是一樣的道理。

import 'echarts/lib/chart/bar';
import 'echarts/lib/chart/line';
import 'echarts/lib/chart/scatter';
import 'echarts/lib/chart/effectScatter';
import 'echarts/lib/chart/treemap';

所以,所有支持按需引入的庫,都可以用上面的方法進行按需引入組件。

一個問題

如果我們有一個需求,就是在 app 加載的時候不引入 element-ui 庫,然后在/admin這個路由下面才引入 element-ui ,那要怎么做呢?

在 main.js 使用各種形式的按需加載肯定是不行的,因為會打包進入 app.js 里面去,從而在初次加載 app 的時候加載。

/admin這個路由下,各個組件用到 element-ui 的組件的時候,各自按需加載。這個方法是可行的,但是非常繁瑣,每次用到 element-ui 的組件都需要引入一下,然后掛載一下。

我選擇的方法是,在/admin這個路由的組件下面,按需加載全部需要的 element-ui 組件,示例代碼如下:

// admin.element.js
import Vue from 'vue';
import Row from 'element-ui/lib/row';
import Col from 'element-ui/lib/col';
import Table from 'element-ui/lib/table';
import TableColumn from 'element-ui/lib/table-column';
import Button from 'element-ui/lib/button';
import Footer from 'element-ui/lib/footer';
import Form from 'element-ui/lib/form';
import FormItem from 'element-ui/lib/form-item';
import Input from 'element-ui/lib/input';
import Menu from 'element-ui/lib/menu';
import Submenu from 'element-ui/lib/submenu';
import MenuItem from 'element-ui/lib/menu-item';
import Loading from 'element-ui/lib/loading';
import Message from 'element-ui/lib/message';

const components = [
  Row,
  Col,
  Table,
  TableColumn,
  Button,
  Footer,
  Form,
  FormItem,
  Input,
  Menu,
  Submenu,
  MenuItem,
];
components.forEach((component) => {
  Vue.component(component.name, component);
});

Vue.use(Loading.directive);
Vue.prototype.$message = Message;

內存泄漏

粗看上面的代碼是沒有問題的,但是仔細想的話,如果每次跳轉到/admin路由下面的話,那不是每次都會安裝引入的這些組件嗎?那如果跳轉多次就會安裝多次,造成內存泄漏啊~~~

雖然說 Vue 本身的插件安裝機制已經避免了這種情況,但是我們還是建議加上一行判斷代碼

import Vue from 'vue';
import Row from 'element-ui/lib/row';
import Col from 'element-ui/lib/col';
import Table from 'element-ui/lib/table';
import TableColumn from 'element-ui/lib/table-column';
import Button from 'element-ui/lib/button';
import Footer from 'element-ui/lib/footer';
import Form from 'element-ui/lib/form';
import FormItem from 'element-ui/lib/form-item';
import Input from 'element-ui/lib/input';
import Menu from 'element-ui/lib/menu';
import Submenu from 'element-ui/lib/submenu';
import MenuItem from 'element-ui/lib/menu-item';
import Loading from 'element-ui/lib/loading';
import Message from 'element-ui/lib/message';

// hack: 防止多次引入導致內存泄漏
if (!Vue.hasAdminPageImportedElement) {
  const components = [
    Row,
    Col,
    Table,
    TableColumn,
    Button,
    Footer,
    Form,
    FormItem,
    Input,
    Menu,
    Submenu,
    MenuItem,
  ];
  components.forEach((component) => {
    Vue.component(component.name, component);
  });

  Vue.use(Loading.directive);
  Vue.prototype.$message = Message;

  Vue.hasAdminPageImportedElement = true;
}


免責聲明!

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



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