Vue3等比例缩放图片组件

今天遇到一个需求,设计需要我无论什么情况都要保持图片比例不变,于是顺手写了个这个组件,组件基于vue3+ts,其实核心代码就是那几句css

<template>
    <div style="position: relative" :style="ratioStr">
        <div style="position: absolute; inset: 0px; user-select: none">
            <img
                v-if="type === 'image'"
                :src="src"
                :alt="alt || src"
                style="object-fit: cover; width: 100%; height: 100%" />
            <video
                v-else
                :src="src"
                controls
                style="object-fit: contain; width: 100%; height: 100%" />
        </div>
    </div>
</template>

<script lang="ts" setup>
const props = defineProps({
    ratio: {
        type: Array as unknown as () => [number, number],
        default: () => [1, 1],
    },
    alt: {
        type: String,
        default: "",
    },
    type: {
        type: String as () => "image" | "video",
        default: "image",
    },
    src: {
        type: String,
        default: "",
    },
});

const ratioStr = computed(() => {
    const [width, paddingBottom] = props.ratio;
    return `width: 100%;padding-bottom: ${(paddingBottom / width) * 100}%;`;
});
</script>

<style lang="scss" scoped></style>

### 实现 Vue 项目中的元素全屏保持宽高比缩放 为了实现在 Vue 中的元素能够全屏显示且按照宽高比进行缩放,可以采用 CSS 结合 JavaScript 的方式。具体来说,在样式方面利用 `aspect-ratio` 属性确保图片或其他元素维持固定的宽度与高度比率;而在脚本部分,则借助 Vue 生命周期钩子监听窗口尺寸变化事件以便动态调整目标元素大小。 #### 利用 aspect-ratio 维持宽高比 对于需要设置固定宽高比例的对象而言,现代浏览器支持直接应用 `aspect-ratio` 属性[^3]: ```css .fullscreen-element { width: 100vw; /* 占满整个视窗 */ height: auto; max-height: 100vh; object-fit: cover; aspect-ratio: 16 / 9; /* 设置特定的宽高比 */ } ``` 上述代码片段定义了一个类名为 `.fullscreen-element` 的 HTML 元素,它会尽可能填充满屏幕的同时保证其自身的宽高比不变形。 #### 动态响应窗口改变 为了让组件内的某个 DOM 节点随视口尺寸变动而相应地更新自身属性,可以在创建阶段绑定好相应的处理逻辑,于销毁前解绑这些监听器以防内存泄漏。这通常是在 mounted 和 beforeDestroy 钩子里完成的操作[^1]: ```javascript export default { data() { return { elementRef: null, }; }, methods: { handleResize(event) { const rect = this.$refs[this.elementRef].getBoundingClientRect(); console.log(`Element size is ${rect.width}x${rect.height}`); // 可在此处加入更多针对不同分辨率下的特殊处理逻辑 } }, mounted() { window.addEventListener(&#39;resize&#39;, this.handleResize); this.handleResize(); // 初始化时也调用一次以获取初始状态 }, beforeDestroy() { window.removeEventListener(&#39;resize&#39;, this.handleResize); } }; ``` 这段代码展示了如何在一个 Vue 组件内部注册全局 resize 事件处理器以及移除该处理器的方法。每当用户调整浏览器窗口大小的时候都会触发此方法执行,从而允许开发者实时监控所关心区域的实际表现情况。 #### 将功能封装成 Mixin 方便复用 考虑到可能有多个地方需要用到相同的机制,因此建议把这部分通用的功能提取出来做成 mixin 文件供其他模块引入使用[^2]: ```javascript // mixins/fullScreenMixin.js import { ref } from &#39;vue&#39;; const fullScreenMixin = { setup(props, context) { let elementRef = ref(null); function handleResize(event) { if (!elementRef.value) return; const rect = elementRef.value.getBoundingClientRect(); console.log(`Resized to ${rect.width}px by ${rect.height}px`); } onMounted(() => { window.addEventListener(&#39;resize&#39;, handleResize); nextTick(handleResize); // 确保DOM已经渲染完毕再计算尺寸 }); onBeforeUnmount(() => { window.removeEventListener(&#39;resize&#39;, handleResize); }); return { elementRef, }; }, }; export default fullScreenMixin; ``` 以上就是关于在 Vue 应用程序里让指定对象实现全屏展示且能按比例伸缩的整体思路和技术要点说明。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值