Necesito su ayuda para completar o cargar una nueva selección con vue js, sé cómo hacer esto con jquery pero en este momento no sé cómo porque soy nuevo en esta biblioteca.

Tengo la selección principal:

<select>
   <option value='3'>FRANCE</option>
   <option value='5'>USA</option>
   <option value='6'>CANADA</option>
   <option value='8'>MOROCCO</option>
</select>

Quiero que si elijo FRANCIA obtengo una selección de ciudades de FRANCIA de la base de datos, y también cuando selecciono EE. UU. Obtengo otra selección de ciudades de EE. UU. De la base de datos.

Entonces, por ejemplo, obtendré:

<select>
   <option value='6'>CANADA</option>
   <option value='8'>MOROCCO</option>
</select>

<select>
   <option value='34'>France city one</option>
   <option value='35'>France city two</option>
</select>

<select>
   <option value='3'>Usa city one</option>
   <option value='5'>Usa city two</option>
</select>

Al elegir Francia y EE. UU., Llenaré una selección de ciudades con una matriz

Agradezco cualquier ayuda, realmente no sé cómo puedo hacer esto con vue js, no quiero agregar todas las ciudades seleccionadas en mi html porque no sé cuántos países tengo.

Intenté esto pero esto no resuelve mi problema:

const addProduct = new Vue({
el: '#addProduct',
data: {
    name: '',
    name_url: '',
    cities: '',
    countries: [],
    range: 0
},
created: function () {
    this.$http.get('/api/countries').then(response => {
        this.countries = response.data
    }, response => {

    });
},
methods: {
    addForm: function(val, data) {
        this.range += 1;
        alert(this.range)

        var index = _.findIndex(this.countries,{city_id: val});
        this.countries.splice(index, 1)
    }
},
watch: {
    'cities' (val, oldVal) {
        this.$http.post('/api/cities/values', {city_id:val}).then(response => {
            this.addForm(val, response.data);
        }, response => {

        });
    }
}

});

En html:

<div class="uk-grid" data-uk-grid-margin>
    <div class="uk-width-medium-1-4">
        <label for="attribute">Countries</label>
        <md-select name="country" id="country" v-model="country">
            <md-option v-for="country in countries" :value="country.country_id">@{{ country.name }}</md-option>
        </md-select>
    </div>
</div>


<div class="uk-grid" data-uk-grid-margin>
    <my-cities v-for="n in range"></my-cities>
</div>

<script type="x-template" id="my-cities">
    <div class="uk-width-medium-1-4">
        <label for="attr">Cities</label>
        <md-select name="attr" id="attr" v-model="attr">
            <md-option value="">Select </md-option>
            <md-option value="val in values">Select</md-option>
        </md-select>
    </div>
</script>

Un ejemplo como este en Jsfiddle: http://jsfiddle.net/pu8pp62v/3/

0
Codinga 6 abr. 2017 a las 12:05

2 respuestas

La mejor respuesta

Este es un ejemplo que quizás pueda usar (pero necesita algunas modificaciones para usar su llamada API):

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' }]
          )
        }
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.5/vue.js"></script>

<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>
0
Happyriwan 6 abr. 2017 a las 13:55

Agregado después del comentario del autor:

Compruebe este violín: http://jsfiddle.net/jjpfvx5q/1/

Dentro de la matriz 'selectedCities' tiene todas las ciudades seleccionadas por país (una ciudad por país).

Respuesta original:

Aquí hay un ejemplo para usted: fiddle

¿Es eso lo que estás tratando de lograr?

Las funciones setTimeout solo pretenden una recuperación de datos real.

<script src="//unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<template>
<div>
  <select v-model="country">
    <option disabled value="">Please select one</option>
    <option
      v-for="c in countries"
      :value="c.id">{{ c.name }}</option>
  </select>
<span>Selected: {{ country }}</span>
<span  v-if="cities.length">Cities:</span>
<ul v-if="cities.length">
<li v-for="c in cities">{{ c }}</li>  
</ul>
</div>
</template>
</div>

<script>
var Main = {
    data() {
      return {
        country: {},
        countries: [],
        cities: [],
        coInit: [{ id: '3', name: 'France' }, { id: '2', name: 'USA' }], 
        cFrance: ['Paris', 'Whatever'], 
        cUSA: ['NY', 'LA'] 
      }
    },
    methods: {
        loadCountries: function () {
        setTimeout(() => { this.countries = this.coInit }, 500);
      },
      getCities: function() { 
      if(this.country) {
        switch (this.country) {
            case '3': 
            setTimeout(() => { this.cities = this.cFrance }, 500);
            break;
          case '2': 
            setTimeout(() => { this.cities = this.cUSA }, 500);
            break;
        }
      }
      }
    },
    mounted() {
        this.loadCountries(); 
    },
    watch: {
        country: function() { 
        this.getCities();
      }
    }
  }
var Ctor = Vue.extend(Main);
new Ctor().$mount('#app');
</script>
0
Egor Stambakio 6 abr. 2017 a las 14:56