ant-design-vue按需引入、自定义主题

ant-design-vue按需引入、自定义主题

2020年07月15日 阅读:67 字数:1164 阅读时长:3 分钟

ant-design-vue按需引入组件、图标,定制主题以及表格高度自适应

使用ant-design-vue@1.7.8

1、按需引入

"babel-plugin-import": "^1.13.3",用于按需加载组件代码和样式的 babel 插件

1.1、组件按需引入

修改babel.config.js文件,配置 babel-plugin-import

module.exports = {
  plugins: [
    [
      'import',
      {
        'libraryName': 'ant-design-vue',
        'libraryDirectory': 'es',
        'style': true // `style: true` 会加载 less 文件
      }
    ]
  ]
}

src/vendor/ant-design.js

import Vue from 'vue'

import {
  // 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,
  message,
  Menu,
  // Mentions,
  Modal,
  notification,
  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,
  ConfigProvider,
  Empty,
  // Result,
  // Descriptions,
  // PageHeader,
  Space,
  version
} from 'ant-design-vue'

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,
  ConfigProvider,
  Empty,
  // Result,
  // Descriptions,
  // PageHeader,
  Space
]

export default {
  /**
   * Vue use注册
   * @param {Object} Vue
   */
  install: function() {
    components.map(function(component) {
      Vue.use(component)
    })

    Vue.prototype.$message = message
    Vue.prototype.$notification = notification
    Vue.prototype.$info = Modal.info
    Vue.prototype.$success = Modal.success
    Vue.prototype.$error = Modal.error
    Vue.prototype.$warning = Modal.warning
    Vue.prototype.$confirm = Modal.confirm
    Vue.prototype.$destroyAll = Modal.destroyAll
  },
  version
}

process.env.NODE_ENV !== 'production' && console.warn('[Antd] Antd使用按需加载, 若缺失, 请到此处修改.')

在main.js中引入

import Antdv from '@/vendor/ant-design'

Vue.use(Antdv)

1.2、图标按需引入

处理1.2.0 之后全量引入了所有图标,bundle体积过大的问题

大概思路是自己搞一个icon引入文件,用别名把icon的默认库替换一下

如果打包报错:查看alias配置以及ant-icons.js导出是否正确

vue.config.js

module.exports = {
  configureWebpack: {
    resolve: {
      alias: {
        '@': resolve('src'),
        // 大概思路是自己搞一个icon引入文件,用别名把icon的默认库替换一下
        // @see https://github.com/ant-design/ant-design/issues/12011
        '@ant-design/icons/lib/dist$': resolve('./src/vendor/ant-icons.js')
      }
    }
  }
}

src/vendor/ant-icons.js

// export what antd other components need
export { default as CloseOutline } from '@ant-design/icons/lib/outline/CloseOutline'
export { default as CheckOutline } from '@ant-design/icons/lib/outline/CheckOutline'
export { default as LoadingOutline } from '@ant-design/icons/lib/outline/LoadingOutline'
export { default as CheckCircleOutline } from '@ant-design/icons/lib/outline/CheckCircleOutline'
export { default as InfoCircleOutline } from '@ant-design/icons/lib/outline/InfoCircleOutline'
export { default as CloseCircleOutline } from '@ant-design/icons/lib/outline/CloseCircleOutline'
export { default as ExclamationCircleOutline } from '@ant-design/icons/lib/outline/ExclamationCircleOutline'
export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill'
export { default as InfoCircleFill } from '@ant-design/icons/lib/fill/InfoCircleFill'
export { default as CloseCircleFill } from '@ant-design/icons/lib/fill/CloseCircleFill'
export { default as ExclamationCircleFill } from '@ant-design/icons/lib/fill/ExclamationCircleFill'
export { default as UpOutline } from '@ant-design/icons/lib/outline/UpOutline'
export { default as DownOutline } from '@ant-design/icons/lib/outline/DownOutline'
export { default as LeftOutline } from '@ant-design/icons/lib/outline/LeftOutline'
export { default as RightOutline } from '@ant-design/icons/lib/outline/RightOutline'
export { default as RedoOutline } from '@ant-design/icons/lib/outline/RedoOutline'
export { default as CalendarOutline } from '@ant-design/icons/lib/outline/CalendarOutline'
export { default as SearchOutline } from '@ant-design/icons/lib/outline/SearchOutline'
export { default as BarsOutline } from '@ant-design/icons/lib/outline/BarsOutline'
export { default as StarFill } from '@ant-design/icons/lib/fill/StarFill'
export { default as FilterOutline } from '@ant-design/icons/lib/outline/FilterOutline'
export { default as CaretUpOutline } from '@ant-design/icons/lib/outline/CaretUpOutline'
export { default as CaretDownOutline } from '@ant-design/icons/lib/outline/CaretDownOutline'
export { default as PlusOutline } from '@ant-design/icons/lib/outline/PlusOutline'
export { default as FileOutline } from '@ant-design/icons/lib/outline/FileOutline'
export { default as FolderOpenOutline } from '@ant-design/icons/lib/outline/FolderOpenOutline'
export { default as FolderOutline } from '@ant-design/icons/lib/outline/FolderOutline'
export { default as PaperClipOutline } from '@ant-design/icons/lib/outline/PaperClipOutline'
export { default as PictureOutline } from '@ant-design/icons/lib/outline/PictureOutline'
export { default as EyeOutline } from '@ant-design/icons/lib/outline/EyeOutline'
export { default as DeleteOutline } from '@ant-design/icons/lib/outline/DeleteOutline'
export { default as UploadOutline } from '@ant-design/icons/lib/outline/uploadOutline'
export { default as EllipsisOutline } from '@ant-design/icons/lib/outline/EllipsisOutline'

