Laravel 5.7, Актуализирайте ‹опции› в падащо меню за избор с Vue

Пиша първия си компонент Laravel Vue и имам тази грешка в конзолата.

[Vue предупреждение]: Изчисленото свойство „опции“ беше присвоено на, но няма настройка.

Кодът е около две падащи менюта за избор, едно с континенти и едно с държави. Искам, когато актуализирам континента, държавите да се актуализират.

Просто пропускам да актуализирам опциите на втория избор с актуализираните стойности, които имам в this.countries.

След промяната на континента променливата this.countries се актуализира, но стойностите на опциите на избрания country_id не се променят. Опитах да добавя computed, но получавам тази грешка.

какво правя грешно

<template>
    <div>
        <div class="form-group continent_id">    
            <select name="continent_id" v-model="continent_selected" id="continent_id" class="selectpicker" data-live-search="false" title="Pick a continent" v-on:change="getAllCountries(continents)">
                <option v-if="continents.length>0" v-for="continent in continents" v-bind:value="continent.id">
                    {{ continent.name }}
                </option>
            </select>
        </div>

        <div class="form-group country_id">    
            <select name="country_id" v-model="country_selected" id="country_id" class="selectpicker" data-live-search="true" title="Pick a country">
                <option  v-for="(country, index) in countries" v-bind:value="country.id" >
                    {{ country.name }}
                </option>
            </select>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.');
            this.loadData();
        },
        data() {
            return {
                continents: [],
                countries: [],
                continent_selected: '',
                country_selected: '',
            }
       },
       computed: {
           get: function () {
               return this.countries;
           },
           set: function (newValue) {
               this.countries = newValue; 
           }
       },
       methods: {
            loadData: function() {
                axios.get('/api/continents')
                .then((response) => {
                    // handle success
                    this.continents = response.data.data;
                    this.getAllCountries(this.continents);
                })
                .catch((error) => {
                    // handle error
                    console.log(error);
                })
                .then(() => {
                    // always executed
                });
            },
            getAllCountries: function(continents) {
                console.log(this.continent_selected);
                console.log(continents);

                var j = 0;
                this.countries = [];

                for (var i = 0, len = continents.length; i < len; i++) {
                    if (!this.continent_selected){
                        for (var key in continents[i].active_countries) {
                            this.countries[j] = {id: continents[i].active_countries[key], name: key};
                            j++;
                        }
                    }
                    else{
                        console.log("continent selected: "+ this.continent_selected);
                        for (var key in continents[i].active_countries) {
                            if (continents[i].id == this.continent_selected){
                                this.countries[j] = {id: continents[i].active_countries[key], name: key};
                                j++;
                            }
                        }

                    }
                }
            }
        },
    }
</script>

person Davide Casiraghi    schedule 26.02.2019    source източник


Отговори (2)


В този ред задавате стойността на атрибута options:

this.options = this.options;

, но това свойство се изчислява:

computed: {
    options: function(event) {
        return this.countries
    }
},

В този случай можете:

1) създайте изчислен сетер: https://vuejs.org/v2/guide/computed.html#Computed-Setter

computed: {
    options: {
        get: function () {
            return this.countries;
        },
        set: function (newValue) {
            this.countries = newValue; 
        }
    }     
},

2) Задайте стойността директно:

this.countries = this.options;
person lmarqs    schedule 26.02.2019
comment
Опитах и ​​двете, грешката изчезна, но при единия работи.. Второто падащо меню все още не се актуализира. - person Davide Casiraghi; 26.02.2019
comment
Гласувам за вашия въпрос, защото той допринася за отлепването на моя проблем, като ме кара да намеря решението. Благодаря ви за отделеното време за въпроса ми! - person Davide Casiraghi; 01.03.2019

Реших проблема си, който беше свързан главно с метода на изчислен набор на променливата optionCountries.

Падащото меню не се актуализира, защото използва Bootsrap Select, така че, за да покаже новите опции, трябва да бъде опреснено.

Разбрах също, че трябва да добавя време за изчакване към заявката за опресняване.

Това е окончателният код.

<template>
    <div>
        <div class="form-group continent_id">    
            <select name="continent_id" v-model="continent_selected" id="continent_id" class="selectpicker" data-live-search="false" title="Pick a continent" v-on:change="getAllCountries(continents)">
                <option v-if="continents.length>0" v-for="continent in continents" v-bind:value="continent.id">
                    {{ continent.name }}
                </option>
            </select>
        </div>

        <div class="form-group country_id">    
            <select name="country_id" v-model="country_selected" id="country_id" class="selectpicker" data-live-search="true" title="Pick a country">
                <option  v-for="(country, index) in optionCountries" v-bind:value="country.id" >
                    {{ country.name }}
                </option>  
            </select>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.');
            this.loadData();
        },
        data() {
            return {
                continents: [],  
                countries: [],
                continent_selected: '',
                country_selected: '',
            }
       },
       computed: {
           optionCountries:{   
               get: function () {
                    return this.countries;
                },
                set: function (newValue) {
                    this.countries = newValue;
                    setTimeout(() => {
                       jQuery('.selectpicker').selectpicker('refresh');
                    }, 500);
                }
            } 
        },

       methods: {
            loadData: function() {  
                axios.get('/api/continents')
                .then((response) => {
                    // handle success
                    this.continents = response.data.data;
                    this.getAllCountries(this.continents);
                })
                .catch((error) => {
                    // handle error
                    console.log(error);
                })
                .then(() => {
                    // always executed
                });
            },
            getAllCountries: function(continents) {                
                var j = 0;
                this.countries = [];

                for (var i = 0, len = continents.length; i < len; i++) {
                    if (!this.continent_selected){
                        for (var key in continents[i].active_countries) {
                            this.countries[j] = {id: continents[i].active_countries[key], name: key};
                            j++;
                        }
                    }
                    else{
                        for (var key in continents[i].active_countries) {
                            if (continents[i].id == this.continent_selected){
                                this.countries[j] = {id: continents[i].active_countries[key], name: key};
                                j++;
                            }
                        }
                        this.optionCountries = this.countries;
                    }
                }
            }
        },
    }
</script>
person Davide Casiraghi    schedule 27.02.2019