我有一个 VDialog,其中包含一个 VCard,而 VCard 又包含一个 VSelect。当我打开 VSelect 时,很难看到选项的下拉列表,因为它的颜色与 VCard 相同。两者似乎都有
background: rgb(var(--v-theme-surface));
唯一让下拉菜单脱颖而出的是阴影,但在黑暗主题中,你几乎看不到它。
如果 VSelect(或 VMenu、VCombobox)位于 VDialog 或 VCard 内,建议更改其背景的方法是什么?
我知道 Vuetify 3 有一种方法可以更改全局配置(包括嵌套选项,例如 VCard 内的 VSelect),但我无法使其工作。
我还尝试使用 CSS 变量,更改
--v-theme-surface
CSS 属性的值,但看起来下拉列表已移到父容器之外并靠近 html <body>
,因此我无法定位它。
有没有办法将 CSS 类“发送”到子下拉菜单中,以便我可以这样定位它?
非常感谢。
我不知道如何直接通过 Vuetify 更改嵌套组件的样式,但是使用
:menu-props
属性,您可以将配置对象传递给底层 v-menu
组件。 :content-class
属性的内容将被设置为覆盖内容节点上的类:
<v-select
...
:menu-props="{
contentClass: 'lighter-surface',
}"
>
有了这个,您现在可以定义 CSS 规则来调整背景颜色变量:
.lighter-surface > .v-theme--dark{
--v-theme-surface: var(--v-theme-on-surface-variant); /* or something like 55,55,55; */
}
const { createApp } = Vue;
const { createVuetify } = Vuetify
const vuetify = createVuetify({theme: {defaultTheme: 'dark'}})
const app = {}
createApp(app).use(vuetify).mount('#app')
.lighter-surface > .v-theme--dark{
--v-theme-surface: var(--v-theme-on-surface-variant);
}
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" />
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<div id="app">
<v-app>
<v-main>
<v-card class="ma-4">
<v-card-title>Selection Card</v-card-title>
<v-card-text>
<v-select
:items="['option 1', 'option 2', 'option 3']"
label="Select"
:menu-props="{
contentClass: 'lighter-surface',
}"
></v-select>
<div style="height: 200px;">
</div>
</v-card-text>
</v-card>
</v-main>
</v-app>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
如果您不想更改全局样式,可以尝试使用
v-menu
属性将 v-card
附加到
:attach
,然后就可以使用本地样式。但不确定是否值得。
或者你可以通过添加自己的主题来解决:
const vuetify = createVuetify({
theme: {
defaultTheme: 'dark',
themes: {
darkOnSurface: { // <--- name of the theme
dark: true, // <--- extend dark theme
colors: {
surface: 'blue', // <--- override color variant from dark theme
}
}
}
}
})
然后在
v-menu
中设置该主题:
<v-select
...
:menu-props="{
theme: 'darkOnSurface',
}"
></v-select>
优点是你可以在所有 Vuetify 组件上使用它。
const {
createApp
} = Vue;
const {
createVuetify
} = Vuetify
const vuetify = createVuetify({
theme: {
defaultTheme: 'dark',
themes: {
darkOnSurface: {
dark: true,
colors: {
surface: 'blue',
}
}
}
}
})
const app = {}
createApp(app).use(vuetify).mount('#app')
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" />
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<div id="app">
<v-app>
<v-main>
<v-card class="ma-4">
<v-card-title>Selection Card</v-card-title>
<v-card-text>
<v-select
:items="['option 1', 'option 2', 'option 3']"
label="Select"
:menu-props="{
theme: 'darkOnSurface',
}"
></v-select>
<div style="height: 200px;">
</div>
</v-card-text>
</v-card>
</v-main>
</v-app>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
谢谢你!我做了一些测试,你的三种方法效果很好。这是我对它们的看法。
一、模板:
<v-card id="my-card" style="padding: 1rem; height: 17rem;">
<v-select label="By Props" :menu-props="{contentClass: 'lighter-surface' }" />
<v-select label="By Theme" theme="onSurface" />
<v-select label="By Attach" :menu-props="{attach: '#my-card' }" />
</v-card>
CSS:
// For the 'By Props' method
.lighter-surface [class*=' v-theme--'] {
--v-theme-surface: var(--v-theme-inner-surface);
--v-theme-on-surface: var(--v-theme-on-inner-surface);
}
// For the 'By Attach' method
.v-card [class*=' v-theme--'] {
--v-theme-surface: var(--v-theme-inner-surface);
--v-theme-on-surface: var(--v-theme-on-inner-surface);
}
Vuetify.ts
const defaultDark: ThemeDefinition = {
dark: true,
colors: {
background: '#1D1716',
surface: '#322929',
'inner-surface': '#BDBDBD', // For the By Props & Attach method
primary: '#793C86',
},
}
const onSurface: ThemeDefinition = {
dark: true,
colors: { surface: '#BDBDBD' }, // For the By Theme method
}
createVuetify({
theme: {
defaultTheme: 'defaultDark',
themes: { defaultDark, onSurface },
},
})
就个人而言,我更喜欢“通过道具”方法。
“通过附加”方法会导致功能发生变化,例如如果掉落物溢出容器,则会被切断。
“按主题”方法要求始终有两个维护的主题。我更喜欢每个主题都包含整个应用程序中使用的所有颜色。
遗憾的是,没有办法自动检测 VCard 中是否使用了 VMenu,而无需使用菜单属性明确标记它。但是,嘿,这效果非常好!
您可以使用上下文默认值来执行此操作:https://vuetifyjs.com/en/features/global-configuration/
createVuetify({
theme: {
themes: {
light: {
colors: { 'inner-surface': '#f00' },
},
},
},
defaults: {
VCard: {
VSelect: {
VList: { bgColor: 'inner-surface' },
},
},
},
})