2017-08-13 130 views
1

我有一个child组件和parent组件。父组件动态地(即按需)呈现子组件,并将记录保存在数组中。当一个子组件需要被移除时,它发出事件并因此传递其ID以便在记录中被识别。尽管记录基于id被删除,但最后创建的实例始终被删除。即使您点击第一个孩子,也只会删除最后一个孩子。动态创建组件总是删除最后一个实例

Here是与我的情况相同的链接,但只是以简单的形式。 我在SO上做过研究,发现这个answer的小提琴是here。所以我确实在另一个​​中遵循了它的模式,但结果没有什么不同。

我不知道这里有什么问题......我做错了什么?

更新1:添加的代码

更新2:检查第一个链接,如果你想跳过下面

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> 
+0

怎么样一些代码? –

+0

@EliranMalka代码非常复杂,所以我添加了一个类似于我的问题的链接,但它的格式很简单。这里是链接https://jsfiddle.net/Lahori/v0z02cna/ – Lahori

+0

这实际上是问题的一部分。如果您提供导致问题的最简单,简明的代码片段,那么您将缩小到有问题的代码(无论如何,您应该这样做) –

回答

2

我想你删除在第一小提琴工作,但你没有正确地看到它,因为你的清单越来越短,如果你正在删除一个项目。所以看起来总是最后一个项目被删除。

同时向对象添加id有助于Vue呈现v-for,并且您可以将键绑定添加到ID。

请看看下面的演示或此fiddle

在,你在你的问题发布您的应用程序代码:

就是所谓的删除处理?你在公共汽车上发射,但是你的听众会被附在这个上面。请看fiddle,这样你就会看到差异。

Vue.component('child', { 
 
\t \t 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() { 
 
     \t return { 
 
      id: 0, 
 
      \t children:[] 
 
      } 
 
    }, 
 
    methods: { 
 
    \t newChild() { 
 
     \t this.children.push({ 
 
     \t id: this.id++, 
 
     \t value: 'new child' 
 
     }) 
 
     }, 
 
     deleteThisRow(index) { 
 
     \t \t \t // console.log('index', index, this.children) 
 
      this.children.splice(index, 1); 
 
     } 
 
    } 
 
}) 
 

 
new Vue({ 
 
    el: '#app', 
 
    template: ` 
 
     <div> 
 
     \t \t <parent /> 
 
      
 
     </div> 
 
    `, 
 
    
 
    methods: { 
 
     
 
    } 
 
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script> 
 
<div id="app"></div>

+0

谢谢@AWolf今天早上我注意到了,你说得对,我没有看清楚。实际上问题不在于各个窗口没有关闭,问题是当一个实例关闭时,它会将其数据传递给下一个同级,这在视觉上导致我相信窗口/实例未被关闭。 – Lahori

+0

看看这里https://jsfiddle.net/Lahori/v0z02cna/3/。创建2/3实例,然后在第一个实例中发送消息,然后将其删除。该实例被删除,但数据被传递给下一个兄弟。 – Lahori

相关问题