动态创建组件总是删除最后一个实例

2023-12-06

我有一个child组件和parent成分。父组件动态渲染子组件,即按需渲染,并将记录保存在数组中。当子组件需要被删除时,它会发出事件,并因此传递其 id 以在记录中进行识别。尽管记录确实会根据 id 被删除,但最后创建的实例始终会被删除。即使您单击第一个子项,它也只会删除最后一个。

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

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

更新1:添加代码

更新 2:如果您想跳过下面的内容,请检查第一个链接

聊天面板.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>

聊天窗口.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>

聊天列表.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>

我认为您的删除在第一个小提琴中起作用,但您没有正确地看到它,因为如果您删除一个项目,您的列表会变得更短。所以似乎总是最后一项被删除。

还添加一个id到你的对象可以帮助Vue渲染v-for并且您可以将键绑定添加到 id。

请看看下面的演示或这个fiddle.

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

您的删除处理程序被调用了吗?您正在总线上发射,但您的侦听器已连接到此。请看一下这个fiddle所以你看到了差异。

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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态创建组件总是删除最后一个实例 的相关文章

随机推荐