记录生活中的点滴,分享、学习、创新
最近在使用vue的时候,遇到一个需求,实现左右div可通过中间部分拖拽调整宽度,本文就整理一下,分享给大家,具体如下:
效果图

整体使用flex布局

在左侧面板与右侧面板之间添加一个隐藏的盒子,我将这个盒子隐藏在box-shadow之中。具体事件放在这个div中实现
1 2  | <div id="line" class="w-2 cursor-move hidden md4:block"onMousedown={hnadleMouseDown}></div> | 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40  | const hnadleMouseDown = (evt: MouseEvent) => {  /* 获取起始点位,并存储 */  let { pageX, pageY } = evt;  basePosition.pageX = pageX;  basePosition.pageY = pageY;  /* 监听鼠标的移动事件 */  document.addEventListener("mousemove", handleMouseMove);  document.addEventListener("mouseup", handleMouseUp);};const handleMouseMove = evt => {  /* 阻止浏览器默认事件,防止触发浏览器的手势功能 */  evt.preventDefault();  /* 设置定时器,防止dom多次回流 */  clearTimeout(timer.value);  timer.value = setTimeout(() => {    let { pageX } = evt;    const baseDiv = document.querySelector(".right-border-shadow");    /* 处理宽度,是否处于最大值/最小值之间 */    let baseWidth: Number | undefined =      Number(baseDiv?.clientWidth) + (pageX - basePosition.pageX);    baseWidth =      baseWidth > Number(props?.maxWidth) ? props.maxWidth : baseWidth;    baseWidth =      Number(baseWidth) < Number(props?.minWidth)        ? props.minWidth        : baseWidth;    baseDiv?.setAttribute("style", `width:${baseWidth}px`);    /* emit宽度改变的事件 */    ctx.emit("drugend");    /* 存储到store */    setStore(baseWidth);  }, 50);};const handleMouseUp = evt => {  /* 结束拖动之后,取消事件监听,并emit出最终宽度 */  const width = document.querySelector(".right-border-shadow")?.clientWidth;  document.removeEventListener("mousemove", handleMouseMove);  document.removeEventListener("mouseup", handleMouseUp);  ctx.emit("drugend", width);}; | 
1 2 3 4 5 6 7  | style={`width:${            store.get("split-width")              ? store.get("split-width")              : props.minWidth              ? props.minWidth              : 384          }px`} | 
手动改变浏览器视窗宽度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22  | nextTick(() => {        ctx.emit("load", ctx);        MutationObserver = window.MutationObserver;        if (MutationObserver) {          /* 监听浏览器的窗口变化,在部分情况下需要这个api */          mo = new MutationObserver(function() {            const __wm = document.querySelector("#rezie-id");            // 只在__wm元素变动才重新调用 __canvasWM            if (!__wm) {              // 避免一直触发              mo.disconnect();              mo = null;              ctx.emit("resize");            }          });          mo.observe(document.querySelector("#rezie-id"), {            attributes: true,            subtree: true,            childList: true,          });        }      }); | 
未生效,求指点
父组件的onMounted钩子中获取子元素的slot元素节点报错,为null。目前的解决办法是在子组件的onMounted钩子中抛出一个load事件,父组件使用onLoad去处理接下来的逻辑。