Vant 2:van-popover组件气泡弹窗溢出屏幕的问题

van-popover组件文档中提供placement这个属性,用来控制气泡弹出位置,但是只能写死,无法传入函数或者传入‘auto’,搜了一下全网好像也没有提供这个问题的处理方案。

就会出现一个问题:当触发元素在视口底部,placement设置了'bottom',气泡就会溢出屏幕。

 

vant的githup仓库上也有这么一条issue提到这个问题:https://github.com/youzan/vant/issues/11600

官方的回复是,加入自动翻转的功能会令组件体积增大,需要评估是否加入,但是作者查看最新的V4版本也没加入,大概率是评估后觉得无需加入,所以还是维持现状。

 既然官方不打算支持,就自己在项目中给van-popover组件打个补丁,优化一下用户体验吧。

// src/patch/popover.js

import { Popover } from 'vant'


Popover.methods.onToggle = function (value) {
    this.$emit('input', value)
    setTimeout(_ => resetPlacement(this), 20)
}

/**
 * @description 根据气泡位置,重新设置placement的值,避免气泡显示位置溢出屏幕的问题
 * @param {*} that
 */
function resetPlacement(that) {
    const { wrapper, popover } = that.$refs
    
    // #reference插槽元素距离视口顶部的剩余距离
    const restTop = wrapper.getBoundingClientRect().top

    // #reference插槽元素距离视口底部的剩余距离
    const restBottom = window.innerHeight - wrapper.getBoundingClientRect().bottom

    // 气泡弹窗的总高度
    const popoverHeight = popover.$el.scrollHeight

    if (/bottom/.test(that.placement) && restBottom < popoverHeight) {
        that.placement = that.placement.replace('bottom', 'top') // 直接重置props的值虽然能生效,但vue会有报错,有待解决
        return
    }

    if (/top/.test(that.placement) && restTop < popoverHeight) {
        that.placement = that.placement.replace('top', 'bottom')
        return
    }
}

export default {
    install(Vue) {
        Vue.component(Popover.name, Popover)
    }
}


// src/main.js

import Popover from './patch/popover';
import Vue from 'vue'
Vue.use(Popover)

代码不多,思路也很简单:当点击refence插槽的元素触发气泡弹窗弹出后,判断一下如果H1小于H2,就说明气泡弹窗溢出了视口,就把方向重置一下,bottom改为top,同理,上下左右四个方向都是这样判断。 

但是这方案有个问题,就是直接设置了this.placement的值,这个属性是通过props传入的,也就是说,这样做会打破vue的单向数据流,vue会有报错:

但是实际使用的时候通常都是使用静态的字面量,在此组件的绝大部分使用场景中都不会有问题,哪位大神如果看到这,有更好的解决方案或者能去掉以上的报错提示,期待您在评论留言讨论。 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值