Vue realizes that the left navigation menu can be dragged to change the width of the left navigation

Realize that the left navigation menu can be dragged to change the width of the navigation.
Realize the effect:
insert image description here

The general structure of html is like this

 <el-scrollbar
      id="leftmenu"
      v-resize="MuneResize"
      wrap-class="scrollbar-wrapper"
    >
      <el-menu
        :default-active="activeMenu"
        :collapse="isCollapse"
        :background-color="variables.menuBg"
        :text-color="variables.menuText"
        :unique-opened="false"
        :active-text-color="variables.menuActiveText"
        :collapse-transition="false"
        mode="vertical"
      >
        <sidebar-item
          v-for="route in routes"
          :key="route.path"
          :item="route"
          :base-path="route.path"
        />
      </el-menu>
    </el-scrollbar>
    <!-- 给个可以拖拽的标识 -->
    <div id="drap-meuline" />
 // 自定义指令 获取当前菜单的宽度
  directives: {
    
    
    resize: {
    
    
      // 指令的名称
      bind(el, binding) {
    
    
        // el为绑定的元素,binding为绑定给指令的对象
        let _width = "";
        function isReize() {
    
    
          const style = document.defaultView.getComputedStyle(el);
          if (_width !== style.width) {
    
    
            binding.value({
    
     width: style.width, targetId: el.id });
            _width = style.width;
          }
        }
        el.__vueSetInterval__ = setInterval(isReize, 300);
      },
      unbind(el) {
    
    
        clearInterval(el.__vueSetInterval__);
      },
    },
  },
mounted() {
    
    
    // 获取dom,对左菜单进行拖拽
    var drapLine = document.getElementById("drap-meuline");
    // 获取右侧内容Dom
    var mainContainer = document.getElementsByClassName("main-container")[0];
    // 获取左侧菜单Dom
    var menuleft = document.getElementById("leftmenu");
    // 获取左侧菜单Dom父元素,为了动态设置宽度
    var sidebarWidth = document.getElementsByClassName("sidebar-container")[0];

    // 是否需要本地保存
    // const history_width = localStorage.getItem("sliderWidth");
    // if (history_width) {
    
    
    //   sidebarWidth.style.width = history_width;
    //   mainContainer.style.marginLeft = history_width;
    // }
    drapLine.onmousedown = function (e) {
    
    
      // 设置最大/最小宽度
      var max_width = 600;
      var min_width = 210;
      let mouse_x = 0; // 记录鼠标相对left盒子x轴位置
      e.preventDefault(); // 阻止默认事件
      const _e = e || window.event;
      mouse_x = _e.clientX - menuleft.offsetWidth;
      document.onmousemove = function (e_) {
    
    
        console.log(min_width, max_width);
        const _e_ = e_ || window.event;
        let left_width = _e_.clientX - mouse_x;
        left_width = left_width < min_width ? min_width : left_width;
        left_width = left_width > max_width ? max_width : left_width;
        sidebarWidth.style.width = left_width + "px";
        mainContainer.style.marginLeft = left_width + "px";
      };
      document.onmouseup = function (e) {
    
    
        document.onmousemove = null;
        document.onmouseup = null;
        // 本地保存
        // localStorage.setItem("sliderWidth", menuleft.style.width);
      };
    };
  },

//拖拽宽度的改变
methods:{
    
    
 // 动态获取左侧菜单的宽度
   MuneResize(data) {
    
    
     // 拿到左侧菜单父元素
     const leftDom = document.getElementById(`${
      
      data.targetId}`);
     // 拿到右侧内容父元素
     const mainContainer =
       document.getElementsByClassName("main-container")[0];
       mainContainer.style.marginLeft = leftDom.clientWidth + "px";
    },
}

Approximate style:

#app .sidebar-container {
    
    
  display: flex;
}
#drap-meuline {
    
    
  background: transparent;
  width: 4px;
  cursor: e-resize; //设置鼠标悬浮上去显示可拖拽样式
}

Guess you like

Origin blog.csdn.net/weixin_45324044/article/details/126548265