ant-design vue组件库使用后总结

1、form组件 自定义校验

template:

   <a-form-item
            fieldDecoratorId="articleNumber"
            label='编码:'
            :fieldDecoratorOptions="{rules: [{ required: true, message: '请输入编码!'},
            {max: 60, message: '编码不能超过60个字符!'},{validator: validateCode}]}"
          >
            <a-input class="with-count" placeholder="请输入相关内容" autocomplete="off"
              v-model="addOptions.productMainVo.articleNumber">
              <template slot="addonAfter">{{addOptions.productMainVo.articleNumber.length}}/60</template>
            </a-input>
          </a-form-item>

methods:

(1)校验不含中文字符
 validateCode (rule, value, callback) {
      let reg = new RegExp('[\\u4E00-\\u9FFF]+', 'g')
      if (value && reg.test(value)) {
        /* eslint-disable-next-line */
        callback('您输入的格式有误!')
        return
      }
      callback()
    }
(2)校验金额
    validateMoney (rule, value, callback) {
      if (value) {
        if (!isNaN(value)) {
          if (Number(value) > 10000000) {
            /* eslint-disable-next-line */
            callback('您输入的格式有误,金额最大值为10,000,000!')
            return
          } else if (isNaN((value + '').charAt(0))) {
            /* eslint-disable-next-line */
            callback('您输入的格式有误,金额首位请替换为数字!')
            return
          } else if (isNaN((value + '').charAt(value.length - 1))) {
            /* eslint-disable-next-line */
            callback('您输入的格式有误,金额末位请替换为数字!')
            return
          } else if ((value + '').indexOf('.') > -1 && (value + '').length - 1 - (value + '').indexOf('.') > 2) {
            /* eslint-disable-next-line */
            callback('您输入的格式有误,小数点后最多两位小数!')
            return
          } else {
            callback()
          }
        } else {
          /* eslint-disable-next-line */
          callback('您输入的格式有误,金额为数字!')
          return
        }
      }
      callback()
    }

2、解决带有下拉框的组件在滚动时 下拉框不跟随滚动的问题

api中有getPopupContainer
使用如下:

template:
  <a-select  :getPopupContainer="getPopupContainer">
       <a-select-option v-for="d in brandData" :key="d.id">{{d.brandName}}</a-select-option>
  </a-select>
methods:
 getPopupContainer (trigger) {
      return trigger.parentElement
}

但是级联选择组件 需要升级组件库版本到1.19不然此属性不生效

3、上传图片组件 , 一次上传一张,照片墙模式,可删除预览,限制图片格式和大小

template:

 <div class="upload-wrapper">
                <div class="upload-tip">建议尺寸:800 x 800 像素。仅支持 gif、 jpeg、 png、 bmp 4种格式, 大小不超过3.0 MB。</div>
                <div class="clearfix">
                  <a-upload
                    action="//qqq.com/upload/file"
                    name="file"
                    :data="{fileType: 'pic'}"
                    listType="picture-card"
                    :fileList="fileList"
                    :withCredentials="true"
                    @preview="handleUploadPreview"
                    @change="handleUploadChange"
                  >
                    <div>
                      <a-icon type="plus" />
                      <div class="ant-upload-text">添加图片</div>
                    </div>
                  </a-upload>
                  <a-modal :visible="previewVisible" :footer="null" @cancel="handleUploadCancel">
                    <img alt="example" style="width: 100%" :src="previewImage" />
                  </a-modal>
                </div>
              </div>

data:

  // 上传图片
      previewVisible: false, // 是否可预览图片
      previewImage: '', // 预览图片
      fileList: [], // 上传图片数据列表

methods:

    handleUploadCancel () {
      this.previewVisible = false
    },
    handleUploadPreview (file) {
      this.previewImage = file.url || file.thumbUrl
      this.previewVisible = true
    },
    handleUploadChange ({file, fileList}) {
      let pos = file.name.lastIndexOf('.')
      let lastName = file.name.substring(pos, file.name.length)
      let supportTypes = ['.gif', '.jpeg', '.png', '.bmp', '.jpg'] // gif、 jpeg、 png、 bmp
      if (supportTypes.indexOf(lastName.toLowerCase()) <= -1) {
        this.$message.error('商品图片仅支持 gif、 jpeg、 png、 bmp 4种格式!')
        return
      }
      if (file.size / (1024 * 1024) > 3) {
        this.$message.error('上传商品图片大小应小于3Mb!')
        return
      }
      this.fileList = fileList
      // 根据服务端返回数据筛选上传成功的文件
      let imgUrls = []
      fileList.forEach((file) => {
        if (file.response && file.response.code === '0') {
          imgUrls.push(file.response.data.fileInfo.url)
        }
      })
    },

