vue前端自适应布局,一步到位所有自适应

news2024/12/27 10:30:17
页面展示

在这里插入图片描述
在这里插入图片描述

实现内容

1,左右布局

  • 左侧固定宽带,右侧自适应剩余的宽度。
  • 中间一条分割线,可以拖拉,自适应调整左右侧的宽度。
  • 左侧的高度超长自动出现横向滚动条,左侧宽度超长,自动出现竖向滚动条。

2,上中下布局

  • 最上面的 搜索条件 div 固定占用 100 px 高度,下面的 查询条件 div 固定占用 30 px 高度,最下面的分页固定占用高度,页面剩下的高度自动分配给中间的表格内容。
  • 表格内容高度超过后自动出现竖向滚动条,宽度超出后自动出现横向滚动条。
  • 点击按钮,可以 隐藏/显示 搜索条件 div 里面的内容。
  • 当隐藏 搜索条件 div 里面的内容时,中间表格的高度为:整个页面的高度—操作按钮div的高度—分页div的高度。
  • 当搜索条件 div 里面的内容时,中间表格的高度为:整个页面的高度—搜索条件div的高度—操作按钮div的高度—分页div的高度。
    2,分辨率自适应
  • 加载即动态实时计算高度,宽度
实现代码

vue2 语法实现

<template>
  <div class="app-container">
    <div class="left" :style="{ width: leftWidth + 'px' }">
      <div class="right-center-left">
        左边的内容,可以很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
      </div>
    </div>
    <div class="divider" @mousedown="startDragging"></div>
    <div class="right">
      <div v-if="showDiv1" class="div1">查询条件</div>
      <div class="div2">
        <button @click="toggleDiv1">操作按钮 div1</button>
      </div>
      <div class="div3" :style="{ height: div3Height + 'px' }">
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
      </div>
      <div class="div4">分页</div>
    </div>
  </div>
</template>

<script>
export default {
  name: "AppContainer",
  data() {
    return {
      isDragging: false,
      leftWidth: 200,
      showDiv1: true
    };
  },
  computed: {
    div3Height() {
      const totalHeight = window.innerHeight;
      const div2Height = 30;
      const div4Height = 30;
      const div1Height = this.showDiv1 ? 100 : 0;

      // 计算 div3 的高度
      return totalHeight - div2Height - div4Height - div1Height;
    }
  },
  methods: {
    startDragging(e) {
      this.isDragging = true;
      document.addEventListener("mousemove", this.onDrag);
      document.addEventListener("mouseup", this.stopDragging);
    },
    onDrag(e) {
      if (this.isDragging) {
        const minWidth = 50;
        const maxWidth = window.innerWidth - 50;
        const newLeftWidth = e.clientX;

        if (newLeftWidth > minWidth && newLeftWidth < maxWidth) {
          this.leftWidth = newLeftWidth;
        }
      }
    },
    stopDragging() {
      this.isDragging = false;
      document.removeEventListener("mousemove", this.onDrag);
      document.removeEventListener("mouseup", this.stopDragging);
    },
    toggleDiv1() {
      this.showDiv1 = !this.showDiv1;
    }
  }
};
</script>

