Vuetify v-select 组件宽度改变

问题描述 投票:0回答:4

我的

v-select
组件应具有固定宽度(60px),它们适合表格单元格,我想防止它们在选择值后更改宽度。

它们会更改宽度,并且下拉箭头在选择后会向右移动,因此如果有办法减小图标或其填充/边距的大小,可能会有所帮助。

不太清楚如何获取这个箭头的 props 以及它是如何调用的。

这是可重现的

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/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/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/[email protected]/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/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>

css vue.js vuetify.js v-select
4个回答
5
投票

基本问题是 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>

除了这些 insideHTML 更改之外,您还需要每列 60px 的固定宽度,因此请更改

<style>
  .select {
    max-width: 60px;
    ...
  }

<style>
  .select {
    width: 60px;
    ...
  }

调整 Vuetify 内部样式

查看有关样式的 Vuetify 问题,有人建议使用无范围样式块或深层样式块,但这对我来说都不起作用。 Vuetify 表示他们正在努力改进样式的应用方式以克服这些问题。

幸运的是,Vue 本身有工具可以用 javascript 完成此操作。

这些是关键步骤

  • 添加对 v-select 的引用,以便可以在 javascript 中访问它
  • 向 v-select 添加更改处理程序,以便在用户选择某些内容时可以重新设置元素的样式
  • 定义对象中的样式调整,以便您可以轻松调整它们
  • 添加应用样式的方法
  • 调用
    mounted()
    中的方法和 v-select
    @change
    处理程序
  • 使用
    Vue.nextTick()
    允许 Vuetify 首先设置样式,然后应用我们的自定义样式

这是调整后的代码片段。我放入了一些非常小的填充和边距,并最大化了所选值的空间(以避免文本换行)。您可能想尝试一下这些样式,因为我不确定我是否理解所有要求。

<!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/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/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/[email protected]/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/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 选择器。

使用新版本的Vuetify,或者改变组件的形状时,可能会出现此问题。对我来说,javascript 解决方案看起来更易于管理。


2
投票

1. 如果您不关心附加的图标,可以使用

append-icon
属性将其删除(传递空值):

<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
类添加样式,使其出现在一个位置:

.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>

0
投票

您好,我面临着同样的问题,但由于我使用的是 vuetify v-select 中的自定义选择,我无法覆盖 CSS,因为它会更改整个项目中的下拉菜单,并且所有从事项目的开发人员都会遇到这种情况

如此简单的解决方案是制作容器 div 并为其指定最小宽度、最大宽度和宽度,如您认为合适,它将解决表格单元格的尺寸更改问题

它对我有用,因为我将下拉最小宽度设置为容器的最大宽度,因此它将具有相同的宽度

例如

<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>
 

0
投票

如果这对任何人有帮助,我可以通过在其上应用

v-select
来消除
class="flex-shrink-1 flex-grow-0"
的额外宽度。使其宽度根据所选项目的需要而定。我正在使用 Vuetify
3.5.8

© www.soinside.com 2019 - 2024. All rights reserved.