失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Vant 2 - 移动端 Vue 组件库 _ 问题记录

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

时间:2023-06-20 04:50:33

相关推荐

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

目录

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-celltitle="开始时间"is-link:value-class="className":value="timeValue"@click="showPopup" /><van-popup v-model="show" position="bottom"><van-datetime-pickerv-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(, 12, 31),className: ''}},methods: {// 显示弹窗showPopup () {this.show = truethis.isLoadingShow = truesetTimeout(() => {this.isLoadingShow = false}, 500)},// 确认选择的时间confirmPicker (val) {let year = val.getFullYear()let month = val.getMonth() + 1let 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-popupv-model="showTitle"position="bottom"><van-pickertitle="标题"show-toolbarvalue-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-pickershow-toolbartitle="车辆类型"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 } = retif (code == 200) {// 循环匹配后赋值其索引值arr.forEach((item, index) => {if (item.dictValue == data) {this.defaultMatch = index}})}}}

List 列表

介绍

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

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

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

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

<van-listv-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 } = retif (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 了 。。

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

如果觉得《Vant 2 - 移动端 Vue 组件库 _ 问题记录》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。