当选择另一个时,Vue js保持下拉值

时间:2017-04-06 16:39:11

标签: javascript vuejs2

您好我有一个下拉列表(选择国家/地区),我希望当我选择一个国家/地区时,我会在新的下拉列表中显示此国家/地区的城市(现在下拉总数:2)当我选择第二个国家/地区时,我想要获得这个国家的城市其他下降,所以我现在将有3个下拉总数。 我的问题在于,当我选择一个国家并选择一个城市时,我的选择会在选择其他国家后消失。 我该如何解决这个问题? 我在国家/地区下拉列表中使用了多选,并在城市下拉菜单中进行了简单选择

new Vue({
  el: "#app",
  data: function() {
    return {
        selectedCountries: [],
        selectOptionsCountries: [
        { value: 3, name: 'FRANCE' },
        { value: 5, name: 'USA' },
        { value: 6, name: 'CANADA' },
        { value: 8, name: 'MOROCCO' }
      ],
      selectedCities: [],
      selectOptionsCities: []
    }
  },
  methods: {

  },
  watch: {
    selectedCountries: function(newValue, oldValue) {
      this.selectOptionsCities = [];
      this.selectedCities = [];

      for( var i = 0, length = newValue.length; i < length; i++ ){

        this.selectedCities[i] = [];

        if( newValue[i] === 3 ){
          this.selectOptionsCities.push(
            [{ value: 31, name: 'Paris' },
            { value: 32, name: 'Marseille' }]
          )
        }
        if( newValue[i] === 5 ){
          this.selectOptionsCities.push(
            [{ value: 51, name: 'New-York' },
            { value: 52, name: 'Boston' }]
          )
        }
        if( newValue[i] === 6 ){
          this.selectOptionsCities.push(
            [{ value: 61, name: 'Montreal' },
            { value: 62, name: 'Vancouver' },
            { value: 63, name: 'Ottawa' },
            { value: 64, name: 'Toronto' }]
          )
        }
        if( newValue[i] === 8 ){
          this.selectOptionsCities.push(
            [{ value: 81, name: 'Rabat' },
            { value: 82, name: 'Casablanca' },
            { value: 83, name: 'Fes' }]
          )
        }
      }
    }
  }
});    
<div id="app">

  Selected countries : {{ selectedCountries }}
  <br />
  Selected cities : {{ selectedCities }}
  <br />
  <select v-model="selectedCountries" multiple>
     <option v-for="(option, index) in selectOptionsCountries" :value='option.value'>
       {{ option.name }}
     </option>
  </select>

  <select v-for="(optionsCities, index) in selectOptionsCities" v-model="selectedCities[index]" multiple>
    <option v-for="(option, index) in optionsCities" :value='option.value'>
       {{ option.name }}
     </option>
  </select>
</div>

2 个答案:

答案 0 :(得分:1)

Vue通常应该是数据驱动的。在这种程度上,我已修改您的代码以实现您的结果。这是新的数据结构。

const countries = [
  { 
    value: 3, 
    name: 'FRANCE', 
    cities: [
      { value: 31, name: 'Paris' },
      { value: 32, name: 'Marseille' }
    ], 
    selectedCities: [] },
  { 
    value: 5, 
    name: 'USA', 
    cities: [
      { value: 51, name: 'New-York' },
      { value: 52, name: 'Boston' }
    ], 
    selectedCities: []},
  { 
    value: 6, 
    name: 'CANADA', 
    cities: [
      { value: 61, name: 'Montreal' },
      { value: 62, name: 'Vancouver' },
      { value: 63, name: 'Ottawa' },
      { value: 64, name: 'Toronto' }
    ], 
    selectedCities: [] 
  },
  { 
    value: 8, 
    name: 'MOROCCO', 
    cities:[
      { value: 81, name: 'Rabat' },
      { value: 82, name: 'Casablanca' },
      { value: 83, name: 'Fes' }
    ], 
    selectedCities: [] 
  }
]

代码

new Vue({
  el: "#app",
  data: function() {
    return {
      countries,
      selectedCountries: []
    }
  }, 
  computed:{
    originalSelectedCountry(){
      return this.selectedCountries.map(country => country.value) 
    },
    originalSelectedCities(){
      return this.selectedCountries.reduce((acc, country) => {
        acc.push(country.selectedCities.map(city => city.value))
        return acc
      },[])
    }
  }
}); 

这是模板

<div id="app">
  Selected countries : {{ originalSelectedCountry }}
  <br />
  Selected cities : {{ originalSelectedCities }}
  <br />
  <select v-model="selectedCountries" multiple >
     <option v-for="country in countries" :value='country' :key="country.value">
       {{ country.name }}
     </option>
  </select>
  <select v-for="country in selectedCountries" v-model="country.selectedCities"  :key="country.value" multiple>
    <option v-for="city in country.cities" :value="city">{{city.name}}</option>
  </select>
</div>

这是工作example

以下是重点。

  • 我将与每个国家/地区相关联的城市移动到该国家/地区的数据中。这样,自然地建立选择流程,您不必观看所选国家。
  • 由于您有多组选定城市,因此尝试将一个模型用于所有集合没有多大意义。我为每个国家/地区添加了selectedCities属性。
  • 我将您的前selectedCountriesselectedCities转换为计算值。这些值只能从当前selectedCountries派生,因为selectedCities是每个国家/地区的属性。在我看来,selectedCities(我变成originalSelectedCities)是一个相当无用的数据结构。如果城市的顺序发生变化会怎样?现在您不知道二维数组与哪些国家/地区相关联。

答案 1 :(得分:0)

看起来您的选择框模型正在执行您要求的模型,并在您将selectedCities设置为空数组时清除。

如果稍微更改数据结构,则可以简化代码。试试这个,请参阅JSFiddle

<div id="app" class="container">
  <div class="row">
    <div class="col-xs-12">
      Selected countries : {{ selectedCountries }}
      <br />
      Selected cities : {{ selectedCities }}
      <br />
      <hr/>
      <select v-model="selectedCountries" 
         multiple class="form-control">>
        <option v-for="(option, index) in selectOptionsCountries" 
          :value='option.value'>
          {{ option.name }}
        </option>
      </select>
      <select v-model="selectedCities" multiple class="form-control">
        <!-- inline object literal -->
        <option v-bind:value="city.value" 
           v-for="(city, index) in selectOptionsCities"
           v-show="selectedCountries.indexOf(city.parent) > -1">
          {{ city.name }}
        </option>
      </select>
    </div>
  </div>
</div>

这是JavaScript。

new Vue({
  el: "#app",
  data: function() {
    return {
      selectedCountries: [],
      selectOptionsCountries: [
        { value: 3, name: 'FRANCE' },
        { value: 5, name: 'USA' },
        { value: 6, name: 'CANADA' },
        { value: 8, name: 'MOROCCO' }
      ],
      selectedCities: [],
      selectOptionsCities: [
        { value: 31, name: 'Paris', parent:3 },
        { value: 32, name: 'Marseille', parent:3 },
        { value: 51, name: 'New-York', parent:5 },
        { value: 52, name: 'Boston', parent:5 },
        { value: 61, name: 'Montreal', parent:5 },
        { value: 62, name: 'Vancouver', parent:6 },
        { value: 63, name: 'Ottawa', parent:6 },
        { value: 64, name: 'Toronto', parent:6 },
        { value: 81, name: 'Rabat', parent: 8 },
        { value: 82, name: 'Casablanca', parent: 8 },
        { value: 83, name: 'Fes', parent: 8 }
      ]
    }
  }
});