百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

iview 组件踩坑记 iview实例教程

ztj100 2024-12-25 16:49 23 浏览 0 评论

Modal 弹窗中再弹窗,关闭一个后禁止页面滚动会失效

Modal 弹窗的禁止滚动是用 scrollable 和 lockScroll 来设置是否弹窗后面的页面可以滚动,但是如果是在已经禁止滚动的弹窗中再弹这一个,关闭的时候会导致动态移除了 body 上的 overflow:hidden,会导致当前没关闭的弹窗一下后面的页面可以滚动了,所以可以直接加个判断,当前弹窗已经禁止滚动了,子弹窗的禁止滚动就设置成允许滚动,只用设置 lockScroll 这一个参数就行了

Modal 弹窗中的 Form 表单里的 Select 下拉选择组件校验问题

Form 表单默认的 async-validator 校验,校验规则里如果不指定数据类型,默认是 String,但是下拉选项里的枚举值后端有时会弄成 Number,所以要自己指定 type: 'number',否则校验会一直不通过。

校验触发 trigger 一般直接选的用 change,输入的用 blur。

注意 Modal + Form + Select时,如果 trigger: 'change',关闭弹窗或显示弹窗的时候,Select 的 on-change 事件有时会被莫名其妙触发,然后会触发校验,解决方法:

① 将 trigger 改成 blur;

② 弹出或关闭时都自己手动重置下表单校验 this.$refs['form'].resetFields()

<template>
  <Modal
    :value="value"
    title="编辑"
    @on-cancel="close"
    @on-ok="onOk"
  >
    <Form :model="form" :rules="rules" :label-width="100" class="form" ref="form">
      <FormItem label="类型" prop="type">
        <Select v-model="form.type" clearable placeholder="请选择类型">
          <Option :value="1">大船</Option>
          <Option :value="2">灰机</Option>
          <Option :value="3">卡车</Option>
        </Select>
      </FormItem>
      <FormItem label="名称" prop="name">
        <Input v-model="form.name" placeholder="请输入名称" />
      </FormItem>
    </Form>
  </Modal>
</template>

<script>
export default {
  name: 'modal-edit',
  props: {
    value: {
      type: Boolean,
      default: false
    },
    curRow: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      form: {
        type: null,
        name: ''
      },
      rules: {
        type: [{ required: true, message: '请选择类型', type: 'number', trigger: 'change|blur' }],
        name: [{ required: true, message: '请输入名称', trigger: 'change|blur' }]
        // phone: {
        //   required: true,
        //   trigger: 'change|blur',
        //   validator: (rule, value, callback) => {
        //     if (!value) {
        //       callback(new Error('请输入手机号'))
        //     } else if (!/^1[3-9]\d{9}$/.test(value)) {
        //       callback(new Error('手机号格式不正确'))
        //     } else {
        //       callback()
        //     }
        //   }
        // }
      },
      loading: false
    }
  },

  computed: {
    isEdit() {
      return !!this.curRow.id
    }
  },

  watch: {
    value(v) {
      if (v) {
        if (this.isEdit) {
          let { type, name } = this.curRow
          this.form = {
            type,
            name
          }
        } else {
          this.form = {
            type: null,
            name: ''
          }
        }
        this.$refs['form'].resetFields()
      } else {
        this.$refs['form'].resetFields()
      }
    }
  },

  methods: {
    onOk() {
      this.$refs['form'].validate(async (val) => {
        if (val) {
          console.log('success')
        }
      })
    },

    close() {
      this.$emit('input', false)
    }
  }
}
</script>
<style lang='stylus' scoped>
</style>

Menu、MenuItem菜单组件不能自动展开和异步控制渲染当前页刷新不能选中

手风琴模式,通过路由跳转到二级菜单,二级菜单不会自动展开,需要用户手动点一下,解决方式是去监听路由变化,然后调用 updateOpened 强制更新菜单展开。

在当前页面选中刷新,切当前菜单有异步控制渲染,会造成不能选中,解决办法监听异步值,调用 updateActiveName 强制更新

