当前位置: 首页 > 知识库问答 >
问题:

vue.js - 这个Vue的Less代码中的@media样式要怎么样才能生效?

巢皓君
2024-06-13

我写的这个Vue的Less样式为什么没有生效?

<template>  <div class="grid-list">    <slot />  </div></template><script setup>import {computed} from 'vue';const props = defineProps({  itemWidth: {    type: String,    default: '300px',  },});const itemWidth = computed(() => {  return props.itemWidth;});</script><style lang="less">.grid-list {  display: grid;  gap: 16px;  grid-auto-rows: minmax(172px, auto);}@iw: e(%('%d', v-bind(itemWidth)));.loop(@index) when (@index < 20) {  @media (min-width: calc(288px + 16px * (@index - 1) + @iw * @index)) {    .grid-list {      grid-template-columns: repeat(@index, 1fr);    }  }  .loop(@index + 1);}.loop(1);</style>

上面是我写的一个自定义组件,但是@media这里的代码没有生效,请问我这里少了什么步骤吗?

共有3个答案

夏知
2024-06-13

有点绕,但是大概能明白你期望在 less 中使用当前的 itemWith 变量的值来作为计算值。

但是你要明白 less 是预处理样式,在编译阶段就已经编译成了普通的CSS了,并不会获取到项目在浏览器中运行的值。除非你的 props.itemWith 是一个固定的值比如说:

<script setup>const testStyle = {  itemWidth: '300px'}</script><style lang="less">.grid-list {  display: grid;  gap: 16px;  grid-auto-rows: minmax(172px, auto);}@iw: e(%('%d', v-bind(testStyle.itemWidth)));.loop(@index) when (@index < 20) {  @media (min-width: calc(288px + 16px * (@index - 1) + @iw * @index)) {    .grid-list {      grid-template-columns: repeat(@index, 1fr);    }  }  .loop(@index + 1);}.loop(1);</style>

所以要达到你期望的目标,可以使用 CSS 自定义属性 来实现。举个例子

<template>  <div  :style="cssVars">    <div class="grid-list">      <slot />    </div>  </div></template><script setup>import {computed} from 'vue';const props = defineProps({  itemWidth: {    type: String,    default: '300px',  },});const cssVars = computed(() => {  return {    "--itemWidth": props.itemWidth  };});</script><style lang="less">.grid-list {  display: grid;  gap: 16px;  grid-auto-rows: minmax(172px, auto);}.loop(@index) when (@index < 20) {  @media (min-width: calc(288px + 16px * (@index - 1) + var(--itemWidth) * @index)) {    .grid-list {      grid-template-columns: repeat(@index, 1fr);    }  }  .loop(@index + 1);}.loop(1);</style>

但是不一定对,我不太确定能否在 calc() 中使用 CSS variables

荆学民
2024-06-13

把@media的样式代码放到下面,确保嵌套层级一样,就会覆盖上面的。

蒙奇
2024-06-13

您提供的Vue组件代码使用了Less语言来编写样式,并试图通过Less的循环来生成一系列基于媒体查询的样式规则。然而,您的代码中存在几个问题,导致@media样式没有生效。

  1. Less不直接支持变量插值到calc函数中,这可能导致编译错误。
  2. Less的混合(mixins)和循环不直接支持动态创建媒体查询,因此您的方法可能不会按预期工作。

以下是您可以尝试的修改步骤,以便生成有效的媒体查询样式:

  1. 使用CSS变量:Vue 3支持在样式中使用CSS变量,这允许您根据组件的props动态地改变样式。不过,CSS变量不能直接用在媒体查询中,因此您可能需要使用JavaScript来计算媒体查询的值,并将它们添加到组件的class或style中。
  2. 避免在Less中使用循环创建媒体查询:Less的循环通常用于生成重复的CSS规则,而不是创建动态的媒体查询。媒体查询通常需要基于实际计算的断点来创建,而断点通常是由组件的props或其他动态因素决定的。
  3. 使用计算属性来动态设置样式:您可以通过Vue的计算属性来计算媒体查询的断点,并将它们以某种方式(例如,绑定到元素的class或style属性)应用到模板中。这通常意味着您需要编写一些JavaScript代码来管理这些样式,而不是完全依赖Less的预处理器功能。
  4. 使用第三方库:有些库可能提供了更高级的功能,可以帮助您根据props或其他因素动态生成媒体查询。这些库可能提供了更简洁的API来处理这类问题。

由于这个问题涉及到动态创建媒体查询,而Less并不直接支持这种用法,因此解决方案可能会比较复杂。您可能需要重新考虑如何组织您的代码,以便更好地利用Vue和CSS的功能来实现您的目标。

最后,请注意,对于动态媒体查询,通常更好的做法是在组件的JavaScript部分进行计算,并根据需要动态地添加或删除CSS类,而不是试图在样式预处理器中处理所有逻辑。

 类似资料: