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>

目录
相关文章
|
27天前
|
JavaScript 前端开发 Go
CSS 与 JS 对 DOM 解析和渲染的影响
【10月更文挑战第16天】CSS 和 JS 会在一定程度上影响 DOM 解析和渲染,了解它们之间的相互作用以及采取适当的优化措施是非常重要的。通过合理的布局和加载策略,可以提高网页的性能和用户体验,确保页面能够快速、流畅地呈现给用户。在实际开发中,要根据具体情况进行权衡和调整,以达到最佳的效果。
|
25天前
|
Kubernetes 监控 Cloud Native
|
15天前
|
前端开发 JavaScript
如何在 JavaScript 中访问和修改 CSS 变量?
【10月更文挑战第28天】通过以上方法,可以在JavaScript中灵活地访问和修改CSS变量,从而实现根据用户交互、页面状态等动态地改变页面样式,为网页添加更多的交互性和动态效果。在实际应用中,可以根据具体的需求和场景选择合适的方法来操作CSS变量。
|
6天前
|
缓存 前端开发 JavaScript
优化CSS和JavaScript加载
Next.js和Nuxt.js在优化CSS和JavaScript加载方面提供了多种策略和工具。Next.js通过代码拆分、图片优化和特定的CSS/JavaScript优化措施提升性能;Nuxt.js则通过代码分割、懒加载、预渲染静态页面、Webpack配置和服务端缓存来实现优化。两者均能有效提高应用性能。
|
6天前
|
前端开发 JavaScript
用HTML CSS JS打造企业级官网 —— 源码直接可用
必看!用HTML+CSS+JS打造企业级官网-源码直接可用,文章代码仅用于学习,禁止用于商业
33 1
|
11天前
|
前端开发 JavaScript 安全
HTML+CSS+JS密码灯登录表单
通过结合使用HTML、CSS和JavaScript,我们创建了一个带有密码强度指示器的登录表单。这不仅提高了用户体验,还帮助用户创建更安全的密码。希望本文的详细介绍和代码示例能帮助您在实际项目中实现类似功能,提升网站的安全性和用户友好性。
22 3
|
15天前
|
前端开发 JavaScript UED
如何使用 JavaScript 动态修改 CSS 变量的值?
【10月更文挑战第28天】使用JavaScript动态修改CSS变量的值可以为页面带来更丰富的交互效果和动态样式变化,根据不同的应用场景和需求,可以选择合适的方法来实现CSS变量的动态修改,从而提高页面的灵活性和用户体验。
|
21天前
|
JSON 移动开发 数据格式
html5+css3+js移动端带歌词音乐播放器代码
音乐播放器特效是一款html5+css3+js制作的手机移动端音乐播放器代码,带歌词显示。包括支持单曲循环,歌词显示,歌曲搜索,音量控制,列表循环等功能。利用json获取音乐歌单和歌词,基于html5 audio属性手机音乐播放器代码。
72 6
|
30天前
|
前端开发 Docker 容器
主机host服务器和Docker容器之间的文件互传方法汇总
Docker 成为前端工具,可实现跨设备兼容。本文介绍主机与 Docker 容器/镜像间文件传输的三种方法:1. 构建镜像时使用 `COPY` 或 `ADD` 指令;2. 启动容器时使用 `-v` 挂载卷;3. 运行时使用 `docker cp` 命令。每种方法适用于不同场景,如静态文件打包、开发时文件同步及临时文件传输。注意权限问题、容器停止后的文件传输及性能影响。
130 0
|
前端开发 容器 Web App开发
用纯 CSS 创作一个在容器中反弹的小球
效果预览 在线演示 按下右侧的“点击预览”按钮可以在当前页面预览,点击链接可以全屏预览。 https://codepen.io/comehope/pen/jKVbyE 可交互视频教程 此视频是可以交互的,你可以随时暂停视频,编辑视频中的代码。
821 0