vue组件封装——固定宽高比的容器(2种方法:纯CSS实现 + JS实现)

简介: vue组件封装——固定宽高比的容器(2种方法:纯CSS实现 + JS实现)

什么是固定宽高比容器?

定义:

无论浏览器窗口或页面元素如何变化,容器的宽度和高度永远保持固定的比例,如16:9。

应用场景:

如大屏自适应,内部元素对容器宽高比依赖很高的复杂模块布局等。

纯CSS实现固定宽高比的容器

原理

  • padding-top的值为百分比时,最终padding-top的计算值 = 百分比 * 当前元素宽度的计算值,从而通过padding-top将容器撑开。
  • 为容器添加样式 box-sizing: border-box; 则容器的高度 = padding-top的计算值,从而实现容器高度根据容器的宽度按百分比自适应变化。
  • 使用“子绝父相”,让容器中的内容完全覆盖容器。

cssRatioContainer.vue

<template>
  <div class="box" :style="ratioStyle">
    <div class="content" :style="contentStyle">
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    ratio: {
      type: Number,
      default: 1,
    },
    overflow: {
      type: String,
      default: "auto",
    },
    overflowX: {
      type: String,
    },
    overflowY: {
      type: String,
    },
  },
  computed: {
    ratioStyle() {
      let ratio = (1 / this.ratio) * 100;
      if (ratio == null || Number.isNaN(ratio)) {
        ratio = 100;
      }
      if (typeof ratio !== "string" || !ratio.endsWith("%")) {
        ratio = ratio + "%";
      }
      return `padding-top: ${ratio};`;
    },

    contentStyle() {
      const styles = [];
      if (this.overflow) {
        styles.push("overflow:" + this.overflow);
      }
      if (this.overflowX) {
        styles.push("overflow-x:" + this.overflowX);
      }
      if (this.overflowY) {
        styles.push("overflow-y:" + this.overflowY);
      }
      return styles.join(";");
    },
  },
};
</script>

<style scoped>
.box {
  position: relative;
  box-sizing: border-box;
}
.content {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}
</style>

JS实现固定宽高比的容器

原理

  • 通过js获取容器的宽度计算值后,按宽高比计算出容器的高度,并赋值给容器。

jsRatioContainer.vue

<template>
  <div id="jsRatioContainerBox" class="box" :style="contentStyle">
    <slot></slot>
  </div>
</template>

<script>
export default {
  props: {
    ratio: {
      type: Number,
      default: 1,
    },
    overflow: {
      type: String,
      default: "auto",
    },
    overflowX: {
      type: String,
    },
    overflowY: {
      type: String,
    },
  },
  data() {
    return {
      myHeight: "",
    };
  },
  computed: {
    contentStyle() {
      const styles = [];
      if (this.myHeight) {
        styles.push("height:" + this.myHeight);
      }
      if (this.overflow) {
        styles.push("overflow:" + this.overflow);
      }
      if (this.overflowX) {
        styles.push("overflow-x:" + this.overflowX);
      }
      if (this.overflowY) {
        styles.push("overflow-y:" + this.overflowY);
      }
      return styles.join(";");
    },
  },
  mounted() {
    this.setHeight();
    window.addEventListener("resize", () => {
      this.setHeight();
    });
  },
  watch: {
    ratio() {
      this.setHeight();
    },
  },
  methods: {
    // 根据宽高比和当前宽度,设置最终的高度
    setHeight() {
      this.$nextTick(() => {
        let myDom = document.getElementById("jsRatioContainerBox");
        let width = window.getComputedStyle(myDom)["width"];
        this.myHeight =
          Number(width.replace("px", "")) * (1 / this.ratio) + "px";
      });
    },
  },
};
</script>

<style scoped>
.box {
  width: 100%;
}
</style>

使用范例

