Vant 2 - 移动端 Vue 组件库 _ 问题记录

news2025/2/24 4:01:43

目录

Popup 弹出层

DatetimePicker 时间选择

Field 输入框

Picker 选择器

List 列表

Tab 标签页


发布初衷 :

记录在移动端项目中使用 Vant  2 组件库时遇到的各种问题 ,

方便以后再次遇到类似问题 , 能够快时查阅解决 ,

大家要是觉得有帮助的话 , 可以收藏一下 , 博主会不定时更新文章的


Popup 弹出层

介绍

弹出层容器,用于展示弹窗、信息提示等内容,支持多个弹出层叠加展示。

问题记录 : Field 输入框 和 Popup 弹出层  两个 结合 使用 时 ,

在 iPhone 真机上测试的时候 出现的一个小 bug :

点击 Field 输入框 的时候 , 第一次会 弹出 一个 手机的键盘输入框

点击第二次的时候 才出来  Popup 弹出层 里面的内容 ( 比如 日期选择器 )

解决方案 : 

    给 Field 输入框 设置 readonly ,通过 readonly 将输入框设置为只读状态

输入框 van-field 必须得加入 readonly 这个 只读属性 ,

不然会导致 用户手机 触发 默认键盘 遮挡 你的弹窗和选择器内容 影响体验

也不要用 disabled 来禁用输入框 , 样式会变成禁用状态下的样式很难改动

只需要设置为只读即可 , 也不会触发手机键盘


DatetimePicker 时间选择

介绍

时间选择器,支持日期、年月、时分等维度,通常与弹出层组件配合使用。

确认选择的时间数据是需要自己处理的,详见 confirmPicker 方法 

<template>
  <div class="seller">
    <van-cell
      title="开始时间"
      is-link
      :value-class="className"
      :value="timeValue"
      @click="showPopup" />
    <van-popup v-model="show" position="bottom">
      <van-datetime-picker
        v-model="currentDate"
        type="datetime"
        title="选择时间"
        :loading="isLoadingShow"
        :min-date="minDate"
        :max-date="maxDate"
        :formatter="formatter"
        @cancel="show = false"
        @confirm="confirmPicker"
      />
    </van-popup>
  </div>
</template>

<script>
export default {
  name: 'Seller',
  data () {
    return {
      msg: '商家页面',
      timeValue: '请选择时间',
      show: false,
      isLoadingShow: true,
      currentDate: new Date(),
      minDate: new Date(),
      maxDate: new Date(2020, 12, 31),
      className: ''
    }
  },
  methods: {
    // 显示弹窗
    showPopup () {
      this.show = true
      this.isLoadingShow = true
      setTimeout(() => {
        this.isLoadingShow = false
      }, 500)
    },
    // 确认选择的时间
    confirmPicker (val) {
      let year = val.getFullYear()
      let month = val.getMonth() + 1
      let day = val.getDate()
      let hour = val.getHours()
      let minute = val.getMinutes()
      if (month >= 1 && month <= 9) { month = `0${month}` }
      if (day >= 1 && day <= 9) { day = `0${day}` }
      if (hour >= 0 && hour <= 9) { hour = `0${hour}` }
      if (minute >= 0 && minute <= 9) { minute = `0${minute}` }
      this.className = 'timeClass'
      this.timeValue = `${year}-${month}-${day} ${hour}:${minute}`
      this.show = false
    },
    // 选项格式化函数
    formatter (type, value) {
      if (type === 'year') {
        return `${value}年`
      } else if (type === 'month') {
        return `${value}月`
      } else if (type === 'day') {
        return `${value}日`
      } else if (type === 'hour') {
        return `${value}时`
      } else if (type === 'minute') {
        return `${value}分`
      } else if (type === 'second') {
        return `${value}秒`
      }
      return value
    }
  }
}
</script>

<style lang="stylus" rel="stylesheet/stylus" scoped>
.seller
  .timeClass {
    color: #333;
  }
</style>


Field 输入框

介绍

表单中的输入框组件。

问题记录 : Field 输入框 和 Popup 弹出层  两个 结合 使用 时 ,

iPhone 真机 上测试的时候 出现的一个小 bug :

点击 Field 输入框 的时候 , 第一次会 弹出 一个 手机的键盘输入框

点击第二次的时候 才出来  Popup 弹出层 里面的内容 ( 比如 日期选择器 )

解决方案 : 

    给 Field 输入框 设置 readonly ,通过 readonly 将输入框设置为只读状态

输入框 van-field 必须得加入 readonly 这个 只读属性 ,

不然会导致 用户手机 触发 默认键盘 遮挡 你的弹窗和选择器内容 影响体验

也不要用 disabled 来禁用输入框 , 样式会变成禁用状态下的样式很难改动

只需要设置为只读即可 , 也不会触发手机键盘


Picker 选择器

介绍

提供多个选项集合供用户选择,支持单列选择和多列级联,通常与弹出层组件配合使用。

业务场景 :

一开始以为只能渲染纯数组

但后来用的时候 , 后端返回来的数据结构是 数组嵌套对象的模式 ,

因此还特意将数组对象里面的数据专门筛选出来一个新数组用于渲染。。

但后来传参的时候需要数据结构里面的其他数据用于传参

所以又找了找这个Picker选择器可不可以渲染数组对象结构的案例 :

发现 [ {  } ]  , 是可以渲染的 ,只不过还要做一下处理 :


使用案例 :

<van-popup
  v-model="showTitle"
  position="bottom"
>
  <van-picker
    title="标题"
    show-toolbar

    value-key="name"

    :columns="columns"
    @confirm="onConfirm"
    @cancel="onCancel"
  />
</van-popup>
export default {
  data() {
    return {
      showTitle: false,
      columns: [], // 后端请求的数据
      queryFrom: {
        id: null,
        name: '',
      }
    };
  },
  methods: {
    onConfirm(value, index) {
      this.queryFrom.id = value.id // 需要传给后端的id值
      this.queryFrom.name = value.name // 用于渲染选择器列表数据
      this.showTitle = false // 关闭弹出层
    },
    onCancel() {
      this.showTitle = false
    },
  },
};

补充知识 :

vant-ui 之 Field 输入框 和 Picker 结合使用时 ,如何绑定正确的 id 类型的值的问题 。

很常见的需求 :

表单中的一项 ,需要从 picker 控件中选择正确的值后 ,展示的是字符串 ,

然后提交到后台服务器的则是字符串对应的 value 类型的值的问题。

点击表单的档案组,弹出 Picker 选择组件 ,选择正确的值 ,填充到表单项 ,但是 ,

提交到服务器去,需要提交对应的 id ,而不是看到的字符串。

如何实现 ?

定义两个属性,id 和 name , 两个是一 一对应的关系 。

在 van-picker 中 ,绑定的 confirm 函数 ,参数获取到的是一个对象 

在这个函数内,同时更新 id 和 name ,保证他俩一 一对应 。

  onConfirm(value, index) {
    this.queryFrom.id = value.id // 需要传给后端的id值
    this.queryFrom.name = value.name // 用于渲染选择器列表数据
    this.showTitle = false // 关闭弹出层
  },

如何展示 默认选中项

项目使用背景 :

用户填写表单时 , 需要根据上面填写的 乘车人数 来自动让下面的 Picker 选择器

下拉时 默认值 展示 与 人数相匹配 的 车辆类型

而又由于车辆类型是后端返回的数据 , 并不是固定不变的 , 所以前端没办法写死匹配方法

1、用户输入完 乘车人数 后 , 自动发起请求 , 由后端来匹配相对应的车辆类型

2、但是这里前端 Picker 组件需要用其索引值来展示下拉默认值 , 后端又无法返给我索引