4、自己写的popover弹框 ,组件自己的弹框在页面宽高变化的时候不好控制位置,会有错位,弹框跟不上触发弹框的按钮

template:

  <div class="add-btn-wrapper">
                    <a-button @click="" class="add-btn">
                      <a-icon type="plus" /> 添加
                    </a-button>
                      <div class="select-spec-val" v-show="ifCanAdd">
                        <div class="ant-popover-arrow"></div>
                      </div>
                  </div>

css:

  .add-btn-wrapper {
        position: relative;
        .ant-btn {
          min-width: 96px;
        }
    .add-btn {
        border: none;
        color: #40a9ff;
        min-width: 96px;
      }
        .select-spec-val {
          position: absolute;
          top: 45px;
          left: -92px;
          z-index: 3;
          padding: 12px 16px;
          color: rgba(0,0,0,.65);
          background-color: #fff;
          background-clip: padding-box;
          border-radius: 4px;
          box-shadow: 0 2px 8px rgba(0,0,0,.15);
          .ant-popover-arrow {
            position: absolute;
            top: -5px;
            left: 135px;
            box-shadow: -3px -3px 7px rgba(0,0,0,.07);
          }
        }
      }

5、合并table组件单元格 ,根据不同数据动态合并行

配置的列属性信息如下:

columns: [
        {
          title: 'www',
          dataIndex: 'we',
          scopedSlots: {customRender: 'we'}
        },
        {
          title: 'bbbb',
          dataIndex: 'er',
          scopedSlots: {customRender: 'er'},
          customRender: (value, row, index) => {
                const obj = {
                  children: value,
                  attrs: {}
                }
// m为要合并的单元格数,自己定
                if (index % m === 0) {
                  obj.attrs.rowSpan = m
                } else {
                  obj.attrs.rowSpan = 0
                }
                return obj
              }
        }
      ]

6、table 组件 选择本页 和 选择全部, 以及处理禁用选择项

  computed: {
    rowSelection () {
      const { selectedRowKeys } = this
      return {
        selectedRowKeys,
        onChange: this.onSelectChange,
// 处理禁用选择项
        getCheckboxProps: record => {
          return {
            props: {
              disabled: this.disabledRowKeys.indexOf(record.key) > -1
            }
          }
        },
        hideDefaultSelections: true,
        selections: [
          {
            key: 'page-data',
            text: '本页全选',
            onSelect: (changableRowKeys) => {
              this.selectedRowKeys = changableRowKeys
              this.selectWholePages = false
            }
          },
          {
            key: 'all-data',
            text: '全部选择',
            onSelect: (changableRowKeys) => {
              this.selectedRowKeys = [...Array(this.pagination.totalCount).keys()]
            }
          }],
        onSelection: this.onSelection
      }
    },
  },

data:

 selectedRowKeys: []

methods:

//  这个方法中只监听选择框的选中和取消,  不监听自定义的选择本页和选择全部
  onSelectChange (selectedRowKeys) {
// 里面的处理逻辑  按自己需求写即可
      this.selectedRowKeys = selectedRowKeys
    },

7、自己再封装的分页组件

<template>
  <div class="page-wrapper text-right">
    <a-pagination
      class="page-content"
      :pageSizeOptions="['10', '20', '30', '40', '50']"
      showSizeChanger
      :total="total"
      :pageSize="pageSize"
      :current="current"
      @change="onChange"
      @showSizeChange="onShowSizeChange"
    >
      <template slot='buildOptionText' slot-scope='props'>
        <span v-if="props.value!=='50'">{{props.value}}条/页</span>
        <span v-if="props.value==='50'">50条/页</span>
      </template>
    </a-pagination>
    <span class="total">共 {{total}} 条</span>
  </div>
