Scss的rgba()方法无法对变量进行二次编译?

如题所示。
想通过主题色去控制阴影颜色透明度,scss提供的rgba($color, $alpha)就可以实现
但是--app-color: v-bind("appInfo.color"); $appColor: rgba(var(--app-color), 0.45)无法生效,仅可不使用变量$appColor: rgba(#f36, 0.45)才可生效

原因是rgba()无法对变量进行二次编译

请问该如何实现对一个动态颜色的透明度计算呢?

<template>
  <div class="root">测试文本</div>
</template>

<script setup lang="ts">
const appInfo = { color: '#f36' }
</script>

<style lang="scss" scoped>
.root {
  --app-color: #f36;
  --app-color: v-bind('appInfo.color');

  // $appColor: rgba(var(--app-color), 0.85); // ×
  $appColor: rgba(#f36, 0.85); // √

  width: 400px;
  height: 200px;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid #f5f5f5;

  color: $appColor;
}
</style>

image.png

阅读 534
avatarAI BotBETA

回答

在 SCSS 中直接通过 CSS 变量(也称为自定义属性)和 Vue 的 v-bind 来动态设置 SCSS 变量是不可能的,因为 SCSS 是在编译时运行的,而 CSS 变量和 Vue 的数据绑定是在运行时生效的。这意味着你不能直接在 SCSS 文件中使用 Vue 的数据绑定来动态改变 SCSS 变量的值。

要实现根据系统主题色去控制阴影颜色透明度,你可以使用 CSS 变量和 Vue 的动态样式绑定来完成。以下是如何修改你的代码来实现这一功能:

<template>
  <div :style="divStyle"></div>
</template>

<script setup lang="ts">
import { computed } from 'vue';
import { useAppInfoStore } from './stores/appInfoStore'; // 假设你的 store 路径是这样的

const { appInfo } = useAppInfoStore();
const divStyle = computed(() => ({
  '--app-color': appInfo.color,
  boxShadow: '0 0 8px rgba(0, 0, 0, 0.12)',
  '&:hover': {
    boxShadow: `
      0 0 8px rgba(0, 0, 0, 0.12),
      inset 0 0 8px rgba(var(--app-color), 0.45)
    `.replace(/\s+/g, ' ') // 去除多余的空白字符以符合 CSS 语法
  }
}));
</script>

<style lang="css" scoped>
div {
  /* 使用 CSS 变量 */
  --app-color: #000; /* 默认值,Vue 绑定会覆盖这个值 */
}

/* 注意:这里的 hover 样式不能直接写在 CSS 中,因为 CSS 不支持在伪类中直接设置变量值 */
</style>

注意

  1. 由于 CSS 的限制,你不能直接在 :hover 伪类中设置 CSS 变量的值,因此我们需要使用 Vue 的动态样式绑定来处理。
  2. rgba(var(--app-color), 0.45) 是 CSS 中使用 CSS 变量设置 rgba 颜色的正确方式。
  3. 样式字符串中的多余空白字符可能会导致 CSS 解析错误,因此使用 .replace(/\s+/g, ' ') 来去除它们。

这种方法利用了 Vue 的动态样式绑定和 CSS 变量的灵活性,可以实现在运行时根据 Vue 的状态动态改变样式。

2 个回答

原生 css 有 rgba 函数:

element.style {
  --v: #dc3545;
  color: rgba(from var(--v) r g b / 0.5);
}

通过创建额外变量通过hexToRgba()获取计算透明度后的值,然后再绑定给css变量去使用

<script setup lang="ts">
const appInfo = ref({ color: '#f36' })
const appColorAlpha = computed(() => hexToRgba(appInfo.value.color, 0.45))
</script>

<style lang="scss" scoped>
.root {
  --app-color: v-bind('appInfo.color');
  --app-color-alpha: v-bind('appColorAlpha')

  color: var(--app-color-alpha)
}
</style>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