Web笔记··By/蜜汁炒酸奶

Nuxt按需引入ant组件

最开始直接引入了ant所有组件,导致打包出来的 vendors.app.js 有700+kb,通过查询和探索得到如下的按需加载解决方案。

以下已默认引入了ant组件,以下以 ant-design-vue 1.6.2  为例,其余版本不排除需略作修改的可能性。

1. 加载babel-plugin-import

1.1 引入组件

npm install babel-plugin-import --save-dev
1

--save-dev 表示开发依赖( devDependencies ),仅在开发阶段使用,发布之后不再使用。

1.2 配置

nuxt.config.js 文件中的 build: {} 模块中添加配置,具体如下:

build: { 
		// ... 省略其他配置
    transpile: ['ant-design-vue'],
    babel: {
      plugins: [
        ['import',{
            libraryName: 'ant-design-vue',
            libraryDirectory: 'lib', // 默认'lib',也可视情况改为 'es',通过查看组件可知这两个目录均存在。
            style: true,  // true 代表使用less, 若使用css文件,可设置为 'css'
          },
          "ant-design-vue"]
      ]
    }, 
    // style: true时才需要,如果上面 style:'css',则不需要该处的 loaders 配置
    loaders: {
      less: {
        lessOptions: {
          javascriptEnabled: true
        }
      }
     } 
  }, 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

2. 配置ant

2.1 配置ant 按需加载

plugins 目录下新建 antd-ui.js ,添加类似如下配置,可全局引入所需的ant组件:

import Vue from 'vue' 
import { Row,Col,Layout,ConfigProvider,Menu} from 'ant-design-vue';
Vue.use(Col).use(Row).use(Layout)
    .use(ConfigProvider).use(Menu);
1
2
3
4

此处需注意 Vue.use 一次只能引入一个组件,若出现类似 Vue.use(Row,Col,Layout) 的写法是无效的(作为新人,最开始为了省事一直这样引入,结果一直提示相应标签未定义异常,之后逐个引入才实现该功能)。
若有引入 Notification 这种 this.$notification 调用方式的,需增加如下配置:

if(!Vue.prototype.$notification) {
    Vue.prototype.$notification =Notification;
}
1
2
3

若无 if 判断语句,之后可能会出现类似 Cannot set property notification of which has only a getter 的异常(作为初学者目前也只能想到这种解决方案了)。

nuxt.config.js 文件中,若之前 css 模块中引入了全局 antd.css ,此时可以删除。
plugins 模块下新增 '@/plugins/antd-ui' 即可。

2.2 按需引入ant-icon

ant组件还可进一步优化,icon组件本身也是比较大的,往往我们需要的也只是一小部分,原则上只需引入。

2.2.1 创建antd-icon.js

在 assets 目录下新建 antd-icon.js 文件,引入所需iocn配置,类似如下

export {
  default as SketchOutline
} from '@ant-design/icons/lib/outline/SketchOutline';

export {
  default as SearchOutline
} from '@ant-design/icons/lib/outline/SearchOutline';
 
1
2
3
4
5
6
7
8

每一个 export {} from ; 都是一个icon,可通过 Ctrl + 鼠标左键上面的 '@ant-design/icons/lib/outline/SketchOutline' 部分进入icon目录查看所有icon的命名规则从而修改出自己所需配置。

2.2.2 引入antd-icon.js

nuxt.config.js 的build引入配置如下:

build: {
	// ... 省略其他配置
  extend(config, ctx) {
  // ... 省略其他配置
   const path = require('path');
    config.resolve.alias['@ant-design/icons/lib/dist$'] = path.resolve(__dirname, './assets/icons/antd-icon.js') // 引入需要的
  }
}
1
2
3
4
5
6
7
8

请自行将 './assets/icons/antd-icon.js' 路径改为自己的 antd-icon.js 路径。

2.3 按需引入国际化

国际化组件 moment 中存在大量的语言包,往往我们不需要所有的,这时候就可以考虑按需引入国际化部分。

首先在 nuxt.config.js 文件中配置 Webpack.IgnorePlugin ,使其在打包时忽略掉moment

build: {
	// ... 省略其他配置
  plugins: [
  	// ... 省略其他配置
  	new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
  ],
}
1
2
3
4
5
6
7

之后在上面的antd-ui.js 中引入如下配置:

import moment from 'moment';
// 此处以中文语言包为例
import 'moment/locale/zh-cn';
moment.locale('zh-cn');
1
2
3
4

由于我当时用了 <a-config-provider :locale="zh_CN">///... </a-config-provider> 国际化组件(不同版本国际化标签可能不同,比如1.7.2已经改为 a-locale-provider ),所以将上面的配置直接写在了引用国际化组件的页面里,这种方式也是可行的。ant的国际化配置可看官方文档:ant-国际化

3. 附录

3.1 ant组件列表

版本不同,组件名称可能存在差异,请以各自版本为准,该列表参考自ant-design-vue/components/index.js

const components = [
  Base,
  Affix,
  Anchor,
  AutoComplete,
  Alert,
  Avatar,
  BackTop,
  Badge,
  Breadcrumb,
  Button,
  Calendar,
  Card,
  Collapse,
  Carousel,
  Cascader,
  Checkbox,
  Col,
  DatePicker,
  Divider,
  Dropdown,
  Form,
  FormModel,
  Icon,
  Input,
  InputNumber,
  Layout,
  List,
  LocaleProvider,
  Menu,
  Mentions,
  Modal,
  Pagination,
  Popconfirm,
  Popover,
  Progress,
  Radio,
  Rate,
  Row,
  Select,
  Slider,
  Spin,
  Statistic,
  Steps,
  Switch,
  Table,
  Transfer,
  Tree,
  TreeSelect,
  Tabs,
  Tag,
  TimePicker,
  Timeline,
  Tooltip,
  Upload,
  Drawer,
  Skeleton,
  Comment,
  // ColorPicker,
  ConfigProvider,
  Empty,
  Result,
  Descriptions,
  PageHeader,
  Space,
];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
预览
Loading comments...
0 条评论

暂无数据

example
预览