VueSelect Как установить начальное значение со свойством объекта - PullRequest
0 голосов
/ 09 июля 2019

Я использую VueSelect для выбора адреса.Существует 3 выбранных компонента для страны, штата, города.

При использовании v-модели хорошо работает получение заданного значения вместо объекта опции с помощью метода Reduction prop.Здесь моя проблема заключается в том, чтобы не устанавливать значение по умолчанию по значению ключа.

Я ожидал, что он установит значение по умолчанию по идентификатору, как HTML выбор.но он показывает значение ключа в том виде, как он есть, а не привязывается значением метки.
Надеюсь, вы сможете понять смысл моего объяснения.
Ожидается, как v-select vuetify. пример vuetify

<template>
  <div class="col-sm-6 ">
    <v-select
        v-model="address.country_id"
        :options="countryOptions"
        :reduce="country => country.id"
        label="name"
        @input="resetStateAndCity"
        :resetOnOptionsChange="true"
    />
  </div>

  <div class="col-sm-6">
    <v-select
        v-model="address.state_id"
        :options="stateOptions"
        :reduce="state => state.id"
        label="name"
        @input="resetCity"
        :resetOnOptionsChange="true"
    />
  </div>

  <div class="col-sm-6">
    <v-select
        v-model="address.city_id"
        :options="cityOptions"
        :reduce="city => city.id"
        label="name"
        :resetOnOptionsChange="true"
    />
  </div>
</template>
<script>
  import VSelect from 'vue-select'

  export default {
    components: {
      VSelect
    },
    data: function () {
      return {
        address: {
          city_id: null,
          state_id: null,
          country_id: null
        },
        countryOptions: [],
        stateOptions: [],
        cityOptions: []
      }
    },
    mounted() {
      this.$axios.get('/countries.json')
        .then(response => {
          this.countryOptions = response.data
        })
    },
    methods: {
      resetStateAndCity() {
        if (!this.address.country_id) return
        this.$axios.get(`/countries/${this.address.country_id}/states.json`)
          .then(response => {
            this.stateOptions = response.data
          })
        this.address.state_id = null
        this.address.city_id = null
        this.cityOptions = []
      },
      resetCity() {
        if (!this.address.country_id || !this.address.state_id) return
        this.address.city_id = null
        this.$axios.get(`/countries/${this.address.country_id}/states/${this.address.state_id}/cities.json`)
          .then(response => {
            this.cityOptions = response.data
          })
      }
    }
  }
</script>

1 Ответ

0 голосов
/ 11 июля 2019

Ниже я обрисовал два разных подхода.В целом, я думаю, что предпочитаю второй подход, но он может зависеть от ваших обстоятельств, которые лучше всего подходят для вас.

new Vue({
  el: '#app',

  components: {
    'v-select': VueSelect.VueSelect
  },

  data: function() {
    return {
      input: {
        user_id: 2
      },
      users: []
    }
  },
  
  methods: {
    getOptionLabel (option) {
      return (option && option.name) || ''
    }
  },
  
  created () {
    setTimeout(() => {
      this.users = [
        {
          id: 1,
          name: "John",
          last: "Doe"
        },
        {
          id: 2,
          name: "Harry",
          last: "Potter"
        },
        {
          id: 3,
          name: "George",
          last: "Bush"
        }
      ]
      
      const currentUser = this.users.find(user => user.id === this.input.user_id)
      
      this.$refs.select.updateValue(currentUser)
    }, 1000)
  }
})
<link rel="stylesheet" href="https://unpkg.com/vue-select@3.1.0/dist/vue-select.css">
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<script src="https://unpkg.com/vue-select@3.1.0/dist/vue-select.js"></script>
<div id="app">
  <v-select
    ref="select"
    v-model="input.user_id"
    :options="users"
    :reduce="user => user.id"
    :get-option-label="getOptionLabel"
  ></v-select>
</div>

Основным препятствием является то, что Vue Select использует внутреннее состояние для отслеживания текущего выбранного значения при использовании reduce.См .:

https://github.com/sagalbot/vue-select/blob/master/src/components/Select.vue#L833

Хуже того, значение, хранимое в этом состоянии, является не сокращенным идентификатором, а целым объектом из options.Так что, если вначале нет options, он попадает в правильный беспорядок, и не очень легко вывести его из этого беспорядка.

Я использовал вызов updateValue длядать ему удар после загрузки options.Я также использовал пропеллер get-option-label вместо label, чтобы не показывать число во время загрузки данных.

Альтернативой может быть создание v-select только после того, как options станут доступны., так как он работает нормально, если они все присутствуют, когда он впервые создан.Макет v-select может быть использован в качестве заполнителя при ожидании данных.Это выглядит так:

new Vue({
  el: '#app',

  components: {
    'v-select': VueSelect.VueSelect
  },

  data: function() {
    return {
      input: {
        user_id: 2
      },
      users: []
    }
  },
  
  created () {
    setTimeout(() => {
      this.users = [
        {
          id: 1,
          name: "John",
          last: "Doe"
        },
        {
          id: 2,
          name: "Harry",
          last: "Potter"
        },
        {
          id: 3,
          name: "George",
          last: "Bush"
        }
      ]
    }, 1000)
  }
})
<link rel="stylesheet" href="https://unpkg.com/vue-select@3.1.0/dist/vue-select.css">
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<script src="https://unpkg.com/vue-select@3.1.0/dist/vue-select.js"></script>
<div id="app">
  <v-select
    v-if="users.length === 0"
    key="dummy"
    disabled
    placeholder="Loading..."
  ></v-select>
  <v-select
    v-else
    v-model="input.user_id"
    :options="users"
    :reduce="user => user.id"
    label="name"
  ></v-select>
</div>

Использование key здесь важно, поскольку оно гарантирует, что Vue не будет повторно использовать тот же v-select и вместо этого создаст новый.Есть и другие способы добиться этого, но key, вероятно, самый чистый.

...