如何在 Vue 组件中将 Vuetify 的材料设计颜色名称转换为十六进制值?



我想在Vue组件的模板中获得一个Vuetify材质设计颜色作为十六进制值,这样我就可以在下面这样做来获得字符串#FFD54F:

<div :style="`border: 5px solid ${ myHexadecimalColor('amber lighten-2') }`">
</div>

我阅读了Vuetify文档的SASS变量和颜色部分,但我无法从中确定解决方案。

我可以看到Vuetify的github-reo@vuetify/packages/vuetify/src/styles/settings/_colors.scss中定义的颜色,但我不知道如何在我的Vue单个文件组件中访问这些Sass变量。

有人知道将Vuetify材料设计颜色名称转换为其十六进制值的最佳方法吗?


奖金-Vuetify 2名称到十六进制函数

根据Boussadjra Brahim的回答,我为十六进制方法写了一个快速的颜色名称,以放入Vue mixin,并将其包含在下面,以防对任何人都有帮助。

示例:hexColor('amber lighten-2')返回#FFD54F

import colors from 'vuetify/lib/util/colors'
methods: {
hexColor: (name) => {
const [nameFamily, nameModifier] = name.split(' ')
const shades = ['black', 'white', 'transparent']
const util = {family: null, modifier: null}
if (shades.find(shade => shade === nameFamily)){
util.family = 'shades'
util.modifier = nameFamily
} else {
const [firstWord, secondWord] = nameFamily.split('-')
util.family = `${ firstWord }${ secondWord
? secondWord.charAt(0).toUpperCase() + secondWord.slice(1)
: '' }`
util.modifier = nameModifier 
? nameModifier.replace('-', '') 
: 'base'
}
return colors[util.family][util.modifier]
}
}

将Vuetify 3名称更新为十六进制函数

以下是Vuetify 3的hexColor()版本。这是必要的,因为颜色名称已从例如blue lighten-2更改为blue-lighten-2

import colors from 'vuetify/lib/util/colors'
hexColor: (name) => {
const baseColors = ['red','pink','purple','deep-purple','indigo','blue','light-blue','cyan','teal','green','light-green','lime','yellow','amber','orange','deep-orange','brown','blue-grey','grey']
const shades = ['black', 'white', 'transparent']
const match = [...baseColors,...shades].find(c => name.startsWith(c)) || null
const remainder = match 
? name.slice(match.length) 
: null
const base = match.replace(/[-_](.)/g, (_, char) => char.toUpperCase());
const variety = remainder 
? remainder.replaceAll('-','')
: 'base'
const nameStructured = shades.find(shade => match === shade) 
? { base:'shades', variety:base}
: { base:base, variety:variety}
return colors[nameStructured.base][nameStructured.variety]
}

将颜色导入组件,然后使用它的修饰符访问颜色,如:


import colors from 'vuetify/lib/util/colors'
....
<div :style="`border: 5px solid ${ colors['amber']['lighten2'] }`"></div>

因此,虽然接受的答案是正确的,但我认为更完整的功能还包括翻译主题颜色(如successerror(及其色调(如success darken-2(的能力,以及在颜色已作为十六进制、rgb或rgba传递时处理输入的能力。

以下是我在mixin中实现的一个函数:

import colors from 'vuetify/lib/util/colors';
...
methods: {
translateColor(color) {
if ('string' !== typeof color || color.trim().length == 0) {
return color;
}
if (color.startsWith('#') || color.startsWith('rgb')) {
return color;
}
const themeColors = Object.keys(this.$vuetify.theme.currentTheme);
const themeColorIndex = themeColors.indexOf(color);
if (themeColorIndex > -1) {
return this.$vuetify.theme.currentTheme[color];
}
let baseColor;
let shade;
if (color.includes(' ')) {
const [bc, s] = color.split(' ');
baseColor = bc;
shade = s;
}
else {
baseColor = color;
shade = 'base';
}
const generalColors = Object.keys(colors);
const generalColorsIndex = generalColors.indexOf(baseColor);
const themeColorsShadeIndex = themeColors.indexOf(baseColor);
if (generalColorsIndex > -1) {
const fixedShade = shade.toLowerCase().replace('-', '');
const co = colors[generalColors[generalColorsIndex]];
return co[fixedShade];
}
else if (themeColorsShadeIndex > -1) {
const fixedShade = shade.toLowerCase().replace('-', '');
const co = this.$vuetify.theme.parsedTheme[themeColors[themeColorsShadeIndex]]
return co[fixedShade];
}
return color;
}
}

现在我确信我的方法可以进行优化,但总的来说,它可以从包含的材料设计颜色和主题的颜色中读取。

Vue3/Vuetify 3的更新答案

以下是我在最近的Nuxt 3项目中采用的方法:

import colors from "vuetify/lib/util/colors";
import { vuetify } from "~/plugins/vuetify";
export default function colorToCssColor(color?: string): string {
if (typeof color !== "string" || color.trim().length === 0) {
return color as string;
}
if (color.startsWith("#") || color.startsWith("rgb")) {
return color;
}
const themeColors = vuetify.theme.current.value.colors;
const stringToColor = new Map<string, string>([
["black", colors.shades.black],
["white", colors.shades.white],
["transparent", colors.shades.transparent],
]);
const regularColors = [
"red",
"pink",
"purple",
"deepPurple",
"indigo",
"blue",
"lightBlue",
"cyan",
"teal",
"green",
"lightGreen",
"lime",
"yellow",
"amber",
"orange",
"deepOrange",
"brown",
"blueGrey",
"grey",
] as const;
regularColors.forEach((regularColor) => {
stringToColor.set(regularColor, colors[regularColor].base);
stringToColor.set(
`${regularColor}-lighten-1`,
colors[regularColor].lighten5
);
stringToColor.set(
`${regularColor}-lighten-2`,
colors[regularColor].lighten4
);
stringToColor.set(
`${regularColor}-lighten-3`,
colors[regularColor].lighten3
);
stringToColor.set(
`${regularColor}-lighten-4`,
colors[regularColor].lighten2
);
stringToColor.set(
`${regularColor}-lighten-5`,
colors[regularColor].lighten1
);
stringToColor.set(`${regularColor}-darken-6`, colors[regularColor].darken1);
stringToColor.set(`${regularColor}-darken-7`, colors[regularColor].darken2);
stringToColor.set(`${regularColor}-darken-8`, colors[regularColor].darken3);
stringToColor.set(`${regularColor}-darken-9`, colors[regularColor].darken4);
});
for (const key in themeColors) {
if (!key.startsWith("on-")) {
stringToColor.set(key, themeColors[key as keyof typeof themeColors]);
}
}
const val = stringToColor.get(color);
if (val) {
return val;
}
return "";
}

最新更新