简体   繁体   中英

Watching dynamic nested data in Vue.JS?

I have a series of checkboxes setup in Vue.js components that are emitting data to my parent element. I want to watch this data for changes and append the data within the object to an API call, in order to filter data.

Here's what my data on the parent element looks like when some items are checked (otherwise it's just an empty object if nothing's checked):

selectedFeatures对象的图像

I want to be able to insert this data into an API call that would (in general) look like this, when the data changes:

this.axios.get('http://localhost:8000/api/v1/schools' + 
    for (feature in selectedFeatures) {
        '?features[]=' + feature
    }
).then((response) => {
    this.$root.$emit('searchQuery', response.data);
});

Usually this is pretty easy with the Watch feature of Vue, but since my data is nested in unnamed arrays and generated dynamically, I'm not sure how to do this.

Fixed by adding the following to Filters.vue's tags:

methods: {
    addFeatures() {
        var featureNames = '';
        // Loop through selectedFeatures and return a string of all features
        for (var key in this.selectedFeatures) {
           var obj = this.selectedFeatures[key];
           for (var prop in obj) {
               // Remove spaces and add + sign
               featureNames += '&features[]=' + obj[prop].split(' ').join('+');
           }
        };
        return 'http://localhost:8000/api/v1/schools?' + this.selectedGrade + '=1' + featureNames;
    }
},
mounted() {
    // When checkUpdated is emited, run new API call
    this.$root.$on('checkUpdated', function() {
        var gradeFeatures = this.addFeatures();
        // Dump string from addFeatures into end of API and send it to the root to filter out data
        this.axios.get( gradeFeatures ).then((response) => {
            this.$root.$emit('searchQuery', response.data);
        });
    }.bind(this));
}

I then changed the Checkbox.vue slightly by replacing:

<input type="checkbox" :disabled="disabled" :name="name" v-model="newValue" @change="$emit('change', newValue, $event)">

to:

<input type="checkbox" :disabled="disabled" :name="name" v-model="newValue" @change="valueChanged">

and added:

methods: {
    valueChanged() {
        this.$root.$emit('checkUpdated');
        this.$emit('change', this.newValue, this.$event);
    }
}

Which the mounted lifecycle can catch on the Filters.vue file to fire the method.

Works great!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM