vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法

1、先上个截图:

说明:拖动上面的分隔栏就可以实现,改变左右区域的大小。

2、上面的例子来自官网的:

Container 布局容器 | Element Plus

3、拖动的效果来自:

https://juejin.cn/post/7029640316999172104#heading-1

4、我们将二个效果,进行了组合,代码:

<template>
  <el-container class="box" style="height: 100vh">
    <el-aside width="200px" class="left">
      <el-scrollbar>
        <el-menu :default-openeds="['1', '3']">
          <el-sub-menu index="1">
            <template #title>
              <el-icon><message /></el-icon>Navigator One
            </template>
            <el-menu-item-group>
              <template #title>Group 1</template>
              <el-menu-item index="1-1">Option 1</el-menu-item>
              <el-menu-item index="1-2">Option 2</el-menu-item>
            </el-menu-item-group>
            <el-menu-item-group title="Group 2">
              <el-menu-item index="1-3">Option 3</el-menu-item>
            </el-menu-item-group>
            <el-sub-menu index="1-4">
              <template #title>Option4</template>
              <el-menu-item index="1-4-1">Option 4-1</el-menu-item>
            </el-sub-menu>
          </el-sub-menu>
          <el-sub-menu index="2">
            <template #title>
              <el-icon><icon-menu /></el-icon>Navigator Two
            </template>
            <el-menu-item-group>
              <template #title>Group 1</template>
              <el-menu-item index="2-1">Option 1</el-menu-item>
              <el-menu-item index="2-2">Option 2</el-menu-item>
            </el-menu-item-group>
            <el-menu-item-group title="Group 2">
              <el-menu-item index="2-3">Option 3</el-menu-item>
            </el-menu-item-group>
            <el-sub-menu index="2-4">
              <template #title>Option 4</template>
              <el-menu-item index="2-4-1">Option 4-1</el-menu-item>
            </el-sub-menu>
          </el-sub-menu>
          <el-sub-menu index="3">
            <template #title>
              <el-icon><setting /></el-icon>Navigator Three
            </template>
            <el-menu-item-group>
              <template #title>Group 1</template>
              <el-menu-item index="3-1">Option 1</el-menu-item>
              <el-menu-item index="3-2">Option 2</el-menu-item>
            </el-menu-item-group>
            <el-menu-item-group title="Group 2">
              <el-menu-item index="3-3">Option 3</el-menu-item>
            </el-menu-item-group>
            <el-sub-menu index="3-4">
              <template #title>Option 4</template>
              <el-menu-item index="3-4-1">Option 4-1</el-menu-item>
            </el-sub-menu>
          </el-sub-menu>
        </el-menu>
      </el-scrollbar>
    </el-aside>
    <div class="resize"></div>
    <el-container class="mid">
      <el-header style="text-align: right; font-size: 12px">
        <div class="toolbar">
          <el-dropdown>
            <el-icon style="margin-right: 8px; margin-top: 1px">
              <setting />
            </el-icon>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item>View</el-dropdown-item>
                <el-dropdown-item>Add</el-dropdown-item>
                <el-dropdown-item>Delete</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
          <span>Tom</span>
        </div>
      </el-header>

      <el-main>
        <el-scrollbar>
          <el-table :data="tableData">
            <el-table-column prop="date" label="Date" width="140" />
            <el-table-column prop="name" label="Name" width="120" />
            <el-table-column prop="address" label="Address" />
          </el-table>
        </el-scrollbar>
      </el-main>
    </el-container>
  </el-container>
</template>

<script lang="ts" setup>
import { onMounted, onUnmounted, ref } from "vue";
import { Menu as IconMenu, Message, Setting } from "@element-plus/icons-vue";

const item = {
  date: "2016-05-02",
  name: "Tom",
  address: "No. 189, Grove St, Los Angeles",
};
const tableData = ref(Array.from({ length: 20 }).fill(item));

function dragControllerDiv() {
  var resize = document.getElementsByClassName("resize");
  var left = document.getElementsByClassName("left");
  var mid = document.getElementsByClassName("mid");
  var box = document.getElementsByClassName("box");
  for (let i = 0; i < resize.length; i++) {
    // 鼠标按下事件
    resize[i].onmousedown = function (e) {
      //颜色改变提醒
      resize[i].style.background = "#818181";
      var startX = e.clientX;
      resize[i].left = resize[i].offsetLeft;
      // 鼠标拖动事件
      document.onmousemove = function (e) {
        var endX = e.clientX;
        var moveLen = resize[i].left + (endX - startX); // (endx-startx)=移动的距离。resize[i].left+移动的距离=左边区域最后的宽度
        var maxT = box[i].clientWidth - resize[i].offsetWidth; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度

        if (moveLen < 32) moveLen = 32; // 左边区域的最小宽度为32px
        if (moveLen > maxT - 150) moveLen = maxT - 150; //右边区域最小宽度为150px

        resize[i].style.left = moveLen; // 设置左侧区域的宽度

        for (let j = 0; j < left.length; j++) {
          left[j].style.width = moveLen + "px";
          mid[j].style.width = box[i].clientWidth - moveLen - 10 + "px";
        }
      };
      // 鼠标松开事件
      document.onmouseup = function (evt) {
        //颜色恢复
        resize[i].style.background = "#d6d6d6";
        document.onmousemove = null;
        document.onmouseup = null;
        resize[i].releaseCapture && resize[i].releaseCapture(); //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
      };
      resize[i].setCapture && resize[i].setCapture(); //该函数在属于当前线程的指定窗口里设置鼠标捕获
      return false;
    };
  }
}

onMounted(() => {
  dragControllerDiv();
});
</script>

<style scoped>
.layout-container-demo .el-header {
  position: relative;
  background-color: var(--el-color-primary-light-7);
  color: var(--el-text-color-primary);
}
.layout-container-demo .el-aside {
  color: var(--el-text-color-primary);
  background: var(--el-color-primary-light-8);
}
.layout-container-demo .el-menu {
  border-right: none;
}
.layout-container-demo .el-main {
  padding: 0;
}
.layout-container-demo .toolbar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  right: 20px;
}

/* 拖拽相关样式 */
/*包围div样式*/
.box {
  width: 100%;
  height: 100%;
  margin: 1% 0px;
  overflow: hidden;
  box-shadow: -1px 9px 10px 3px rgba(0, 0, 0, 0.11);
}
/*左侧div样式*/
.left {
  width: calc(32% - 10px); /*左侧初始化宽度*/
  height: 100%;
  background: #ffffff;
  float: left;
}
/*拖拽区div样式*/
.resize {
  cursor: col-resize;
  float: left;
  position: relative;
  top: 45%;
  background-color: #d6d6d6;
  border-radius: 5px;
  margin-top: -10px;
  width: 10px;
  height: 50px;
  background-size: cover;
  background-position: center;
  /*z-index: 99999;*/
  font-size: 32px;
  color: white;
}
/*拖拽区鼠标悬停样式*/
.resize:hover {
  color: #444444;
}
/*右侧div'样式*/
.mid {
  float: left;
  width: 68%; /*右侧初始化宽度*/
  height: 100%;
  background: #fff;
  box-shadow: -1px 4px 5px 3px rgba(0, 0, 0, 0.11);
}
</style>

5、通过上面的代码,我们可以很轻松的实现拖动改变左右二侧区域的大小,说明:

document.getElementsByClassName:返回一个类似数组的对象,包含了所有指定 class 名称的子元素。比如document.getElementsByClassName("left"); 是查找class="left"的所有的elements。

document.onmousemove = function (e) {
        var endX = e.clientX;
        var moveLen = resize[i].left + (endX - startX); // (endx-startx)=移动的距离。resize[i].left+移动的距离=左边区域最后的宽度
        var maxT = box[i].clientWidth - resize[i].offsetWidth; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度

        if (moveLen < 32) moveLen = 32; // 左边区域的最小宽度为32px
        if (moveLen > maxT - 150) moveLen = maxT - 150; //右边区域最小宽度为150px

        resize[i].style.left = moveLen; // 设置左侧区域的宽度

        for (let j = 0; j < left.length; j++) {
          left[j].style.width = moveLen + "px";
          mid[j].style.width = box[i].clientWidth - moveLen - 10 + "px";
        }
      };