<template>
  <div class="father">
    <h2>CSS实现固定宽高比的容器</h2>
    <CssRatioContainer
      ref="CssRatioContainer"
      id="CssRatioContainer"
      :ratio="ratioWidth / ratioHeight"
    >
      <div class="itemBox" v-for="item in 100" :key="item">段落{{ item }}</div>
    </CssRatioContainer>
    <p>容器的宽度为:{{ mySize.width }}</p>
    <p>容器的高度为:{{ mySize.height }}</p>
    <label>容器的宽高比:</label>
    <input
      class="inputStyle"
      type="number"
      v-model="ratioWidth"
      @input="getSize"
    />
    <input
      class="inputStyle"
      type="number"
      v-model="ratioHeight"
      @input="getSize"
    />
    <h2>JS实现固定宽高比的容器</h2>
    <JsRatioContainer :ratio="ratioWidth / ratioHeight">
      <div class="itemBox" v-for="item in 100" :key="item">段落{{ item }}</div>
    </JsRatioContainer>
  </div>
</template>
<script>
import CssRatioContainer from "./cssRatioContainer.vue";
import JsRatioContainer from "./jsRatioContainer.vue";
export default {
  components: { CssRatioContainer, JsRatioContainer },
  mounted() {
    this.getSize();
    window.addEventListener("resize", () => {
      this.getSize();
    });
  },
  methods: {
    getSize() {
      this.$nextTick(() => {
        let myDom = document.getElementById("CssRatioContainer");
        let myComputedStyle = window.getComputedStyle(myDom);
        this.$set(this.mySize, "height", myComputedStyle.height);
        this.$set(this.mySize, "width", myComputedStyle.width);
      });
    },
  },

  data() {
    return {
      mySize: {},
      ratioWidth: 6,
      ratioHeight: 1,
    };
  },
};
</script>
<style scoped>
.father {
  max-width: 1200px;
  margin: 20px;
}
.itemBox {
  background: red;
  border: 1px solid yellow;
}
.inputStyle {
  width: 60px;
  text-align: center;
}
</style>

目录
相关文章
|
JavaScript Linux 内存技术
Debian 11系统下Node.js版本更新方法详解
本指南详细介绍在Linux系统中安装和管理Node.js的步骤。首先检查现有环境,包括查看当前版本和清除旧版本;接着通过NodeSource仓库安装最新版Node.js并验证安装结果。推荐使用nvm(Node Version Manager)进行多版本管理,便于切换和设置默认版本。同时,提供常见问题解决方法,如权限错误处理和全局模块迁移方案,以及版本回滚操作,确保用户能够灵活应对不同需求。
1654 0
|
JavaScript Linux 内存技术
Debian 11系统下Node.js版本更新方法
Debian 11更新Node.js主要就是这三种方式,无论你是初涉其中的新手还是找寻挑战的专家,总有一种方式能满足你的需求。现在,你已经是这个
1667 80
|
存储 前端开发 JavaScript
仿真银行app下载安装, 银行卡虚拟余额制作app,用html+css+js实现逼真娱乐工具
这是一个简单的银行账户模拟器项目,用于学习前端开发基础。用户可进行存款、取款操作,所有数据存储于浏览器内存中
|
JavaScript 前端开发 Java
js 垃圾回收机制的方法
JS回收机制方法讲解
|
移动开发 运维 供应链
通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理;js数组元素检查的方法,some()的使用详解,array.some与array.every的区别(附实际应用代码)
array.some()可以用来权限检查、表单验证、库存管理、内容审查和数据处理等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
供应链 JavaScript 前端开发
通过array.every()实现数据验证、权限检查和一致性检查;js数组元素检查的方法,every()的使用详解,array.some与array.every的区别(附实际应用代码)
array.every()可以用来数据验证、权限检查、一致性检查等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
JavaScript 前端开发
ActiveX组件与JavaScript交互
1.在COM组件中调用JavaScript函数// 连接点方式页面javascript脚本        alert("State(" + s + ")");        return 123;        testCom.
1205 0
|
JavaScript 前端开发 C++
一步一步实现ATL开发的ActiveX组件与javascript的交互(一)
1.      打开VS2008,单击起始页中的“New Project…”,选择“ATL”分类下的“ATL Project”项目,项目名称为“ATLtest”。在随后出现的项目向导中,使用默认配置即可。
1825 0
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
503 2

热门文章

最新文章

  • 1
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    589
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    448
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    452
  • 4
    (CSS)使用Flex布局,帮助你快速了解各种基本的Flex布局属性以及帮你让元素快速达到布局中的指定位置!
    297
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    575
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    749
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    1473
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    325
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    1188
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    528