<template>
  <Menu ref="menu" active-name="1-2" :open-names="['1']">
    <Submenu name="1">
      <MenuItem name="1-1">Option 1</MenuItem>
      <MenuItem name="1-2">Option 2</MenuItem>
    </Submenu>
    <Submenu name="2">
      <MenuItem name="2-1">Option 3</MenuItem>
      <MenuItem v-if="showMenu" name="2-2">Option 4</MenuItem>
    </Submenu>
    <MenuItem name="3">Option 5</MenuItem>
  </Menu>
</template>
<script>
export default {
  data() {
    return {
      showMenu: false
    }
  },
  watch: {
    $route(v) {
      this.$nextTick(() => {
        this.$refs.menu && this.$refs.menu.updateOpened()
      })
    },
    showMenu(v) {
      // 页面刷新会造成不能选中,异步控制造成选中的类名 ivu-menu-item-active 不能加到 MenuItem 上去
      if (v) {
        this.$nextTick(() => {
          this.$refs.menu && this.$refs.menu.updateActiveName()
        })
      }
    },
  },
  create() {
    // 模拟异步
    setTimeout(() => {
      this.showMenu = true
    }, 10000)
  }
}
</script>

select组件加了filterable选择后输入框的值前后有空格的问题

可搜索 filterable 设置成 true 后,选择后输入框的值前后有空格会多出很多空格,造成显示错乱

最后发现是代码格式化的问题,加了 filterable 后选项 Option 里的文字不要换行,只要格式化换行了就会造成前后空格:

<template>
    <!-- 有问题的写法 -->
    <Select
        v-model="form.name"
        :filterable="true"
        clearable
        transfer
    >
        <Option
            v-for="(n, i) in options"
            :value="n.value"
            :key="i"
        >
            {{ n.name }}
        </Option>
    </Select>

    <!-- 推荐显示正常的写法:版本1 -->
    <Select
        v-model="form.name"
        :filterable="true"
        clearable
        transfer
    >
        <Option v-for="(n, i) in options" :value="n.value" :key="i">{{ n.name }}</Option>
    </Select>


    <!-- 推荐显示正常的写法:版本2 -->
    <Select
        v-model="form.name"
        :filterable="true"
        clearable
        transfer
    >
        <Option v-for="(n, i) in options" :value="n.value" :key="i" :label="c.name" />
    </Select>

    <!-- 额外发现的问题 -->
    <!-- 如果用了 Option 来自定义选项内容,记得一定要给 Option 加上 label 来指定选中后的显示值,否则选中后会出现选不中或者显示出自定义选项里面的全部内容 -->
    <Select
        v-model="form.name"
        :filterable="true"
        clearable
        transfer
    >
        <Option v-for="(n, i) in options" :value="n.value" :key="i" :label="n.name">
            <span>{{ n.name }}</span>
            <span style="float:right;color:#ccc">{{ n.statusName }}</span>
        </Option>
    </Select>
</template>

微信小程序里的 text 组件之前也遇到类似的问题,text 组件里的文字如果换行格式化,空格也会被保留,造成页面布局错乱。

page 分页组件

切换页数的 on-page-size-change 事件监听页数改变,我们一般会直接将传过来的 size 赋值给页数,然后手动载获取一下数据。但是这里 iview 有坑:在页码非第一页时会自动去触发页码改变事件获取数据,如果我们手动再去获取一次,其实会调用两次接口,如果是第一页,iview又不会主动去获取数据,通过查看组件源码:

// 页码改变
changePage (page) {
    if (this.disabled) return;
    if (this.currentPage != page) { // 在第一页改变页码时不会主动去获取数据
        this.currentPage = page;
        this.$emit('update:current', page);
        this.$emit('on-change', page);
    }
},

// 页数改变
onSize (pageSize) {
    if (this.disabled) return;
    this.currentPageSize = pageSize;
    this.$emit('on-page-size-change', pageSize);
    this.changePage(1);
},

改变页码获取数据时,最好加一个判断 this.page.index === 1 的判断再手动去获取数据或者自己手动改下 index = 1 再去获取数据,否则 在末尾几页触发 handlePageSize 在 index 还没变的时候去获取实际没有的页数数据会返回空(而这次的异步接口如果比自动触发的晚显示可能造成页面暂无数据)

handlePage(pageNum) {
    this.page.index = pageNum
    this.getList()
},

