在 Vue 中使用具有动态属性的媒体查询

问题描述 投票:0回答:3

因此,我的一个页面总是有一个带有背景图像的 Div,该背景图像会根据媒体查询而变化(例如,我从手机上的 CDN 获取较小的分辨率)。

现在,由于我在页面加载时获得了图像 Url,我需要将其设置到 CSS 中,这对于计算的样式属性来说很好,但这些属性不支持媒体查询。

我看到的唯一解决方案是一些调整大小事件侦听器,但我更希望获得一个干净的解决方案。

示例代码片段在具有预定义 Url 的 CSS 中的外观:

/* Custom, iPhone Retina */ 
@media only screen and (min-width : 320px) {
  .image {
        background: linear-gradient(rgba(255, 255, 255, 0.0), rgba(0, 0, 0, 0.95)), url("https://res.cloudinary.com/.../image/upload/c_scale,w_900/v.../3.jpg") no-repeat center;
        background: -webkit-linear-gradient(rgba(255, 255, 255, 0.0), rgba(0, 0, 0, 0.95)), url("https://res.cloudinary.com/.../image/upload/c_scale,w_900/v.../3.jpg") no-repeat center;
      }
  }

/* Extra Small Devices, Phones */ 
@media only screen and (min-width : 480px) {
  .image {
        background: linear-gradient(rgba(255, 255, 255, 0.0), rgba(0, 0, 0, 0.95)), url("https://res.cloudinary.com/.../image/upload/c_scale,w_1300/v.../3.jpg") no-repeat center;
        background: -webkit-linear-gradient(rgba(255, 255, 255, 0.0), rgba(0, 0, 0, 0.95)), url("https://res.cloudinary.com/.../image/upload/c_scale,w_1300/v.../3.jp"") no-repeat center;
      }
  }
javascript css vue.js vuejs2
3个回答
1
投票

我想到的最简单的解决方案是在页面安装时保存窗口宽度,并根据值动态添加类

data() { return { deviceWidth: 0 } }
设置组件挂载钩上的值

created() { this.deviceWidth = window.innerWidth; }
还有你的模板

// handle extra sizes <element :class="{'image-ios': deviceWidth < 480, 'image-small': deviceWidth >= 480}"></element>

请注意,您不需要 resizeListener,因为在现实生活中从智能手机输入时不会发生调整大小,因此安装/创建时屏幕的宽度就足够了


0
投票
您的资产是否包含在构建输出中?如果是这样,您应该让

Webpack 处理创建路径,而不是对它们进行硬编码。

如果这不是一个选项,您可以查看 CSS

image-set

,这是一种在媒体查询之外定义响应式图像的方法。但是,
浏览器支持不是很好

最后,您可以在 HTML 中使用

srcset

 属性,然后根据媒体查询隐藏/显示元素。

--编辑:

我忘记了你实际上可以在 VUE.js 模板中绑定样式。

v-bind:style

 
这是一个例子。这实际上改变了在构建时编译的样式块。这不是内联“计算”样式。

-- 编辑#2

使用 VUE 设置 CSS 变量

--backgroundImage

 然后可以在 CSS 的媒体查询中使用它。有人制作了一个很棒的 
Codepen 示例。

CSS

:root { --backgroundImage: 'blank.png'; } div { background-image: var(--backgroundImage); }

VUE

watch: { img(val){ element.style.setProperty('--backgroundImage', val) } }
    

0
投票
您可以使用

matchMedia 函数来控制要应用的值。这样,所有浏览器工程师都在优化屏幕调整大小计算。

<script setup> import { ref, computed, onUnmounted, onMounted} from "vue"; const mediaQuery = window.matchMedia('(min-width : 480px)'); const isScreenLarge = ref(mediaQuery.matches) const update = (event) => (isScreenLarge.value = event.matches); onMounted(() => mediaQuery.addEventListener("change", update)); onUnmounted(() => mediaQuery.removeEventListener("change", update)); const background = computed(() => isScreenLarge.value ? 'large.jpg' : 'small.jpg'; </script> <template> <div>some content</div> </template> <style scoped> div { background: v-bind(background); } </style>
您甚至可以构建一个

可组合来在应用程序的其他部分执行此操作。

© www.soinside.com 2019 - 2024. All rights reserved.