3、前端这里只能先请求车辆类型数据列表后 , 再请求匹配车型数据值 , 循环去匹配后拿到当前匹配的索引值后再赋值给 Picker 组件


代码实现 :

根据乘车人数展示默认选中项
<van-picker
  show-toolbar
  title="车辆类型"
  value-key="dictLabel"
  :default-index="defaultMatch"
  :columns="applyType"
/>

data() {
  return {
    defaultMatch: 0, // 车辆类型下拉展示默认索引值
    applyType: [], // 车辆类型列表
  }
}

methods: {
  // 根据乘车人数自动匹配车辆类型
  async blurMatchType() {
  let arr = []
  // 先请求车辆类型列表数据用于匹配
  let res = await this.getDicts('car_apply_type')
  if (res.code == 200) arr = res.data
  // 根据乘车人数请求匹配的车辆类型值
  let ret = await getMatchType(this.userCarForm.riderNum)
  const { code, data } = ret
  if (code == 200) {
      // 循环匹配后赋值其索引值
      arr.forEach((item, index) => {
        if (item.dictValue == data) {
          this.defaultMatch = index
        }
      })
    }
  }
}

List 列表

介绍

瀑布流滚动加载,用于展示长列表,当列表即将滚动到底部时,会触发事件并加载更多列表项。

List 组件通过 loading 和 finished 两个变量控制加载状态,当组件滚动到底部时,会触发 load 事件并将 loading 设置成 true

此时可以发起异步操作并更新数据,数据更新完毕后,将 loading 设置成 false 即可。

若数据已全部加载完毕,则直接将 finished 设置成 true 即可。

<van-list
  v-model="loading"
  :finished="finished"
  :finished-text="appList.length ? '没有更多了' : ''"
  @load="onLoad"
>
  <van-cell v-for="item in appList" :key="item" :title="item" />
</van-list>

export default {
  data() {
    return {
      loading: false,
      finished: false,
      appList: [], // 用车申请列表
      appQuery: {
        page: '1', // 要查询的页码
        rows: '10', // 每页记录数量
        userId: null, // 用户 Id
      }
    };
  },
  methods: {
    async onLoad() {
      // 异步更新数据
      let ret = await getAppList(this.appQuery)
      const { code, data } = ret
      if (code == 200) {
        this.appList = this.appList.concat(data.rows)
        // 加载状态结束
        this.loading = false;
        if (this.appList.length >= data.total) {
          // 没有更多数据了
          this.finished = true;
          Notify({
            message: '已加载完全部订单',
            background: '#ee0a24'
          })
        } else {
          this.appQuery.page++
        }
      }
    },
  },
};

以上是正常情况下 , onLoad 滚动到底部可以正常触发加载下一页数据

接下来就是说明一个不正常使用情况 , 此 bug 组件库还未修复

就是 和 Tab 标签页 组件 公用 :

我猜估计是包裹内容的高度它无法断定了吧 , 所以 onLoad 加载就有问题了

Tab 标签页

<van-tabs v-model="active">
  <van-tab title="标签 1">
    <ApprovalItem type='1' />
  </van-tab>
  <van-tab title="标签 2">
    <ApprovalItem type='2' />
  </van-tab>
  <van-tab title="标签 3">
    <ApprovalItem type='3' />
  </van-tab>
  <van-tab title="标签 4">
    <ApprovalItem type='4' />
  </van-tab>
</van-tabs>

data() {
  return {
    active: 2,
  };
},

主要注意点就是子组件的高度需要设置一下 ,

一开始尝试的给 ApprovalItem 子组件一个高度  height:100% ,

但并没有解决一直触发 onLoad 加载的问题 ,

后来改成  height:100vh  , 就 OK 了 。。

没别的了 , 就是记录一下 , 提醒避坑 。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/405866.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3+TypeScript+Vite如何使用require动态引入类似于图片等静态资源

