Creating a component Dynamically always deletes the last instance

I have a child and parent component. The parent component dynamically displays the child component, i.e. On demand, and saves the record in an array. When a child component requires removal, it throws an event and, therefore, passes its identifier, which will be identified in the record. Although the record is deleted based on id, the last instance created is always deleted. Even if you press the first child, he will only delete the last one.

There is a link here that is identical to my situation, but only in a simple way. I researched SO and found this answer whose violin is here . Thus, I executed its template in another fiddle , but the result is no different.

I don’t know what the problem is here ... what am I doing wrong?

Update 1: Code Added

Update 2: check the first link if you want to skip below

ChatPanel.vue

  <template> <div class="chat-container"> <div class="columns" style="justify-content: flex-end;"> <div class="column is-3" style="order: 1;"> <div class="chat-panel"> <nav class="panel state" :class="[statusIn ? 'in' : 'out']"> <p class="panel-heading"> Arbab Nazar <span id="click-handle" @click="toggleState"></span> </p> <div class="panel-block"> <p class="control has-icons-left"> <input class="input is-small" type="text" placeholder="search"> <span class="icon is-small is-left"> <i class="fa fa-search"></i> </span> </p> </div> <p class="panel-tabs"> <a class="is-active">all</a> <a>Online</a> <a>Sleeping</a> </p> <chat-list/> </nav> </div> </div> <chat-window v-for="(window, index) in windows" :identity="index" v-on:remove-window="removeWindow(window)" /> </div> </div> </template> <script> import ChatList from './ChatList' import ChatWindow from './ChatWindow' import Bus from '../Events/Bus.js' export default { name: 'chatpanel', data () { return { statusIn: true, windows: [], id: Number } }, mounted() { Bus.$on('new-window', (data)=> { this.windows.push((this.windows.length+1)) }) }, methods: { toggleState(event) { event.stopPropagation() this.statusIn = !this.statusIn }, removeWindow(window) { this.windows.splice(this.windows.indexOf(window),1) } }, components: { ChatList, ChatWindow } } </script> 

ChatWindow.vue

 <template> <div class="column is-2"> <div class="chat-window-container" :class="{'reset': statusIn}"> <div class="card state" :class="[statusIn ? 'in' : 'out']"> <header class="card-header"> Ahmad Jan <a class="delete" @click="$emit('remove-window')"></a> <span id="click-handle" @click="toggleState"></span> </header> <div class="card-content"> <template v-for="message in messages"> <p> {{ message }} </p> </template> </div> </div> <div class="field has-addons"> <div class="control is-expanded"> <input class="input" type="text" placeholder="Write something amazing..." @keyup.enter="sendMessage" v-model="messageText" > </div> <div class="control"> <a class="button is-primary" @click="sendMessage" style="background:rgb(0, 184, 255)" > Send </a> </div> </div> </div> </div> </template> <script> import Bus from '../Events/Bus.js' export default { props:['identity'], data() { return { messageText: '', messages: [], statusIn: true, id: '' } }, created() { this.id = this.identity }, methods: { sendMessage(event) { this.messages.push(this.messageText) this.messageText = '' console.log('msg', event.target.value) // this.messages }, toggleState(event) { event.stopPropagation() this.statusIn = !this.statusIn }, removeWindow(id) { console.log(`remove window with id ${id}`) Bus.$emit('remove-window', {id}) } } } </script> 

ChatList.vue

 <template> <div style="overflow-y: scroll;max-height: 17.5rem;"> <template v-for="chat in chats"> <chatter :user="chat"></chatter> </template> </div> </template> <script> import Chatter from './Chatter' export default { props:{}, data () { return { chats: [ { name: 'Abdul Hameed', active: true }, { name: 'Ahmad Jan', active: false }, { name: 'Murad Surkhab', active: false }, { name: 'Angelo Mathews', active: false }, { name: 'Hasan Ali', active: true }, { name: 'Fakhar-ud-Din', active: true }, { name: 'Sultan Usman', active: true }, { name: 'Muad Saeed', active: false }, { name: 'Saleem Yousaf', active: false }] } }, components: { Chatter } } </script> 

Chatter.vue

 <template> <div> <a class="panel-block" :class="{'is-active':user.active }" @click="letsCaht"> <div style="display: flex;"> <p class="image is-24x24 chat-image" > <img src="http://bulma.io/images/placeholders/96x96.png"> </p> <p class="content"> {{user.name}} </p> </div> <span class="panel-icon"> <i class="fa fa-comments"></i> </span> </a> </div> </template> <script> import Bus from '../Events/Bus.js' export default { props:['user'], methods: { letsCaht(event) { Bus.$emit('new-window', {user: this.user}) console.log(`${this.user.name} is listening`) } }, components: {} } </script> 
+1
source share
1 answer

I think your deletion works in the first fiddle, but you do not see it correctly because your list gets shorter if you delete one item. Therefore, it seems that the last element is always deleted.

Also adding id to your object helps Vue display v-for , and you can add key binding to id.

Please view the demo below or fiddle .

In the application code that you posted in your question:

Is your delete handler called? You radiate on the bus, but your listener is attached to it. Look at the fiddle to see the difference.

 Vue.component('child', { props:['index', 'data'], template: ` <div> data# {{data}} <button @click="$emit('delete-me')">Delete</button> </div>` }) Vue.component('parent', { template: ` <div> Keep Adding new Instances <button @click="newChild">New</button> <hr /> <child v-for="(row, index) in children" :data="row" v-on:delete-me="deleteThisRow(index)" :key="row.id" :index="index" ></child> </div>`, data() { return { id: 0, children:[] } }, methods: { newChild() { this.children.push({ id: this.id++, value: 'new child' }) }, deleteThisRow(index) { // console.log('index', index, this.children) this.children.splice(index, 1); } } }) new Vue({ el: '#app', template: ` <div> <parent /> </div> `, methods: { } }) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script> <div id="app"></div> 
+2
source

Source: https://habr.com/ru/post/1011562/


All Articles