zoukankan      html  css  js  c++  java
  • 前端组件化封装及npm部署

    前端组件化封装及npm部署

    简介

    组件化思想是软件编程的一个重要思想。如汽车的生产,将轮子、灯、座椅等作为单独的组件,由各自的工厂去生产维护,各个组件都做好后再拿到组装厂统一组装使用。组件化思想就是将一个项目拆分成若干个组件,分而治之。

    组件化开发好处

    • 高复用性:复用的好处可以得到 较高的生产效率以及随之而来的成本降低、较高的软件质量(错误可以更快的被纠正)以及 恰当的使用复用可以改善系统的可维护性。
    • 低耦合性:低耦合就是指各模块依赖程度,减少模块间调用。

    高内聚和低耦合目的是使程序模块的可重用性、移植性大大增强。

    组件封装

    github地址:https://github.com/MengFangui/iview-table-page

    项目中经常使用表格和分页组件,目前比较流行的element UI,iview UI和Ant Design 3个UI库都有表格和分页组件,但是没有将表格和分页组件组合;同时分页组件都有一个bug,即电梯(快速跳转到某一页)没有绑定跳转事件。本文将以iview ui的Table和Page为例,简述前端组件封装和npm打包部署。

    iview-table-page 组件实现

    <template>
    <div>
         <Table
         :columns="columns"
         :data="data"
         :stripe='stripe'
         :border='border'
         :show-header='showHeader'
         :width='width'
         :height='height'
         :max-height='maxHeight'
         :loading='loading'
         :disabled-hover='disabledHover'
         :row-class-name='rowClassName'
         :size='size'
         :no-data-tex='noDataText'
         :no-filtered-data-text='noFilteredDataText'
         :draggable='draggable'
         :tooltip-theme='tooltipTheme'
         :row-key='rowKey'
         :highlight-row='highlightRow'
    
         @on-current-change='onCurrentChange'
         @on-select='onSelect'
         @on-select-cancel='onSelectCancel'
         @on-select-all='onSelectAll'
         @on-select-all-cancel='onSelectAllCancel'
         @on-selection-change='onSelectionChange'
         @on-sort-change='onSortChange'
         @on-filter-change='onFilterChange'
         @on-row-click='onRowClick'
         @on-row-dblclick='onRowDblclick'
         @on-expand='onExpand'
         @on-drag-drop='onDragDrop'>
          <template slot="header">
              <slot name='header'></slot>
          </template>
          <template slot="footer">
              <slot name='footer'></slot>
          </template>
          <template slot="loading">
              <slot name='loading'></slot>
          </template>
         </Table>
        <div :style="pageStyle" v-if="paginationShow">
            <Page
                :total="total"
                :current="current"
                :page-size='pageSize'
                :page-size-opts='pageSizeOpts'
                :placement='placement'
                :size='pageShapeSize'
                :simple='simple'
                :show-total='showTotal'
                :show-elevator='showElevator'
                :show-sizer='showSizer'
                :class-name='pageClassName'
                :styles='styles'
                :transfer='transfer'
                :prev-text='prevText'
                :next-text='nextText'
    
                @on-change='onChange'
                @on-page-size-change='onPageSizeChange'>
                <slot/>
                </Page>
        </div>
    </div>
    </template>
    
    <script>
    export default {
      name: 'iviewTablePage',
      props: {
        // 表格数据
        data: {
          type: Array,
          default: () => {
            return []
          }
        },
        // 表格列属性
        columns: {
          type: Array,
          default: () => {
            return []
          }
        },
        // 是否显示间隔斑马纹
        stripe: {
          type: Boolean,
          default: false
        },
        // 是否显示纵向边框
        border: {
          type: Boolean,
          default: false
        },
        // 是否显示表头
        showHeader: {
          type: Boolean,
          default: true
        },
        // 表格宽度,单位 px
         [String, Number],
        // 表格高度,单位 px,设置后,如果表格内容大于此值,会固定表头
        height: [String, Number],
        // 表格最大高度,单位 px,设置后,如果表格内容大于此值,会固定表头
        maxHeight: [String, Number],
        // 表格是否加载中
        loading: {
          type: Boolean,
          default: false
        },
        // 禁用鼠标悬停时的高亮
        disabledHover: {
          type: Boolean,
          default: false
        },
        // 是否支持高亮选中的行,即单选
        highlightRow: {
          type: Boolean,
          default: false
        },
        // 行的 className 的回调方法
        rowClassName: {
          type: Function,
          default: () => {
            return ''
          }
        },
        // 表格尺寸,可选值为 large、small、default 或者不填
        size: {
          type: String
        },
        // 数据为空时显示的提示内容
        noDataText: {
          type: String,
          default: '暂无数据'
        },
        // 筛选数据为空时显示的提示内容
        noFilteredDataText: {
          type: String,
          default: '暂无筛选结果'
        },
        // 是否开启拖拽调整行顺序,需配合 @on-drag-drop 事件使用
        draggable: {
          type: Boolean,
          default: false
        },
        // 列使用 tooltip 时,配置它的主题,可选值为 dark 或 light
        tooltipTheme: {
          type: String,
          default: 'dark'
        },
        // 是否强制使用内置的 row-key,开启后可能会影响性能
        rowKey: {
          type: Boolean,
          default: false
        },
        // 当前页码,支持 .sync 修饰符
        currentPage: {
          type: Number,
          default: 1
        },
        // 数据总数
        total: {
          type: Number,
          default: 0
        },
        // 每页条数
        pageSize: {
          type: Number,
          default: 10
        },
        // 每页条数切换的配置
        pageSizeOpts: {
          type: Array,
          default: () => {
            return [10, 20, 30, 40]
          }
        },
        // 条数切换弹窗的展开方向,可选值为 bottom 和 top
        placement: {
          type: String,
          default: 'bottom'
        },
        // 可选值为small(迷你版)或不填(默认)
        pageShapeSize: {
          type: String
        },
        // 简洁版
        simple: {
          type: Boolean,
          default: false
        },
        // 显示总数
        showTotal: {
          type: Boolean,
          default: false
        },
        // 显示电梯,可以快速切换到某一页
        showElevator: {
          type: Boolean,
          default: false
        },
        // 显示分页,用来改变page-size
        showSizer: {
          type: Boolean,
          default: false
        },
        // 自定义 class 名称
        pageClassName: {
          type: String,
          default: ''
        },
        // 自定义 style 样式
        styles: {
          type: Object,
          default: () => {
            return {}
          }
        },
        // 是否将弹层放置于 body 内,在 Tabs、带有 fixed 的 Table 列内使用时,建议添加此属性,它将不受父级样式影响,从而达到更好的效果
        transfer: {
          type: Boolean,
          default: false
        },
        // 替代图标显示的上一页文字
        prevText: {
          type: String,
          default: ''
        },
        // 替代图标显示的下一页文字
        nextText: {
          type: String,
          default: ''
        },
        // 是否显示页码
        paginationShow: {
          type: Boolean,
          default: true
        },
        paginationPosition: {
          type: String,
          default: 'right'
        }
      },
      data () {
        return {
          pageStyle: {
            'text-align': this.paginationPosition,
            margin: '16px 0'
          },
          current: 1
        }
      },
      methods: {
        // 开启 highlight-row 后有效,当表格的当前行发生变化的时候会触发
        onCurrentChange (...arg) {
          this.$emit('on-current-change', ...arg)
        },
        // 在多选模式下有效,选中某一项时触发
        onSelect (...arg) {
          this.$emit('on-select', ...arg)
        },
        // 在多选模式下有效,取消选中某一项时触发
        onSelectCancel (...arg) {
          this.$emit('on-select-cancel', ...arg)
        },
        // 在多选模式下有效,点击全选时触发
        onSelectAll (...arg) {
          this.$emit('on-select-all', ...arg)
        },
        // 在多选模式下有效,点击取消全选时触发
        onSelectAllCancel (...arg) {
          this.$emit('on-select-all-cancel', ...arg)
        },
        // 在多选模式下有效,只要选中项发生变化时就会触发
        onSelectionChange (...arg) {
          this.$emit('on-selection-change', ...arg)
        },
        // 排序时有效,当点击排序时触发
        onSortChange (...arg) {
          this.$emit('on-sort-change', ...arg)
        },
        // 筛选时有效,筛选条件发生变化时触发
        onFilterChange (...arg) {
          this.$emit('on-filter-change', ...arg)
        },
        // 单击某一行时触发
        onRowClick (...arg) {
          this.$emit('on-row-click', ...arg)
        },
        // 双击某一行时触发
        onRowDblclick (...arg) {
          this.$emit('on-row-dblclick', ...arg)
        },
        // 展开或收起某一行时触发
        onExpand (...arg) {
          this.$emit('on-expand', ...arg)
        },
        // 拖拽排序松开时触发,返回置换的两行数据索引
        onDragDrop (...arg) {
          this.$emit('on-drag-drop', ...arg)
        },
        // 页码改变的回调,返回改变后的页码
        onChange (...arg) {
          this.$emit('on-change', ...arg)
        },
        // 切换每页条数时的回调,返回切换后的每页条数
        onPageSizeChange (...arg) {
          this.$emit('on-page-size-change', ...arg)
        },
        // 表格方法
        // 清除高亮项,仅在开启 highlight-row 时可用
        clearCurrentRow (...arg) {
          this.$children[0].clearCurrentRow(...arg)
        },
        // 表格方法
        // 全选或者取消全选
        selectAll (status) {
          this.$children[0].selectAll(status)
        },
        // 表格方法
        exportCsv (...arg) {
          this.$children[0].exportCsv(...arg)
        }
      },
      mounted () {
        // 初始化页码
        this.current = this.currentPage
        let that = this
        // 获取跳转页码
        let dom = document.querySelector('.ivu-page-options-elevator input')
        if (dom) {
          // 定义事件onchange
          dom.onchange = function () {
            let pageNo = parseInt(dom.value, 10)
            if (!Number.isNaN(pageNo) && pageNo > 0 && pageNo <= that.total) {
              that.current = pageNo
            }
          }
        }
      }
    }
    </script>
    
    

    API 说明

    table 属性

    属性 说明 类型 默认值
    data 显示的结构化数据,其中,字段 cellClassName 用于设置任意单元格的样式名称,因此数据不能使用该字段,详见示例特定样式。 Array []
    columns 表格列的配置描述,具体项见后文 Array []
    stripe 是否显示间隔斑马纹 Boolean false
    border 是否显示纵向边框 Boolean false
    show-header 是否显示表头 Boolean false
    width 表格宽度,单位 px Number, String 自动
    height 表格高度,单位 px,设置后,如果表格内容大于此值,会固定表头 Number, String -
    max-height 表格最大高度,单位 px,设置后,如果表格内容大于此值,会固定表头 Number, String -
    loading 表格是否加载中 Boolean false
    disabled-hover 禁用鼠标悬停时的高亮 Boolean false
    highlight-row 是否支持高亮选中的行,即单选 Boolean false
    row-class-name 行的 className 的回调方法,传入参数:row:当前行数据, index:当前行的索引 Function -
    size 表格尺寸,可选值为 large、small、default 或者不填 String -
    no-data-text 数据为空时显示的提示内容 String 暂无数据
    no-filtered-data-text 筛选数据为空时显示的提示内容 String 暂无筛选结果
    draggable 是否开启拖拽调整行顺序,需配合 @on-drag-drop 事件使用 Boolean false
    tooltip-theme 列使用 tooltip 时,配置它的主题,可选值为 dark 或 light String dark
    row-key 是否强制使用内置的 row-key,开启后可能会影响性能 Boolean false

    table事件

    事件名 说明 返回值
    on-current-change 开启 highlight-row 后有效,当表格的当前行发生变化的时候会触发 currentRow:当前高亮行的数据, oldCurrentRow:上一次高亮的数据
    on-select 在多选模式下有效,选中某一项时触发 selection:已选项数据, row:刚选择的项数据, 即接收的参数是(selection,row)
    on-select-cancel 在多选模式下有效,取消选中某一项时触发 selection:已选项数据,row:取消选择的项数据
    on-select-all 在多选模式下有效,点击全选时触发 selection:已选项数据
    on-select-all-cancel 在多选模式下有效,点击取消全选时触发 selection:已选项数据
    on-selection-change 在多选模式下有效,只要选中项发生变化时就会触发 selection:已选项数据
    on-sort-change 排序时有效,当点击排序时触发 column:当前列数据,key:排序依据的指标,order:排序的顺序,值为 asc 或 desc
    on-filter-change 筛选时有效,筛选条件发生变化时触发 当前列数据
    on-row-click 单击某一行时触发 当前行的数据,index
    on-row-dblclick 双击某一行时触发 当前行的数据,index
    on-expand 展开或收起某一行时触发 row:当前行的数据,status:当前的状态
    on-drag-drop 拖拽排序松开时触发,返回置换的两行数据索引 index1, index2

    page 属性

    属性 说明 类型 默认值
    currentPage 当前页码 Number 1
    total 数据总数 Number 0
    page-size 每页条数 Number 10
    page-size-opts 每页条数切换的配置 Array [10, 20, 30, 40]
    placement 条数切换弹窗的展开方向,可选值为 bottom 和 top String bottom
    page-shape-size 可选值为small(迷你版)或不填(默认) String -
    simple 简洁版 Boolean false
    show-total 显示总数 Boolean false
    show-elevator 显示电梯,可以快速切换到某一页 Boolean false
    show-sizer 显示分页,用来改变page-size Boolean false
    page-class-name 自定义 class 名称 String -
    styles 自定义 style 样式 Object -
    transfer 是否将弹层放置于 body 内,在 Tabs、带有 fixed 的 Table 列内使用时,建议添加此属性,它将不受父级样式影响,从而达到更好的效果 Boolean false
    prev-text 替代图标显示的上一页文字 String -
    next-text 替代图标显示的下一页文字 String -

    新增属性

    属性 说明 类型 默认值
    pagination-show 是否显示页面 Boolean true
    pagination-position 页码位置 String 可选值为 left、center 和 right right

    其中大多数都是ivew UI上的事件和属性,新增了pagination-show和pagination-position属性。

    电梯(跳转到某一页)事件绑定实现

    获取跳转页面input dom,将dom绑定onchange事件。

    // 获取跳转页码dom
    let dom = document.querySelector('.ivu-page-options-elevator input')
    if (dom) {
      // 定义事件onchange
      dom.onchange = function () {
        let pageNo = parseInt(dom.value, 10)
        if (!Number.isNaN(pageNo) && pageNo > 0 && pageNo <= that.total) {
          that.current = pageNo
        }
      }
    

    demo

    iview-table-page 组件使用

    安装组件

    $ npm i --save iview-table-page
    or
    $ yarn add iview-table-page
    

    组件注册

    全局注册组件

    main.js中:

    import Vue from 'vue'
    import iviewTablePage from 'iview-table-page'
    Vue.use(iviewTablePage)
    
    局部注册组件
    <template>
    <div>
      <iviewTablePage
      border
      :columns="columns7"
      :data="data6"
      :total='total'
      >
      </iviewTablePage>
    </div>
    </template>
    
    <script>
    import iviewTablePage from 'iview-table-page'
    export default {
      components: { iviewTablePage },
      data () {
        return {
          columns7: [
            {
              title: 'Name',
              key: 'name',
              render: (h, params) => {
                return h('div', [
                  h('Icon', {
                    props: {
                      type: 'person'
                    }
                  }),
                  h('strong', params.row.name)
                ])
              }
            },
            {
              title: 'Age',
              key: 'age'
            },
            {
              title: 'Address',
              key: 'address'
            },
            {
              title: 'Action',
              key: 'action',
               150,
              align: 'center',
              render: (h, params) => {
                return h('div', [
                  h(
                    'Button',
                    {
                      props: {
                        type: 'primary',
                        size: 'small'
                      },
                      style: {
                        marginRight: '5px'
                      },
                      on: {
                        click: () => {
                          this.show(params.index)
                        }
                      }
                    },
                    'View'
                  ),
                  h(
                    'Button',
                    {
                      props: {
                        type: 'error',
                        size: 'small'
                      },
                      on: {
                        click: () => {
                          this.remove(params.index)
                        }
                      }
                    },
                    'Delete'
                  )
                ])
              }
            }
          ],
          data6: [
            {
              name: 'John Brown',
              age: 18,
              address: 'New York No. 1 Lake Park'
            },
            {
              name: 'Jim Green',
              age: 24,
              address: 'London No. 1 Lake Park'
            },
            {
              name: 'Joe Black',
              age: 30,
              address: 'Sydney No. 1 Lake Park'
            },
            {
              name: 'Jon Snow',
              age: 26,
              address: 'Ottawa No. 2 Lake Park'
            }
          ],
          total: 4
        }
      }
    }
    </script>
    

    npm 打包

    package.json核心配置

    "build-bundle": "vue-cli-service build --target lib --name iviewTablePage ./src/components/index.js",
    
    "main": "dist/iviewTablePage.umd.js",
    
    • 打包为lib。
    • 入口文件为umd规范的js。
    • keywords:便于搜索npm 包。
    • repository: 代码存放地址(一般是git地址)。
    • devDependencies: 你要发的包,所依赖的开发环境下的包。
    • dependencies:你要发的包,所依赖的线上环境下的包。

    package.json的完整配置见:https://github.com/MengFangui/iview-table-page/blob/master/package.json

    npm注册账号

    https://www.npmjs.com/signup

    发包

    在你将要发包的目录下,执行

    npm adduser
    
    npm publish
    

    到此完成前端组件化封装和npm打包部署工作。

  • 相关阅读:
    Python基础 | pandas中dataframe的整合与形变(merge & reshape)
    Python基础 | pandas中数据的筛选(index & subset)
    Python基础 | 关于“循环”那些事
    Python基础 | 数据文件的读写
    Python基础 | 字符串操作
    如何用数据说谎 How to lie with data
    浅谈“数据敏感度”
    爬虫 | IT桔子互联网公司死亡名单
    从一道面试题谈数据推算方法
    爬虫 | cnblog文章收藏排行榜(“热门文摘”)
  • 原文地址:https://www.cnblogs.com/mengfangui/p/12198654.html
Copyright © 2011-2022 走看看