问题&#xff1a;Vue3TypeScriptVite的项目中如何使用require动态引入类似于图片等静态资源&#xff01; 描述&#xff1a;今天在开发项目时&#xff08;项目框架为Vue3TypeScriptVite&#xff09;需要 动态引入静态资源&#xff0c;也就是img标签的src属性值为动态获取&#…

Lodash 使用及常用方法

简介 Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。它内部封装了诸多对字符串、数组、对象等常见数据类型的处理函数,Lodash 通过降低 array、number、objects、string 等等的使用难度从而让 JavaScript 变得更简单。 官网 Lodash 简介 | Lodash 中文文档…

TypeScript详解十六:类型声明(declare)

目录前言一、类型声明的作用&#xff1f;1.1 declare 关键字1.2 示例二、常见的几种类型声明2.1 普通类型声明2.2 外部枚举2.3 命名空间三、类型声明文件3.1 模拟类型声明文件&#xff0c;以 jquery 为例3.2 使用手动实现的jquery.d.ts声明文件3.3 第三方声明文件&#xff08;以…

Django web 开发(三) - Django的使用

文章目录Django安装Django安装Pythonpip加速安装Django创建项目文件介绍简单访问APP添加新的app注册app创建blog的页面templates模板templates模板语法单一变量列表循环(列表)字典循环(字典)列表套字典条件判断请求和响应案例: 用户登录数据库操作安装第三方模块ORM创建数据库D…

node版本、npm版本随意切换

前言 随着项目越做越多&#xff0c;难免会有a项目需要12.x的node版本&#xff0c;b项目需要>16.0.0的情况。 为了避免出现node版本切换的繁琐&#xff0c;特意找了这么一个工具&#xff0c;主要是方便管理node版本。 请按照以下步骤来实现 官方地址: 传送门 1、下载软件 …

使用react实现后台管理系统项目

一.开发React必须依赖三个库 1.react&#xff1a;包含react所必须的核心代码 2.react-dom&#xff1a;react渲染在不同平台所需要的核心代码 3.babel&#xff1a;将jsx转换成React代码的工具 二.React的依赖引入 1.方式一&#xff1a;直接CDN引入 2.方式二&#xff1a;下载后&…

vue高级特性总结

文章目录一、修饰符1、事件修饰符案例1案例22、按键修饰符案例33、表单修饰符案例4二、计算属性computed案例5三、监听器watch案例6案例7&#xff1a;当商品数量大于1000时&#xff0c;输入框中数字自动设置成1000&#xff1b;当商品数量小于0时&#xff0c;输入框中数字自动设…

vue中如何使用vue-pdf及相应报错解决

目录 一、安装npm 依赖 二、引入组件 1、html中使用组件 单页 多页 2、数据处理 单页 多页 三、项目使用--代码部分 四、报错解决 前言 使用vue-pdf组件实现文件预览功能 并在文件上增加操作按钮vue3不支持vue-pdf&#xff0c;vue3项目用pdfjs-dist一、安装npm 依赖…

【Vue】Vue简介、引入、命令式和声明式编程

&#x1f4ad;&#x1f4ad; ✨&#xff1a; 开始陆陆续续更新vue啦   &#x1f49f;&#xff1a;东非不开森的主页   &#x1f49c;&#xff1a;如果有幸和你一起学习一起进步&#xff0c;那就太棒啦&#xff0c;一起学习吧。&#x1f49c;&#x1f49c;   初识vue一、初识…

从零入门开源框架---若依(前后端分离版)

一、若依是什么&#xff1f; 若依它就是一个开源项目&#xff0c;别人写好的代码&#xff0c;我们拿来进行二次开发,它主要是做数据和权限管理系统。 二、使用背景 任何公司的各种大的项目必然需要一个后台权限管理系统&#xff0c;这是必然的&#xff0c;但是如果不想投入太多…

windows安装yarn 详细教程