这里的left[j],mid[j], length=1的时候,就是第一个元素,也就是我们左侧导航与右侧数据。

容器宽度 = 左边区域的宽度 + resize的宽度 + 右边区域的宽度

resize[0]的left就是左侧的宽度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/910880.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio加载旧的安卓工程项目报错处理

文章目录 Invalid Gradle JDK configuration foundNDK not configuredCMake 3.10.2 was not found安装cmake适配cmake版本号 com.intellij.openapi.externalSystem.model.ExternalSystemExceptiongradle版本过低或下载不了下载gradle与依赖库超时替换gradle国内源替换Maven 仓库…

Qt中的Model与View 4:QStandardItemModel与QTableView

目录 QStandardItemModel API QTableView 导航 视觉外观 坐标系统 API 样例&#xff1a;解析一个表格txt文件 QStandardItemModel QStandardItemModel 可用作标准 Qt 数据类型的存储库。它是模型/视图类之一&#xff0c;是 Qt 模型/视图框架的一部分。它提供了一种基于…

web——sqliabs靶场——第一关

今天开始搞这个靶场&#xff0c;从小白开始一点点学习,加油&#xff01;&#xff01;&#xff01;&#xff01; 1.搭建靶场 注意点&#xff1a;1.php的版本问题&#xff0c;要用老版本 2.小p要先改数据库的密码&#xff0c;否则一直显示链接不上数据库 2.第一道题&#xff0…

Markdown快速上手(typora)

一级标题~六级标题 可以选中文本在这里直接设置&#xff0c;后面也有快捷键&#xff0c;也可以使用其语法&#xff0c;一个#&#xff0c;对应一级标题&#xff0c;两个#&#xff0c;对应二级标题&#xff0c;等。 我这里使用Ctrl1没生效是因为快捷键冲突&#xff0c;也需要注意…

一招解决Mac没有剪切板历史记录的问题

使用Mac的朋友肯定都为Mac的剪切功能苦恼过&#xff0c;旧内容覆盖新内容&#xff0c;导致如果有内容需要重复输入的话&#xff0c;就需要一次一次的重复复制粘贴&#xff0c;非常麻烦 但其实Mac也能够有剪切板历史记录功能&#xff0c;iCopy&#xff0c;让你的Mac也能拥有剪切…

在鱼皮的模拟面试里面学习有感

文章目录 1.上半场1.1.引言1.2.鱼皮的建议 2.下半场2.1中间问题 3.我的总结3.1我的体会3.2我的计划 1.上半场 今天的直播&#xff0c;第一次全程的跟下来&#xff1a;也算是放松一下~~ 1.1.引言 上半场是后来总结的&#xff0c;听的时候没有随手记录&#xff1a; 1&#xf…

windows在两台机器上测试 MySQL 集群实现实时备份

在两台机器上测试 MySQL 集群实现实时备份的基本步骤&#xff1a; 一、环境准备 机器配置 确保两台机器&#xff08;假设为服务器 A 和服务器 B&#xff09;能够互相通信&#xff0c;例如它们在同一个局域网内&#xff0c;并且开放了 MySQL 通信所需的端口&#xff08;默认是 …

MQTT从入门到精通之MQTT入门

MQTT入门 1 MQTT概述 1.1 MQTT简介 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;由IBM于1999年开发的一种基于**"发布订阅模式"的轻量级的消息传输协议**&#xff01; 发布订阅模式是一种传统的客户端-服务器架构的替代方案&#xff0c;因为…

python在word中插入图片

本文讲解python如何在word文档中插入图片&#xff0c;以及指定插入图片的段落。 1、在新建的word文档中插入图片 import win32com.client as win32 from win32com.client import constants # 1&#xff09;打开word应用程序 doc_app win32.gencache.EnsureDispatch(Word.App…

Linux(CentOS)安装 Nginx

CentOS版本&#xff1a;CentOS 7 Nginx版本&#xff1a;1.24.0 有两种安装方式 一、通过编译源码包安装 编译源码包&#xff1a;.tar.gz或.tar包文件 1、下载 Nginx 打开Nginx官网&#xff1a;https://nginx.org/ 2、上传 Nginx 文件到 CentOS 使用FinalShell远程登录工…