// export what you need
// @see node_modules/@ant-design/icons/lib/index.es.js
export { default as LockOutline } from '@ant-design/icons/lib/outline/LockOutline'
export { default as InboxOutline } from '@ant-design/icons/lib/outline/InboxOutline'
export { default as UserOutline } from '@ant-design/icons/lib/outline/UserOutline'
export { default as RollbackOutline } from '@ant-design/icons/lib/outline/RollbackOutline'
export { default as PlusSquareOutline } from '@ant-design/icons/lib/outline/PlusSquareOutline'
export { default as MinusSquareOutline } from '@ant-design/icons/lib/outline/MinusSquareOutline'
export { default as ArrowDownOutline } from '@ant-design/icons/lib/outline/ArrowDownOutline'
export { default as EditOutline } from '@ant-design/icons/lib/outline/EditOutline'

process.env.NODE_ENV !== 'production' && console.warn('[Antd] Icon使用按需加载, 若缺失, 请到此处修改.')

2、自定义主题

vue.config.js

module.exports = {
  css: {
    loaderOptions: {
      less: {
        lessOptions: {
          // If you are using less-loader@5 please spread the lessOptions to options directly
          modifyVars: {
            'primary-color': '#1FCAC4'
          },
          javascriptEnabled: true
        }
      }
    }
  }
}

3、表格高度自适应

使用vue自定义指令实现

const install = function(Vue) {
  Vue.directive('ant-height-adaptive-table', adaptive)
}

if (window.Vue) {
  window['ant-height-adaptive-table'] = adaptive
  Vue.use(install); // eslint-disable-line
}

/**
 * How to use
 * <el-table height="100px" v-el-height-adaptive-table="{bottomOffset: 30}">...</el-table>
 * el-table height is must be set
 * bottomOffset: 30(default)   // The height of the table from the bottom of the page.
 */

const doResize = (el, binding, vnode) => {
  const { componentInstance: $table } = vnode

  const { value } = binding

  const bottomOffset = (value && value.bottomOffset) || 30

  if (!$table) return

  const $tableHead = el.querySelector('.ant-table-thead') || { clientHeight: 0 }
  const top = el.getBoundingClientRect().top

  if (top === 0) return

  const height = window.innerHeight - top - $tableHead.clientHeight - bottomOffset
  setTimeout(() => {
    // 设置table/list的高度
    const $tableBody = el.querySelector('.ant-table-body') || el.querySelector('.ant-list .ant-row')
    if (!$tableBody) return
    $tableBody.style.height = height + 'px'
    binding.value.setHeight(height)
  }, 0)
}

export default {
  bind(el, binding, vnode) {
    el.resizeListener = debounce(() => {
      doResize(el, binding, vnode)
    }, 100)
    // parameter 1 is must be "Element" type
    window.addEventListener('resize', el.resizeListener)
    vnode.componentInstance.$handleResize = function() {
      return doResize(el, binding, vnode)
    }
  },
  inserted(el, binding, vnode) {
    doResize(el, binding, vnode)
  },
  unbind(el) {
    window.removeEventListener('resize', el.resizeListener)
  },
  install
}

在组件中使用

<template>
    <a-table
      v-ant-height-adaptive-table="{bottomOffset: 105, setHeight: handleResizeTable}"
      :scroll="{y: scrollY}"
    />
</template>

<script>
import antHeightAdaptiveTable from '@/directive/ant-table'

export default {
    data() {
        return {
            scrollY: 300
        }
    },
    directives: {
    antHeightAdaptiveTable
  },
  methods: {
    /**
     * 响应式设置表格高度
     * @param {Number} height 表格高度
     */
    handleResizeTable(height) {
      this.scrollY = height
    }
  }
}
</script>

推荐阅读

恰饭区

评论区 0

0/500

还没有评论,快来抢第一吧