handlePageSize(size) {
    this.page.size = size

    // 页码为非1时会自动触发获取数据
    if (this.page.index === 1) this.getList()

    // 或者下面这样(不过非第一页会调两次接口,不推荐)
    // this.page.index = 1
    // this.getList()
},

Form 表单里的 InputNumber 组件校验一直不通过

明明输入框里已经有值了,校验一直报红,看控制台还报错:

[Vue warn]: Invalid prop: type check failed for prop "value". Expected Number with value 1, got String with value "1"

这里就是因为初始赋值的时候,直接将数值字符串直接赋值给了 InputNumber,Form 表单里的校验规则 rules 里又有指定 type 为 number,类型不一致导致校验不通过。

相关推荐

sharding-jdbc实现`分库分表`与`读写分离`

一、前言本文将基于以下环境整合...

三分钟了解mysql中主键、外键、非空、唯一、默认约束是什么

在数据库中,数据表是数据库中最重要、最基本的操作对象,是数据存储的基本单位。数据表被定义为列的集合,数据在表中是按照行和列的格式来存储的。每一行代表一条唯一的记录,每一列代表记录中的一个域。...

MySQL8行级锁_mysql如何加行级锁

MySQL8行级锁版本:8.0.34基本概念...

mysql使用小技巧_mysql使用入门

1、MySQL中有许多很实用的函数,好好利用它们可以省去很多时间:group_concat()将取到的值用逗号连接,可以这么用:selectgroup_concat(distinctid)fr...

MySQL/MariaDB中如何支持全部的Unicode?

永远不要在MySQL中使用utf8,并且始终使用utf8mb4。utf8mb4介绍MySQL/MariaDB中,utf8字符集并不是对Unicode的真正实现,即不是真正的UTF-8编码,因...

聊聊 MySQL Server 可执行注释,你懂了吗?

前言MySQLServer当前支持如下3种注释风格:...

MySQL系列-源码编译安装(v5.7.34)

一、系统环境要求...

MySQL的锁就锁住我啦!与腾讯大佬的技术交谈,是我小看它了

对酒当歌,人生几何!朝朝暮暮,唯有己脱。苦苦寻觅找工作之间,殊不知今日之事乃我心之痛,难道是我不配拥有工作嘛。自面试后他所谓的等待都过去一段时日,可惜在下京东上的小金库都要见低啦。每每想到不由心中一...

MySQL字符问题_mysql中字符串的位置

中文写入乱码问题:我输入的中文编码是urf8的,建的库是urf8的,但是插入mysql总是乱码,一堆"???????????????????????"我用的是ibatis,终于找到原因了,我是这么解决...

深圳尚学堂:mysql基本sql语句大全(三)

数据开发-经典1.按姓氏笔画排序:Select*FromTableNameOrderByCustomerNameCollateChinese_PRC_Stroke_ci_as//从少...

MySQL进行行级锁的?一会next-key锁,一会间隙锁,一会记录锁?

大家好,是不是很多人都对MySQL加行级锁的规则搞的迷迷糊糊,一会是next-key锁,一会是间隙锁,一会又是记录锁。坦白说,确实还挺复杂的,但是好在我找点了点规律,也知道如何如何用命令分析加...

一文讲清怎么利用Python Django实现Excel数据表的导入导出功能

摘要:Python作为一门简单易学且功能强大的编程语言,广受程序员、数据分析师和AI工程师的青睐。本文系统讲解了如何使用Python的Django框架结合openpyxl库实现Excel...

用DataX实现两个MySQL实例间的数据同步

DataXDataX使用Java实现。如果可以实现数据库实例之间准实时的...

MySQL数据库知识_mysql数据库基础知识

MySQL是一种关系型数据库管理系统;那废话不多说,直接上自己以前学习整理文档:查看数据库命令:(1).查看存储过程状态:showprocedurestatus;(2).显示系统变量:show...

如何为MySQL中的JSON字段设置索引

背景MySQL在2015年中发布的5.7.8版本中首次引入了JSON数据类型。自此,它成了一种逃离严格列定义的方式,可以存储各种形状和大小的JSON文档,例如审计日志、配置信息、第三方数据包、用户自定...

取消回复欢迎 发表评论: