import 和組件庫按需引入

概述

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

參考資料:element-ui

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

從 import 講起

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

babel 會將這段代碼進行轉碼,轉碼以後是這個樣子:app

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

因此,就算咱們只想使用 element-ui 的 button 和 Select 這2個組件,可是實際上,咱們把整個 elment-ui 庫引入進來了。echarts

babel-plugin-component 作了什麼

咱們知道,在 element-ui 的文檔裏面強調,若是要使用按需加載,就要使用 babel-plugin-component 庫。那麼 babel-plugin-component 庫又作了什麼?簡單來講,它把上面的代碼轉化成了下面的樣子:ui

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

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

相似的,e-charts 在按需引入組件的時候是這麼引入的,也是同樣的道理。prototype

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;
}
相關文章
相關標籤/搜索