<style scoped>
.app-container {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

.left {
  overflow-x: auto;
  overflow-y: auto;
  white-space: nowrap;
  min-width: 90px;
}

.divider {
  width: 5px;
  cursor: ew-resize;
  background-color: #ccc;
}

.right {
  display: flex;
  flex-direction: column;
  height: 100%;
  flex: 1; /* 自动填满剩余宽度 */
}

.div1 {
  height: 100px;
  background-color: #f0f0f0;
}

.div2 {
  height: 30px;
  background-color: #ddd;
}

.div3 {
  overflow-x: auto; /* 添加横向滚动条 */
  overflow-y: auto; /* 添加纵向滚动条 */
  background-color: #f5f5f5;
}

.div4 {
  height: 200px;
  background-color: #ccc;
}
</style>

vue3 语法实现

<template>
  <div class="app-container">
    <div class="left" :style="{ width: leftWidth + 'px' }">
      左边的内容,可以很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长<br />
      1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
      1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
      1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
      1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
      1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
      1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
    </div>
    <div class="divider" @mousedown="startDragging"></div>
    <div class="right">
      <div v-if="showQueryDiv" class="right-query">搜索条件</div>
      <div class="right-button">
        <div class="right-button-left">操作按钮</div>
        <div class="right-button-right">
          <button @click="toggleQueryDiv">隐藏/展示 搜索条件</button>
        </div>
      </div>
      <div class="right-table" :style="{ height: tableHeight + 'px' }">
        表格内容<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
        1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />1<br />
      </div>
      <div class="right-page">分页内容</div>
    </div>
  </div>
</template>

<script>
import { ref, computed, onMounted, onUnmounted } from 'vue';

export default {
  name: "AppContainer",
  setup() {
    const isDragging = ref(false);
    const leftWidth = ref(200);
    const showQueryDiv = ref(true);

    const tableHeight = computed(() => {
      const totalHeight = window.innerHeight;
      const buttonHeight = 30;
      const pageHeight = 30;
      const queryHeight = showQueryDiv.value ? 100 : 0;
      return totalHeight - buttonHeight - pageHeight - queryHeight;
    });

    const startDragging = (e) => {
      isDragging.value = true;
      document.addEventListener("mousemove", onDrag);
      document.addEventListener("mouseup", stopDragging);
    };

    const onDrag = (e) => {
      if (isDragging.value) {
        const minWidth = 50;
        const maxWidth = window.innerWidth - 50;
        const newLeftWidth = e.clientX;
        if (newLeftWidth > minWidth && newLeftWidth < maxWidth) {
          leftWidth.value = newLeftWidth;
        }
      }
    };

    const stopDragging = () => {
      isDragging.value = false;
      document.removeEventListener("mousemove", onDrag);
      document.removeEventListener("mouseup", stopDragging);
    };

    const toggleQueryDiv = () => {
      showQueryDiv.value = !showQueryDiv.value;
    };

    onMounted(() => {
      window.addEventListener("resize", onDrag);
    });

    onUnmounted(() => {
      window.removeEventListener("resize", onDrag);
    });

    return {
      leftWidth,
      showQueryDiv,
      tableHeight,
      startDragging,
      toggleQueryDiv
    };
  }
};
</script>

<style scoped>
.app-container {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

.left {
  overflow-x: auto;
  overflow-y: auto;
  white-space: nowrap;
  min-width: 90px;
}

.divider {
  width: 5px;
  cursor: ew-resize;
  background-color: #ccc;
}

.right {
  display: flex;
  flex-direction: column;
  height: 100%;
  flex: 1; /* 自动填满剩余宽度 */
}

.right-query {
  height: 100px;
  background-color: #f0f0f0;
}

.right-button {
  height: 30px;
  display: flex;
  justify-content: space-between; /* 左右对齐内容 */
  align-items: center; /* 垂直居中对齐 */
  background-color: #ddd;
}

.right-button-left {
  margin-left: 5px;
  text-align: left;
}

.right-button-right {
  margin-right: 5px;
  text-align: right;
}

.right-table {
  overflow-x: auto; /* 添加横向滚动条 */
  overflow-y: auto; /* 添加纵向滚动条 */
  background-color: #f5f5f5;
}

.right-page {
  height: 200px;
  background-color: #ccc;
}
</style>
实现感想

这个功能,从毕业就开始思索,直到八年后的今天成熟完善,真是艰辛也是很不容易。目前市面上没有见过有人实现,很多人都是只言片语的,基本复制下来,无法达到效果。我这个一键复制到自己的项目,就能实现了,中间的坎坷不平,到了完全实现的这一刻,才觉得激动不已。

无任何坑,也没有任何额外的引入,一个普普通通,最简单的vue页面,布局建好,里面的内容就可以自己随意发挥了。

未觉池塘春草梦,阶前梧叶已秋声。记录激动时刻,也造福后来人。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

栈的实现及括号匹配问题

一、栈的概念及结构 栈是一种特殊的线性表&#xff0c;只允许在固定的一端进行插入删除元素操作。 进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。 栈中的数据元素遵循后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&#xff1a…

Linux/C 高级——shell脚本

1. shell脚本基础概念 1.1概念 shell使用方式&#xff1a;手动下命令和脚本 脚本本质是一个文件&#xff0c;文件里面存放的是特定格式的指令&#xff0c;系统可以使用脚本解析器翻译或解析指令并执行&#xff08;它不需要编译&#xff09;。 shell脚本本质&#xff1a;shell命…

浅谈 Spring AOP框架 (2)——Spring统一功能处理

文章目录 一、AOP实战——SpringBoot统一功能处理1.1、使用拦截器实现用户登录权限的统一验证1.1.1、使用原生Spring AOP实现统一拦截的难点1.1.2、Spring 拦截器1.1.2.1、Spring拦截器 使用步骤1.1.2.2、拦截器实现原理 1.2、统一数据格式返回1.2.1、为什么要返回统一的数据格…

Linux/C 高级——条件编译

1.根据宏是否定义 #define 宏名 #ifdef 宏名 /*code1*/ #else /*code2*/ #endif 执行顺序&#xff1a;宏名如果定义则编译code1&#xff0c;否则编译code2 例子&#xff1a; 2.根据宏值 #define 宏名 值 #if 宏名 /*code1*/ #else /*code2*/ #endif 执行顺序&#xff1a;宏的值…

真值表编程

打开真值表进行编辑 在图表中创建并标记真值表后&#xff0c;您可以指定其逻辑行为。要打开真值表&#xff0c;请双击真值表函数。 默认情况下&#xff0c;真值表包含一个条件表和一个动作表&#xff0c;每个表都有一行。条件表包含一个决策列D1和一个动作行。 选择动作语言 …

达梦数据库 数据类型

达梦数据类型 1.背景2.要求3.描述与使用3.1 常规数据类型3.1.1 字符数据类型3.1.1.1 CHAR类型3.1.1.2 CHARACTER类型3.1.1.3 VARCHAR类型 3.1.2 数值数据类型3.1.2.1 NUMERIC类型3.1.2.2 DECIMAL类型3.1.2.3 DEC类型3.1.2.4 NUMBER类型3.1.2.5 INTEGER类型3.1.2.6 INT类型3.1.2…

VC++_opencv插件ImageWatch的安装和使用

1、插件安装 以VS2015为例&#xff1a; 进入扩展和更新界面&#xff0c;点“联机”&#xff0c;然后输入“ImageWatch”进行搜索&#xff1a; 2、安装完毕后重启VisualStudio 如下图在菜单“视图\其他窗口”找到“ImageWatch”这个栏目 然后点开&#xff1a; 也可让其停靠在Vi…

c++----初识模板

大家好&#xff0c;这篇博客想与大家分享一些我们c中比较好用的知识点。模板。首先咧&#xff0c;我们都知道模板嘛&#xff0c;就是以前人的经验总结出来的知识。方便我们使用。这里的模板也是一样的。当我们学习过后&#xff0c;对于一些在c中的自定义函数&#xff0c;我们在…

QList 的访问方式list.at(index) 和 list[index] 对比

QList 是 Qt 框架中提供的一个模板容器类&#xff0c;用于存储和操作一系列元素。它提供了两种不同的方式来访问容器中的元素&#xff1a;.at()成员函数和下标运算符 []。以下是这两种方式的区别&#xff1a; 1. QList::at() 方法 at()是一个成员函数&#xff0c;它允许通过索…

04--Docker

前言&#xff1a;前面写过关于DockerKubernetes的部署&#xff0c;主要是针对国产化linux系统的适配问题&#xff0c;并没有对docker进行复习。这里整理一下docker的知识点&#xff0c;用作容器化微服务的起点&#xff0c;主要为日常工作配置使用&#xff0c;本章可能有点长&am…

详解Xilinx FPGA高速串行收发器GTX/GTP(4)--TX/RX接口的数据位宽和时钟设计

目录 1、时钟设计 2、TX接口 3、接口位宽与时钟的关系 4、时钟来源方案 5、TX端内部的时钟分频设计 6、RX接口 文章总目录点这里:《FPGA接口与协议》专栏的说明与导航 1、时钟设计 GT收发器内部比较复杂,所使用的时钟就不止一个,比较主要的时钟有两个,架构…

做好网络安全风险管理必备的5种能力

网络安全风险管理和网络安全防护是两个密切相关但不可互换的概念&#xff0c;网络安全防护侧重于应对攻击和响应正在发生的安全事件&#xff0c;而网络安全风险管理则强调从更全面的视角去评估企业的安全状况和面临的威胁态势&#xff0c;包括了从对组织运营、商誉、财务和合规…

值得注意!家里有带毛发动物就有浮毛?宠物空气净化器一键净化

上次跟朋友逛完街去她家&#xff0c;她家热情的哈基米开门就一个猛冲&#xff0c;我朋友接住就是一顿猛亲&#xff0c;亲猫一时爽&#xff0c;汗液粘着猫毛&#xff0c;粘得满手臂、满脸都是&#xff0c;看得鼻炎星人头皮发麻...好多养宠物的都说&#xff0c;梳毛根本不管用&am…

关于let 、const和Object.freeze的使用记录

let和const的使用差异 let对象变量&#xff0c;可以修改对象属性&#xff0c;可以给变量重新赋值 const对象变量&#xff0c;可以修改对象属性&#xff0c;不可以给变量重新赋值 Object.freeze()返回一个不可变对象&#xff0c;需要接收返回值。不会改变原参数的性质

LVS详解及其NAT模式与DR模式部署(全网最详细!!!)

文章目录 LVS集群概念集群和分布式 LVS运行原理LVS简介LVS专业术语工作原理LVS调度算法ipvsadm常用命令 LVS工作模式及其原理NAT模式DR模式TUN模式fullnet模式 部署NAT模式集群案例DR模式&#xff08;企业中最常用&#xff09;LVS持久链接&#xff08;session回话问题解决&…

SimpleITK C++版在windows 下编译

一般都是用python 版的SimpleITK&#xff0c;因为项目需要集成到C Qt上&#xff0c;然后ITK用起来又不如SimpleITK方便&#xff0c;所有就编译了C版的Sitk,下面记录下过程。 版本对应 SimpleITK 编译需要ITK ,而且不同版本需要对应不同的ITK&#xff0c;sitk 2.2.1 对应ITK 5…

基于Hadoop的海量电商用户行为分析及机器学习购买预测研究【购物行为分析、100万条数据案例项目】

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主引言研究背景国内外研究现状研究目的研究意义 关键技术理论介绍Hadoop集群搭建及数据准备Hadoop全套组件搭建数据集介绍数据预处理 基于大数据的电商用户行为指标分析HIve准备数据表flume配…

在哪些行业中,3D 技术发挥了重要作用?

3D技术目前常见于行业或领域中的应用&#xff0c;主要包括3D数字孪生、3D打印等。3D数字孪生技术作为一种前沿技术&#xff0c;在多个行业中发挥着重要作用&#xff0c;它通过创建物理实体的数字化副本&#xff0c;实现对实体的实时监控、预测和优化。以下是一些3D数字孪生技术…

【总结】TCP/IP四层模型的理解

在开始之前放上一张本文章的核心图片&#xff0c;要一直记住图中的内容&#xff01;&#xff01;&#xff01; 一、概念理解 首先我们知道分析网络的时候有两种模型&#xff0c;一种是OSI七层模型&#xff0c;另一种就是TCP/IP四层模型。一般来说&#xff0c;我们常用的就是TC…

医疗工厂网络同步时钟,子母钟系统结构,可使用十年以上

在医疗和工业领域&#xff0c;准确的时间信息对于确保各项工作的高效运行至关重要。网络同步时钟系统因其高精度、易维护等特点&#xff0c;成为现代医疗工厂不可或缺的时间管理工具。本文将详细介绍网络同步时钟系统的优点及其技术细节。 一、网络同步时钟优点 网络同步时钟系…