</template>

<script>
export default {
  data () {
    return {
    }
  },
  props: {
    total: {
      require: true,
      type: Number
    },
    pageSize: {
      require: true,
      type: Number
    },
    current: {
      require: true,
      type: Number
    }
  },
  methods: {
    onChange (current, pageSize) {
      this.$emit('onChange', current, pageSize)
    },
    onShowSizeChange (current, pageSize) {
      this.$emit('onShowSizeChange', current, pageSize)
    }
  }
}
</script>

<style lang='scss' rel="stylesheet/scss" type="text/scss">

</style>

使用如下:

template:
      <custom-pagination
        :total="pagination.totalCount"
        :pageSize="pagination.pageSize"
        :current="pagination.pageNo"
        @onChange="onChangePage"
        @onShowSizeChange="onShowSizeChangePage"
      ></custom-pagination>

script:
import CustomPagination from 'components/pagination/index.vue'

data: 
   pagination: {
        pageNo: 1,
        pageSize: 10,
        totalCount: 0
      },

methods:
    onChangePage (pageNo, pageSize) {
      this.pagination.pageNo = pageNo
      // 重新请求数据
    },
    onShowSizeChangePage (pageNo, pageSize) {
      this.pagination.pageSize = pageSize
      // 重新请求数据
    },

8、上传压缩包, 校验只能上传zip压缩包

template:

 <a-upload :multiple="false" :fileList="fileList"
            name="file"
            :data="{fileType: 'zip'}"
            accept="*.zip"
            :withCredentials="true"
            action="//qqq.com/file" @change="uploadZip">
            <a-button>
              <a-icon type="upload" />
            </a-button>
          </a-upload>

data:

   fileList: [],

methods:

    uploadZip (info) {
      let pos = info.file.name.lastIndexOf('.')
      let lastName = info.file.name.substring(pos, info.file.name.length)
      if (lastName.toLowerCase() === '.zip') {
        this.fileList = info.fileList.slice(-1)
        this.loadedFile = info.file
        let res = info.file.response
        if (res) {
          if (res.code === '0') {
            this.$message.success('文件上传成功')
          } else {
            this.$message.error(res.message)
          }
        }
      } else {
        this.$message.error('只能上传zip压缩包')
      }
    },

9、格式化金额数字为小数点后两位,没有就补0

  filters: {
    money (num) {
      if (!/^(\d+)(\.\d*)?$/.test(num)) {
        return ''
      }
      let strNum = num + ''
      let number = num
      if (strNum.indexOf('.') > -1) {
        number = num.toFixed(2)
      } else {
        number = num + '.00'
      }
      strNum = number + ''
      let font = strNum.substring(0, strNum.indexOf('.'))
      let back = strNum.substring(strNum.indexOf('.'))
      let mod = font.length % 3
      let output = (mod === 0 ? '' : (font.substring(0, mod)))
      for (let i = 0; i < Math.floor(font.length / 3); i++) {
        if ((mod === 0) && (i === 0)) {
          output += font.substring(mod + 3 * i, mod + 3 * i + 3)
        } else {
          output += ',' + font.substring(mod + 3 * i, mod + 3 * i + 3)
        }
      }
      return output + back
    }
  },

10、文字两端对齐,pc端

css:

    .item-title {
      background-color: transparent;
      border: none;
      font-family: PingFang-SC-Medium;
      font-size: 14px;
      color: #666;
      padding: 0 11px;
      line-height: 32px;
      width: 126px;
      text-align:justify;
      text-justify:distribute-all-lines;/*ie6-8*/
      text-align-last:justify;/* ie9*/
      -moz-text-align-last:justify;/*ff*/
      -webkit-text-align-last:justify;/*chrome 20+*/
    }

11、model组件 确认弹框中内容使用自定义的标签

     let self = this
      this.$confirm({
        centered: true,
        maskClosable: true,
        title: '确认吗?',
// 注意此处写法   JSX support
        content: (  
          <div>
            <p>信息1:{row.msg1}</p>
            <p>信息2:{row.msg2}</p>
          </div>
        ),
        onOk () {
          let params = {}
          }
          self.request(params)
        },
        onCancel() {}
      })
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容