写点什么

Vue 项目中实现 ElementUI 按需引入

作者:不叫猫先生
  • 2023-06-07
    北京
  • 本文字数:3693 字

    阅读完需:约 12 分钟

Vue项目中实现ElementUI按需引入

前言

为了减小项目打包体积,提高项目性能,对 Element UI 组件进行按需引入,但是在实际实践过程中遇到了比较有意思的问题,官方写的 demo 然而并不能行的通,有开发者在 Issues 提问,然后官方并没有给予解决,而开发者用另一种方式实现了。(在这里我就想吐槽:官方 demo 实现不了,写在官网上给更多的人种坑,网上一大堆的 Element UI 组件按需引入几乎都是官方的例子。我就想问问那些写文章的兄弟们有么有实践过,又给众多兄弟埋坑呢!所以我总结一下给兄弟们避雷。)


官网 demo:链接直达Issues 地址:链接直达

按需引入

一、误区

这里有个误区,不使用babel-plugin-import插件,而是如下这么写,依然打包的是正个 Element UI 模块。


import Vue from "vue"import { Button } from "element-ui"Vue.use(Button)
复制代码

二、正确手法

使用babel-plugin-import插件,组件库按需加载时在 babel 编译 js 阶段进行了代码转换,只加载使用的组件代码。

1、安装插件

npm install babel-plugin-component -D
复制代码

2、更改.babelrc配置

若项目目录没有.babelrc文件,没有的话新建一个。在 babel 执行编译的过程中,会从项目的根目录下的.babelrc文件中读取配置。.babelrc是一个 json 格式的文件。在.babelrc配置文件中,主要是对预设(presets) 和 插件(plugins) 进行配置。


{  "plugins": [    [      "component",      {        "libraryName": "element-ui",        "styleLibraryName": "theme-chalk"      }    ]  ]}
复制代码

3、 新建auto-import-elementUI.js文件,注册需要用到的组件

这里以实际项目中使用为例,下面代码注释的是我项目中没有用到的组件。完整组件列表和引入方式(完整组件列表以 components.json 为准)


==注意:官方给的例子和我下面写的不太一样,这就是为什么用官方例子就报错,官方是下面的写法,在实际过程就会报错,我所使用的 Element UI 版本为2.15.13 </font>==


//官方例子import Vue from 'vue';import {  Pagination,  Dialog,  Autocomplete,  Dropdown,  DropdownMenu,  DropdownItem,  Menu,  Submenu,  MenuItem,  MenuItemGroup,  Input,  InputNumber,  Radio,  RadioGroup,  RadioButton,  Checkbox,  CheckboxButton,  CheckboxGroup,  Switch,  Select,  Option,  OptionGroup,  Button,  ButtonGroup,  Table,  TableColumn,  DatePicker,  TimeSelect,  TimePicker,  Popover,  Tooltip,  Breadcrumb,  BreadcrumbItem,  Form,  FormItem,  Tabs,  TabPane,  Tag,  Tree,  Alert,  Slider,  Icon,  Row,  Col,  Upload,  Progress,  Spinner,  Badge,  Card,  Rate,  Steps,  Step,  Carousel,  CarouselItem,  Collapse,  CollapseItem,  Cascader,  ColorPicker,  Transfer,  Container,  Header,  Aside,  Main,  Footer,  Timeline,  TimelineItem,  Link,  Divider,  Image,  Calendar,  Backtop,  PageHeader,  CascaderPanel,  Loading,  MessageBox,  Message,  Notification} from 'element-ui';
Vue.use(Pagination);Vue.use(Dialog);Vue.use(Autocomplete);Vue.use(Dropdown);Vue.use(DropdownMenu);Vue.use(DropdownItem);Vue.use(Menu);Vue.use(Submenu);Vue.use(MenuItem);Vue.use(MenuItemGroup);Vue.use(Input);Vue.use(InputNumber);Vue.use(Radio);Vue.use(RadioGroup);Vue.use(RadioButton);Vue.use(Checkbox);Vue.use(CheckboxButton);Vue.use(CheckboxGroup);Vue.use(Switch);Vue.use(Select);Vue.use(Option);Vue.use(OptionGroup);Vue.use(Button);Vue.use(ButtonGroup);Vue.use(Table);Vue.use(TableColumn);Vue.use(DatePicker);Vue.use(TimeSelect);Vue.use(TimePicker);Vue.use(Popover);Vue.use(Tooltip);Vue.use(Breadcrumb);Vue.use(BreadcrumbItem);Vue.use(Form);Vue.use(FormItem);Vue.use(Tabs);Vue.use(TabPane);Vue.use(Tag);Vue.use(Tree);Vue.use(Alert);Vue.use(Slider);Vue.use(Icon);Vue.use(Row);Vue.use(Col);Vue.use(Upload);Vue.use(Progress);Vue.use(Spinner);Vue.use(Badge);Vue.use(Card);Vue.use(Rate);Vue.use(Steps);Vue.use(Step);Vue.use(Carousel);Vue.use(CarouselItem);Vue.use(Collapse);Vue.use(CollapseItem);Vue.use(Cascader);Vue.use(ColorPicker);Vue.use(Transfer);Vue.use(Container);Vue.use(Header);Vue.use(Aside);Vue.use(Main);Vue.use(Footer);Vue.use(Timeline);Vue.use(TimelineItem);Vue.use(Link);Vue.use(Divider);Vue.use(Image);Vue.use(Calendar);Vue.use(Backtop);Vue.use(PageHeader);Vue.use(CascaderPanel);
Vue.use(Loading.directive);
Vue.prototype.$loading = Loading.service;Vue.prototype.$msgbox = MessageBox;Vue.prototype.$alert = MessageBox.alert;Vue.prototype.$confirm = MessageBox.confirm;Vue.prototype.$prompt = MessageBox.prompt;Vue.prototype.$notify = Notification;Vue.prototype.$message = Message;
复制代码


