Vuetify v-select 组件宽度变化
Vuetify v-select component width changing
我的 v-select
组件应具有固定宽度 (60px),它们适合 table 单元格,我想防止它们在选择值后更改宽度。
他们改变了宽度,下拉箭头在选择后向右移动,所以如果有办法减小图标或其 padding/margin 的大小,可能会有所帮助。
真的不知道这个箭的道具怎么获得,怎么调用。
这是可重现的
https://codesandbox.io/s/competent-dew-eixq2?file=/src/components/Playground.vue
编辑:添加片段
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.0.1/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<style>
.select {
max-width: 60px;
max-height: 60px;
font-size: 11px;
}
.col {
max-width: 60px;
max-height: 60px;
}
</style>
</head>
<body>
<div id="app">
<v-app>
<v-row>
<div class="col" v-for="col in cols" :key="col">
<v-select class="select" :items="variants" item-value="name" item-text="name" label="" dense outlined hide-details single-line v-model="selected">
</v-select>
</div>
</v-row>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.0.1/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: {
selected: "",
cols: [1, 2, 3, 4, 5],
variants: [{
id: 0,
name: ""
},
{
id: 1,
name: "1:0"
},
{
id: 2,
name: "0:1"
},
{
id: 3,
name: "1:0 B"
},
{
id: 4,
name: "0:1 B"
},
{
id: 6,
name: "1:0 R"
},
{
id: 7,
name: "0:1 R"
},
{
id: 8,
name: "1:0 F"
},
{
id: 9,
name: "0:1 F"
},
],
},
})
</script>
</body>
</html>
1. 如果你不关心附加的图标,你可以使用 append-icon
prop(传递空值)将其删除:
<v-select
class="select"
...
append-icon=""
></v-select>
2.您可以用自己的内容覆盖图标的插槽:
<v-select
class="select"
...
>
<template #append>
<div class="my-custom-icon">...</div>
</template>
</v-select>
然后为您的 my-custom-icon
添加样式 class 使其出现在一个地方:
.my-custom-icon {
position: absolute;
left: ...;
right: ...;
}
3. 利用overflow: hidden
属性:
<style> // don't add "scoped" attribute, otherwise the style won't be applied
.select .v-input__control {
overflow: hidden;
}
</style>
基本问题是 v-select 有一些样式(特别是填充和边距)在小宽度下效果不佳。
这是呈现的 v-select 的 innerHTML,其中包含需要减少的样式
<div class="select...">
<div class="v-input__control">
<div role="button" class="v-input__slot"> <!-- padding-right: 12px; -->
<div class="v-select__slot">
<div class="v-select__selections">
<div class="v-select__selection--comma"> <!-- margin-right: 4px; -->
1:0 B
</div>
</div>
<div class="v-input__append-inner"> <!-- padding-left: 4px; -->
<div class="v-input__icon v-input__icon--append"> <!-- width: 24px; min-width: 24px;-->
<i aria-hidden="true" class="v-icon..."></i>
</div>
</div>
</div>
</div>
</div>
</div>
除了那些 innerHTML 更改之外,您希望每列的固定宽度为 60px,因此更改
<style>
.select {
max-width: 60px;
...
}
到
<style>
.select {
width: 60px;
...
}
调整 Vuetify 内部样式
查看有关样式的 Vuetify 问题,有人建议使用无作用域样式块或深度作用域样式块,但对我来说都不起作用。 Vuetify 表示他们正在努力改进应用样式的方式来克服这些问题。
幸运的是 Vue 本身在 javascript 中有工具可以做到这一点。
这些是关键步骤
- 添加对 v-select 的引用,以便它可以在 javascript
中访问
- 向 v-select 添加一个更改处理程序,以便当用户 select 有东西时可以重新设置元素的样式
- 定义对象中的样式调整,以便您轻松调整它们
- 添加应用样式的方法
- 调用
mounted()
中的方法和 v-select @change
处理程序
- 使用
Vue.nextTick()
让 Vuetify 先设置样式,然后应用我们的自定义样式
这是调整后的代码片段。我放入了一些非常小的填充和边距,并最大化了 space 的 selected 值(以避免文本换行)。您可能想尝试一下这些样式,因为我不确定我是否理解所有要求。
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.0.1/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<style>
.select {
width: 60px;
max-height: 60px;
font-size: 11px;
}
.col {
max-width: 60px;
max-height: 60px;
}
</style>
</head>
<body>
<div id="app">
<v-app>
<v-row>
<div class="col" v-for="col in cols" :key="col">
<v-select ref="select" @change="applyCustomStyles"
class="select" :items="variants" item-value="name" item-text="name" label="" dense outlined hide-details single-line v-model="selected">
</v-select>
</div>
</v-row>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.0.1/dist/vuetify.js"></script>
<script>
const customStyles = {
".v-input__slot": {
padding: "0 0 0 4px",
},
".v-select__selections": {
width: "27px",
},
".v-select__selection--comma": {
margin: "7px 0 7px 0",
},
".v-input__append-inner": {
"padding-left": "0",
},
".v-input__icon": {
width: "14px",
"min-width": "14px",
},
};
new Vue({
el: '#app',
vuetify: new Vuetify(),
mounted() {
this.applyCustomStyles();
},
methods: {
applyCustomStyles() {
Vue.nextTick(() => {
this.$refs.select.forEach((vSelect) => {
Object.entries(customStyles).forEach(([selector, styles]) => {
Object.entries(styles).forEach(([style, value]) => {
vSelect.$el.querySelector(selector).style[style] = value;
});
});
});
});
},
},
data: {
selected: "",
cols: [1, 2, 3, 4, 5],
variants: [{
id: 0,
name: ""
},
{
id: 1,
name: "1:0"
},
{
id: 2,
name: "0:1"
},
{
id: 3,
name: "1:0 B"
},
{
id: 4,
name: "0:1 B"
},
{
id: 6,
name: "1:0 R"
},
{
id: 7,
name: "0:1 R"
},
{
id: 8,
name: "1:0 F"
},
{
id: 9,
name: "0:1 F"
},
],
},
})
</script>
</body>
</html>
为什么不是 <style>
块?
有人建议使用无范围样式块来覆盖 Vuetify 样式。
例如,
<style>
.select .v-input__slot {
padding-right: 4px
}
...
</style>
问题是 Vuetify 样式是在组件上声明的样式之后应用的。
您可以通过应用比 Vuetify 使用的更高的特异性来做到这一点,例如
<style>
.select.v-text-field.v-text-field--enclosed:not(.v-text-field--rounded)>.v-input__control>.v-input__slot {
padding-right: 4px
}
</style>
给你这个
所以你可以找出所有需要更改的现有位置并复制 Vuetify selector.
使用新版本的Vuetify,或者更改组件的形状时,可能会出现问题。对我来说,javascript 解决方案看起来更易于管理。
你好我遇到了同样的问题但是因为我使用的是 vuetify v-select 定制的 select 我不能覆盖 CSS 因为它会改变整个 drop-down项目,这将适用于所有从事项目工作的开发人员
如此简单的解决方案是制作容器 div 并为其提供 min-width 最大宽度和您认为合适的宽度,它将解决 table 单元格[=11] 的尺寸变化问题=]
它对我有用,因为我将容器的 drop-down 最小宽度设置为 max-width,因此它的宽度相同
例
<div :class='container'>
<v-select />
</div>
<style>
. container {
max-width: 9rem // in my case it's the min width for my default selected option
}
</style>
我的 v-select
组件应具有固定宽度 (60px),它们适合 table 单元格,我想防止它们在选择值后更改宽度。
他们改变了宽度,下拉箭头在选择后向右移动,所以如果有办法减小图标或其 padding/margin 的大小,可能会有所帮助。
真的不知道这个箭的道具怎么获得,怎么调用。
这是可重现的
https://codesandbox.io/s/competent-dew-eixq2?file=/src/components/Playground.vue
编辑:添加片段
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.0.1/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<style>
.select {
max-width: 60px;
max-height: 60px;
font-size: 11px;
}
.col {
max-width: 60px;
max-height: 60px;
}
</style>
</head>
<body>
<div id="app">
<v-app>
<v-row>
<div class="col" v-for="col in cols" :key="col">
<v-select class="select" :items="variants" item-value="name" item-text="name" label="" dense outlined hide-details single-line v-model="selected">
</v-select>
</div>
</v-row>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.0.1/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: {
selected: "",
cols: [1, 2, 3, 4, 5],
variants: [{
id: 0,
name: ""
},
{
id: 1,
name: "1:0"
},
{
id: 2,
name: "0:1"
},
{
id: 3,
name: "1:0 B"
},
{
id: 4,
name: "0:1 B"
},
{
id: 6,
name: "1:0 R"
},
{
id: 7,
name: "0:1 R"
},
{
id: 8,
name: "1:0 F"
},
{
id: 9,
name: "0:1 F"
},
],
},
})
</script>
</body>
</html>
1. 如果你不关心附加的图标,你可以使用 append-icon
prop(传递空值)将其删除:
<v-select
class="select"
...
append-icon=""
></v-select>
2.您可以用自己的内容覆盖图标的插槽:
<v-select
class="select"
...
>
<template #append>
<div class="my-custom-icon">...</div>
</template>
</v-select>
然后为您的 my-custom-icon
添加样式 class 使其出现在一个地方:
.my-custom-icon {
position: absolute;
left: ...;
right: ...;
}
3. 利用overflow: hidden
属性:
<style> // don't add "scoped" attribute, otherwise the style won't be applied
.select .v-input__control {
overflow: hidden;
}
</style>
基本问题是 v-select 有一些样式(特别是填充和边距)在小宽度下效果不佳。
这是呈现的 v-select 的 innerHTML,其中包含需要减少的样式
<div class="select...">
<div class="v-input__control">
<div role="button" class="v-input__slot"> <!-- padding-right: 12px; -->
<div class="v-select__slot">
<div class="v-select__selections">
<div class="v-select__selection--comma"> <!-- margin-right: 4px; -->
1:0 B
</div>
</div>
<div class="v-input__append-inner"> <!-- padding-left: 4px; -->
<div class="v-input__icon v-input__icon--append"> <!-- width: 24px; min-width: 24px;-->
<i aria-hidden="true" class="v-icon..."></i>
</div>
</div>
</div>
</div>
</div>
</div>
除了那些 innerHTML 更改之外,您希望每列的固定宽度为 60px,因此更改
<style>
.select {
max-width: 60px;
...
}
到
<style>
.select {
width: 60px;
...
}
调整 Vuetify 内部样式
查看有关样式的 Vuetify 问题,有人建议使用无作用域样式块或深度作用域样式块,但对我来说都不起作用。 Vuetify 表示他们正在努力改进应用样式的方式来克服这些问题。
幸运的是 Vue 本身在 javascript 中有工具可以做到这一点。
这些是关键步骤
- 添加对 v-select 的引用,以便它可以在 javascript 中访问
- 向 v-select 添加一个更改处理程序,以便当用户 select 有东西时可以重新设置元素的样式
- 定义对象中的样式调整,以便您轻松调整它们
- 添加应用样式的方法
- 调用
mounted()
中的方法和 v-select@change
处理程序 - 使用
Vue.nextTick()
让 Vuetify 先设置样式,然后应用我们的自定义样式
这是调整后的代码片段。我放入了一些非常小的填充和边距,并最大化了 space 的 selected 值(以避免文本换行)。您可能想尝试一下这些样式,因为我不确定我是否理解所有要求。
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.0.1/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<style>
.select {
width: 60px;
max-height: 60px;
font-size: 11px;
}
.col {
max-width: 60px;
max-height: 60px;
}
</style>
</head>
<body>
<div id="app">
<v-app>
<v-row>
<div class="col" v-for="col in cols" :key="col">
<v-select ref="select" @change="applyCustomStyles"
class="select" :items="variants" item-value="name" item-text="name" label="" dense outlined hide-details single-line v-model="selected">
</v-select>
</div>
</v-row>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.0.1/dist/vuetify.js"></script>
<script>
const customStyles = {
".v-input__slot": {
padding: "0 0 0 4px",
},
".v-select__selections": {
width: "27px",
},
".v-select__selection--comma": {
margin: "7px 0 7px 0",
},
".v-input__append-inner": {
"padding-left": "0",
},
".v-input__icon": {
width: "14px",
"min-width": "14px",
},
};
new Vue({
el: '#app',
vuetify: new Vuetify(),
mounted() {
this.applyCustomStyles();
},
methods: {
applyCustomStyles() {
Vue.nextTick(() => {
this.$refs.select.forEach((vSelect) => {
Object.entries(customStyles).forEach(([selector, styles]) => {
Object.entries(styles).forEach(([style, value]) => {
vSelect.$el.querySelector(selector).style[style] = value;
});
});
});
});
},
},
data: {
selected: "",
cols: [1, 2, 3, 4, 5],
variants: [{
id: 0,
name: ""
},
{
id: 1,
name: "1:0"
},
{
id: 2,
name: "0:1"
},
{
id: 3,
name: "1:0 B"
},
{
id: 4,
name: "0:1 B"
},
{
id: 6,
name: "1:0 R"
},
{
id: 7,
name: "0:1 R"
},
{
id: 8,
name: "1:0 F"
},
{
id: 9,
name: "0:1 F"
},
],
},
})
</script>
</body>
</html>
为什么不是 <style>
块?
有人建议使用无范围样式块来覆盖 Vuetify 样式。
例如,
<style>
.select .v-input__slot {
padding-right: 4px
}
...
</style>
问题是 Vuetify 样式是在组件上声明的样式之后应用的。
您可以通过应用比 Vuetify 使用的更高的特异性来做到这一点,例如
<style>
.select.v-text-field.v-text-field--enclosed:not(.v-text-field--rounded)>.v-input__control>.v-input__slot {
padding-right: 4px
}
</style>
给你这个
所以你可以找出所有需要更改的现有位置并复制 Vuetify selector.
使用新版本的Vuetify,或者更改组件的形状时,可能会出现问题。对我来说,javascript 解决方案看起来更易于管理。
你好我遇到了同样的问题但是因为我使用的是 vuetify v-select 定制的 select 我不能覆盖 CSS 因为它会改变整个 drop-down项目,这将适用于所有从事项目工作的开发人员
如此简单的解决方案是制作容器 div 并为其提供 min-width 最大宽度和您认为合适的宽度,它将解决 table 单元格[=11] 的尺寸变化问题=]
它对我有用,因为我将容器的 drop-down 最小宽度设置为 max-width,因此它的宽度相同
例
<div :class='container'>
<v-select />
</div>
<style>
. container {
max-width: 9rem // in my case it's the min width for my default selected option
}
</style>