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打包部署工作。

  • 相关阅读:
    53. Maximum Subarray
    64. Minimum Path Sum
    28. Implement strStr()
    26. Remove Duplicates from Sorted Array
    21. Merge Two Sorted Lists
    14. Longest Common Prefix
    7. Reverse Integer
    412. Fizz Buzz
    linux_修改域名(centos)
    linux_redis常用数据类型操作
  • 原文地址:https://www.cnblogs.com/mengfangui/p/12198654.html
Copyright © 2011-2022 走看看