报错如下:




为了避免出现上面的报错现象,下面的写法是 Issus 给出的正解,不会报错:


//Issus给出的正解import Vue from 'vue'import {  Pagination,  Dialog,  // Autocomplete,  Dropdown,  DropdownMenu,  DropdownItem,  Menu,  Submenu,  MenuItem,   MenuItemGroup,  Input,  InputNumber,    Radio,  RadioGroup,  RadioButton,  Checkbox,  CheckboxButton,  CheckboxGroup,  Switch,  Select,  Option,  OptionGroup,  Button,  ButtonGroup,  Table,  TableColumn,  DatePicker,  TimeSelect,  TimePicker,  Popover,  Tooltip,  Breadcrumb,  BreadcrumbItem,  Form,  FormItem,  Tabs,  TabPane,  Tag,  Tree,  Alert,  Slider,  Icon,  Row,  Col,  Upload,  Progress,  // Spinner,  Badge,  Card,  Rate,  // Steps,  // Step,  // Carousel,  // CarouselItem,  // Collapse,  // CollapseItem,  Cascader,  ColorPicker,  // Transfer,  // Container,  // Header,  // Aside,  // Main,  // Footer,  Timeline,  TimelineItem,  Link,  Divider,  // Image,  Calendar,  // Backtop,  // PageHeader,  CascaderPanel,  Loading,  MessageBox,  Message,  Notification,  Scrollbar} from 'element-ui';


Vue.use(Pagination);Vue.use(Dialog);// Vue.use(Autocomplete);Vue.use(Dropdown);Vue.use(DropdownMenu);Vue.use(DropdownItem);Vue.use(Menu);Vue.use(Submenu);Vue.use(MenuItem);Vue.use(MenuItemGroup);Vue.use(Input);Vue.use(InputNumber);Vue.use(Radio);Vue.use(RadioGroup);Vue.use(RadioButton);Vue.use(Checkbox);Vue.use(CheckboxButton);Vue.use(CheckboxGroup);Vue.use(Switch);Vue.use(Select);Vue.use(Option);Vue.use(OptionGroup);Vue.use(Button);Vue.use(ButtonGroup);Vue.use(Table);Vue.use(TableColumn);Vue.use(DatePicker);Vue.use(TimeSelect);Vue.use(TimePicker);Vue.use(Popover);Vue.use(Tooltip);Vue.use(Breadcrumb);Vue.use(BreadcrumbItem);Vue.use(Form);Vue.use(FormItem);Vue.use(Tabs);Vue.use(TabPane);Vue.use(Tag);Vue.use(Tree);Vue.use(Alert);Vue.use(Slider);Vue.use(Icon);Vue.use(Row);Vue.use(Col);Vue.use(Upload);Vue.use(Progress);// Vue.use(Spinner);Vue.use(Badge);Vue.use(Card);Vue.use(Rate);// Vue.use(Steps);// Vue.use(Step);// Vue.use(Carousel);// Vue.use(CarouselItem);// Vue.use(Collapse);// Vue.use(CollapseItem);Vue.use(Cascader);Vue.use(ColorPicker);// Vue.use(Transfer);// Vue.use(Container);// Vue.use(Header);// Vue.use(Aside);// Vue.use(Main);// Vue.use(Footer);Vue.use(Timeline);Vue.use(TimelineItem);Vue.use(Link);Vue.use(Divider);// Vue.use(Image);Vue.use(Calendar);// Vue.use(Backtop);// Vue.use(PageHeader);Vue.use(CascaderPanel);Vue.use(Scrollbar);

const { directive: loadingDirective, service: loadingService } = Loadingconst msgbox = MessageBoxconst { alert, confirm, prompt } = msgboxVue.use(loadingDirective)Vue.prototype.$loading = loadingServiceVue.prototype.$msgbox = msgboxVue.prototype.$alert = alertVue.prototype.$confirm = confirmVue.prototype.$prompt = promptVue.prototype.$notify = NotificationVue.prototype.$message = Message//设置项目中所有拥有 size 属性的组件Vue.prototype.$ELEMENT = { size: 'small', zIndex: 3000 }
复制代码


至于为什么这么写,就需要研究源码了。

4、main.js 引入

import "./auto-import-elementUI.js"
复制代码


接下来启动项目就可以啦,大功告成,如有遇到其他情况留言评论区。

发布于: 刚刚阅读数: 3
用户头像

还未添加个人签名 2022-10-18 加入

前端领域优质创作者、阿里云专家博主,专注于前端各领域技术,共同学习共同进步,一起加油呀!

评论

发布
暂无评论
Vue项目中实现ElementUI按需引入_Vue_不叫猫先生_InfoQ写作社区