Colleagues, I am new to vue, tell me please, such a problem.
I use laravel + vue stack.
I have two components. The first is the table, the second is the form for adding a new element (modal window of the bootstrap wrapped in the vue component).
On the form there is a list of multiple choice. Through props I pass all the options for the list from the parent component (table) and I want, when I open the form, all the elements of the list are selected.
I do all the documentation. In order not to change the parent's value from the child component, I create a local value in the child component through data . But at the time of use, this local value is always empty!
Calling a child component (add form):
<table class="table"> <thead> <tr> <th scope="col">#</th> <th scope="col">id приложения</th> <th scope="col">Наименование</th> <th scope="col">Описание</th> <th scope="col">Картинка</th> <th scope="col">URL</th> <th scope="col"></th> </tr> </thead> <tbody> <tr v-for="sportSite in sportSites"> <th scope="row">{{ sportSite.id }}</th> <td> <template v-for="application in sportSite.applications"> id {{ application.id }} => {{ application.name }} <br> </template> </td> <td>{{ sportSite.name }}</td> <td>{{ sportSite.description }}</td> <td> <img style="width: 100px; height: 100px;" :src="sportSite.image" > </td> <td> <a :href="sportSite.url" target="_blank">{{ sportSite.url }}</a> </td> <td> </td> </tr> </tbody> </table> </div> </template> <script> import { EventBus } from '../../app'; export default { name: "SportSitesTable", created() { }, mounted(){ this.loadTable(); this.getApplications(); }, methods:{ loadTable: function () { window.axios.get('/sport_sites_all') .then(resp => { this.sportSites = resp.data.data; }).catch(err => { console.error("Ошибка загрузки данных с сервера!"); console.error(err); }); }, getApplications: function () { window.axios.get('/applications/all') .then(resp => { this.applicationsAll = resp.data.applications.data; this.$forceUpdate(); }).catch(err => { console.error('Ошибка получения списка приложений!'); console.error(err); }); } }, data(){ return { sportSites: [], applicationsAll: [], } }, } </script>The implementation of the child component (where multiple select):
<template> <div> <button type="button" class="btn btn-primary my-2" data-toggle="modal" data-target="#sportSiteAdd"> Добавить </button> <div class="modal fade" id="sportSiteAdd" tabindex="-1" role="dialog" aria-labelledby="sportSiteAddLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="sportSiteAddLabel">Добавить спортивный сайт</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <ul class="alert-danger"> <li v-for="error in errors"> {{ error[0] }} </li> </ul> <form> <div class="form-group"> <label for="name">Заголовок</label> <input type="text" class="form-control" id="name" name="name" v-model="formFields.name"> </div> <div class="form-group"> <label for="image">Картинка</label> <input type="text" class="form-control" id="image" name="image" v-model="formFields.image"> </div> <div class="form-group"> <label for="url">URL</label> <input type="text" class="form-control" id="url" name="url" v-model="formFields.url"> </div> <div class="form-group"> <label for="description">Описание</label> <textarea class="form-control" id="description" name="description" v-model="formFields.description"></textarea> </div> <div> <label class="typo__label">Связанные приложения</label> <multiselect v-model="applications" tag-placeholder="Связанные приложения" placeholder="Поиск" label="name" track-by="id" :options="allApplications" :multiple="true" :taggable="true"> </multiselect> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Закрыть</button> <button type="button" class="btn btn-primary" v-on:click="submit">Сохранить</button> </div> </div> </div> </div> </div> </template> <script> import { EventBus } from '../../app'; import Multiselect from 'vue-multiselect' export default { name: "SportSitesAdd", props: ['allApplications'], mounted: function(){ }, methods:{ submit: function (e) { window.axios.post('/sport_site/add/', this.formFields) .then(res => { console.log('Saved!'); $('#sportSiteAdd').modal('hide'); this.formFields.name = ''; this.formFields.image = ''; this.formFields.url = ''; this.formFields.description = ''; EventBus.$emit('reloadApplicationsTable'); }).catch(err => { if(err.response.status === 422){ this.errors = err.response.data.errors || []; } console.error('Ошибка сохранения!'); }); }, }, data(){ return { formFields: { name: '', image: '', url: '', description: '', }, applications: this.allApplications, errors: [], } }, components: { Multiselect }, } </script>
At the same time, if I specify the allApplications property as options and values in the list, then everything works.
But you know, this is no good.
First, vue warns that I am changing the value in the parent from the child, and second, when removing an item from the list, it is removed from the parent. And the list is so slowly "emptying"))
If you delete everything, then there will be nothing to choose later, since the elements will not remain in the parent component.
Here is the result that I would like to see, that is, you open it - and everything is selected:
