解决ant-design Vue3.x中的date-picker弹出事件无效

项目场景:

之前在项目中使用到了ant-design的date-picker组件,需求是在日期框中为直播过的日期添加一些提醒。使用时候发现panelChange设置无效

翻看源码

1.在3.x的分支中可以看到generateSinglePicker这个组件是绑定了panelChange这个事件的
在这里插入图片描述
2.于是又去看了vc-picker组件,发现没有接受这个事件。
在这里插入图片描述
到这里其实就已经知道原因了,现在想的是如何解决。
1.升级库的版本(升级到最新的版本4.x),但是直接升级可能会出现不兼容的情况,引发新的bug。
2.直接修改lib下面的vc-picker(更不推荐),如果需要更新该库到新版本,你将无法直接使用包管理工具(如npm或yarn)进行更新,因为任何更新操作都可能会覆盖你的修改。
3.自己重新封装一个自定义的panelChange事件。
其实只有方法3最可行,正好MutationObserver这一新的webAPI可以满足这一需求。

Mutation Observer

Mutation Observer API 用来监视 DOM 变动。DOM 的任何变动,比如节点的增减、属性的变动、文本内容的变动,这个 API 都可以得到通知。
概念上,它很接近事件,可以理解为 DOM 发生变动就会触发 Mutation Observer 事件。但是,它与事件有一个本质不同:事件是同步触发,也就是说,DOM 的变动立刻会触发相应的事件;Mutation Observer 则是异步触发,DOM 的变动并不会马上触发,而是要等到当前所有 DOM 操作都结束才触发。
Mutation Observer 有以下特点

  • 它等待所有脚本任务完成后,才会运行(即异步触发方式)
  • 它把 DOM 变动记录封装成一个数组进行处理,而不是一条条个别处理 DOM 变动
  • 它既可以观察 DOM 的所有类型变动,也可以指定只观察某一类变动。

解决方案:

直接利用MutationObserver来观察dom变动,然后执行响应的代码:
1.确定要观察的对象,我这里直接观察的是header,当左右筛选月份时去调响应的接口,拿到直播日期再做处理。
在这里插入图片描述
2.确定点击的是左边还是右边,点击的是年份还是月份。
我这里利用的将点击的数据存入数组,下次的点击的时候再作比较。

      const observeDatePickerChanges = () => {
        const datePicker = datePickerRef.value.$el;
        const parentNode = datePicker.parentElement;
        nextTick(() => {
          const headerView = parentNode.querySelector('.ant-picker-header');
          observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
              //TODO:区分点击的是月份还是年份
              const textContent: string = mutation.target.textContent!;
              if (/^\d+月$/.test(textContent)) {
                // 点击的是月份
                const month = parseInt(textContent);
                monthDateStack.value.push(month);
                fetchActivities();
              } else if (/^\d+年$/.test(textContent)) {
                // 点击的是年份
                const year = parseInt(textContent);
                yearDateStack.value.push(year);
                fetchActivities();
              }
            });
          });

          observer.observe(headerView, {
            childList: true,
            subtree: true,
            characterData: true,
          });
        });
      };
      onBeforeUnmount(()=>{
          yearDateStack.value = []; // 清空 yearDateStack 数组
          monthDateStack.value = []; // 清空 monthDateStack 数组
      })
            const stopObservingDatePickerChanges = () => {
        if (observer) {
          observer.disconnect(); // 停止 MutationObserver 的监听
          observer = null; // 释放 MutationObserver
        }
      };

      const getLivesProducts = async (status: boolean) => {
        // 触发自定义的openChange事件
        if (status) {
          observeDatePickerChanges();
          fetchActivities();
        } else {
          emit('transfeTime', selectedDate.value)
          stopObservingDatePickerChanges();
        }

3.当然还有需要处理的是当直接选择月份和年份也要观察(不是左右箭头选择)。不过因为需求急,而且ant-design date-picker可以设置
mode=“date”,不让选择。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值