TESSY学习笔记—project view界面的架构

1&#xff1a;project view界面能添加的元素 project view界面能添加的元素&#xff08;暂且称为元素&#xff09;&#xff0c;打开project view界面&#xff0c;下图中红框勾选出来的就是 2&#xff1a;一共存在5种可添加元素 **1&#xff09;Test collection 测试集合&…

vue中如何关闭eslint检测?

ESLint作为一个用于JavaScript代码的验证工具&#xff0c;主要用于检查代码语法和编码规范。本文旨在指导那些希望在Vue.js项目中禁用ESLint验证功能的用户。对于需要这一操作的朋友&#xff0c;以下内容将提供参考。 vue中如何关闭eslint检测&#xff1f; 有了eslint的校验&…

uniApp之uni-file-picker使用踩坑

标题党~也不算坑吧 就是初体验 上传是需要存储一下子的&#xff0c;我以为uniApp是自己免费开的服务给大家中转使用&#xff0c;就没管这个事&#xff0c;但是官网是这么说的&#xff1a; 就我是怎么发现的&#xff0c;使用了一段时间后&#xff0c;上传的图片都裂了&#xff…

K8s小白入门

文章目录 前言一、特性二、集群的结构控制平面内部组件Node内部组件 三、Docker与K8s的关系总结 前言 Kubernetes&#xff08;K8s&#xff09;是一个开源的容器编排平台&#xff0c;用于自动化容器化应用的部署、扩展和管理。是支持云原生部署的一个平台&#xff0c;它前生是谷…

[asdf] 管理erlang 版本--ubuntu 16.04

部分网址 asdf 官网&#xff1a;快速入门 | asdf elang 插件网址&#xff1a;https://github.com/asdf-vm/asdf-erlang rebar 插件网址&#xff1a;https://github.com/Stratus3D/asdf-rebar 安装asdf 先安装依赖,默认装了git 可只安装curl apt install curl git 2、安装as…

微信小程序 uniapp网络记账设计个人理财系统

文章目录 项目介绍具体实现截图技术介绍mvc设计模式小程序框架以及目录结构介绍错误处理和异常处理java类核心代码部分展示详细视频演示源码获取 项目介绍 aa账簿 (自动编号、用户id、用户账号、备注、登记时间、消费类型、创建时间、消费金额)&#xff1b; 配置文件 (自动编…

【VR】PICO 手部追踪 steamvr内无法识别,依旧识别手柄的解决方案

一、问题描述 && 原因分析 1.PICO4 手部追踪 steamvr内无法识别&#xff0c;依旧识别手柄的解决方案 尽管平放&#xff08;或关闭手柄连接&#xff09;之后&#xff0c;在 PICO 一体机中进入了手部追踪状态&#xff0c; 但只要进入 steamvr&#xff0c;就无法正确识别…

React中类组件和函数组件的理解和区别

react代码模块分为类组件和函数组件。 从语法和定义、内部状态管理、生命周期、性能、可读性和维护性、上下文、集成状态管理库等角度对比React中类组件和函数组件。 1、语法和定义 类组件&#xff1a; 使用 ES6 的类&#xff08;class&#xff09;语法定义的 React 组件。…

ruoyi-vue集成tianai-captcha验证码

后端代码 官方使用demo文档&#xff1a;http://doc.captcha.tianai.cloud/#%E4%BD%BF%E7%94%A8demo 我的完整代码&#xff1a;https://gitee.com/Min-Duck/RuoYi-Vue.git 主pom.xml 加入依赖 <!-- 滑块验证码 --><dependency><groupId>cloud.tianai.captc…

ctfshow(316)--XSS漏洞--反射性XSS

Web316 进入界面&#xff1a; 审计 显示是关于反射性XSS的题目。 思路 首先想到利用XSS平台解题&#xff0c;看其他师傅的wp提示flag是在cookie中。 当前页面的cookie是flagyou%20are%20not%20admin%20no%20flag。 但是这里我使用XSS平台&#xff0c;显示的cookie还是这样…