1

我正在尝试创建一个customCombobox像正常工作一样的组件,v-combobox添加一个 - 在用户按下tab键后,它将自动选择第一个选项(如果有的话)。

到目前为止我所做的看起来不错,但v-model在这个领域不起作用(它总是null)。

<template>
  <v-combobox ref="combobox" :rules="rules"
              @keydown.tab.prevent="selectFirst"
              :value="innerValue" :label="label"
              :items="items"

  >

  </v-combobox>
</template>
<script>
module.exports = {
  props: ['value', 'label', 'items', 'rules'],
  data() {
    return {
      innerValue:null,
    }
  },
  watch:{
    value(_new){
       this.innerValue = _new
      this.$emit('input',[_new])
      this.$emit('change')
    }
  },
  methods: {
    selectFirst() {
      var combobox = this.$refs.combobox
      var filteredItems = combobox.filteredItems
      if (filteredItems.length){
          this.innerValue = filteredItems[0]
      }
    }
  },
  computed: {

  }
}
</script>

你知道为什么吗?

4

1 回答 1

2

您可以在自定义组件中使用计算的 setter 来处理v-model来自父级的并将其传递给它自己的子级v-combobox

自定义组件:

<v-combobox v-model="selected" v-bind="$attrs"></v-combobox>
computed: {
  selected: {
    get() {
      return this.value;
    },
    set(val) {
      this.$emit('input', val);
    }
  }
}

Usingv-bind="$attrs"还会从父级传递所有道具。这是一个演示:

Vue.component('comp', {
  props: ['value'],
    template: `
    <v-combobox v-model="selected" v-bind="$attrs"></v-combobox>
  `,
  computed: {
    selected: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit('input', val);
      }
    }
  }
})

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data() {
    return {
      selected: 'Vue',
      label: 'This is my label',
      rules: ['These are my rules'],
      items: ['Programming', 'Design', 'Vue', 'Vuetify']
    }
  }
})
#app {
  padding: 48px;
}
<div id="app">
  <v-app id="inspire">
    Selected in parent: {{ selected }}
    <comp
         v-model="selected"
         :label="label"
         :items="items"></comp>
  </v-app> 
</div>

<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.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>

于 2020-12-07T18:54:06.233 回答