1、yarn介绍&#xff1a;yarn是一个代码包管理器&#xff0c;它允许我们与来自世界各地的其他开发人员共享代码。想要更多了解可以进入官网查看&#xff1a;https://yarnpkg.com/getting-started 2、进入yarn官网&#xff0c;可以看见官网已经声明从新版本(16.10)开始&#xf…

Vue项目二 登录注册功能的实现

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、系统注册功能的实现1.配置注册页面路由2.注册页面的搭建3.api下发送ajax请求的文件创建二、后台数据服务的创建1.app.js文件的建立2.User.js文件的建立3.配置…

目前最流行的 5 大 Vue 动画库,使用后太炫酷了

⭐️ 本文首发自 前端修罗场(点击加入)&#xff0c;是一个由 资深开发者 独立运行 的专业技术社区&#xff0c;我专注 Web 技术、答疑解惑、面试辅导以及职业发展。现在加入&#xff0c;私聊我即可获取一次免费的模拟面试机会&#xff0c;帮你评估知识点的掌握程度&#xff0c;…

vue3 antd项目实战——table表格的自定义筛选【纯前端filters过滤、自定义筛选table表格数据】

vue3 antd项目实战——table表格自定义筛选&#xff08;使用filters属性实现表头列columns自定义筛选&#xff09;往期知识调用&#xff08;步骤不懂就看这儿&#xff09;场景复现实战演示实例1——筛选发布状态&#x1f525;1、双向绑定表格列目录、表格数据2、编写列目录内容…

vue控制滚动条滑到某个位置

一.关于web开发的各种高度的计算介绍 设置当前滑动到的距离 语法一&#xff1a;window.scrollTop(x,y) 传俩个值 //x横坐标 y纵坐标 例&#xff1a;window.scrollTop(0&#xff0c;1000) 语法二&#xff1a;window.scrollTop(options) 传对象&#xff0c;对象里面放属性 w…

js遍历map(js遍历map对象)

javascript怎么遍历map var map new HashMap();map.put(a,1);map.put(b,2);遍历&#xff1a;var key map.keySet();for (var i in key){ alert(map.get(key[i]));&#xff5d;注&#xff1a;js 中使用map&#xff0c;要先导入一个HashMap.js文件 没要求&#xff0c;引入这个文…

【深入浅出imx8企业级开发实战 | 04】嵌入式Linux设备掉电数据容错研究

这是机器未来的第58篇文章 原文首发地址:https://robotsfutures.blog.csdn.net/article/details/126924015 《深入浅出i.MX8企业级开发实战》快速导航 【01】imx8qxp yocto工程构建指南 【02】Yocto工程repo源码gitee加速配置方法 【03】imx8qxp一键独立编译指南 【04】嵌入式…

三分钟创建一个新应用,ivx的神奇之处【PPT式程序开发】

像做PPT一样的可视化编程语言你想拥有吗&#xff0c;可以自己尝试一下。像PPT一样的编程语言 文章目录&#x1f353;&#x1f353;用ivx创建一个新的应用&#xff08;零基础&#xff09;&#x1f680;&#x1f680;&#x1f96d;&#x1f96d;点击链接&#xff0c;跳转到官网&a…

【Vue 路由(vue—router)二】路由传参(params的类型 、Query参数的类型、路由name)

目录 前言 一、路由传参 效果展示 1.params的类型 &#xff08;后附源码&#xff09; params的类型源码不要在意注释代码 2.​​​​​​query参数的类型&#xff08;后附源码&#xff09; query参数的类型源码同样无视注释代码 3.路由name 前言 此内容为连载&#xff0c…

一文搞懂JS-Web-API——DOM

&#x1f308;本系列文章是博主精心整理的面试热点问题&#xff0c;吸收了大量的技术博客与面试文章&#xff0c;总结多年的面试经历&#xff0c;带你快速建立前端面试知识体系。抓住每一场面试的机会&#xff0c;知己知彼才能百战百胜。直击技术痛点&#xff0c;主动出击&…