Vue 3中如何正确使用this关键字实现点击删除动态创建的div
问题原因
- Vue 模板中
@click绑定的回调里的this指向当前组件实例,不是点击的DOM元素,所以你传递的参数根本不是目标节点 - 你在
addStatus方法中手动拼接HTML绑定的onclick会从全局作用域查找closeStatus方法,而该方法是组件内部方法,全局不存在,自然调用失败 - 直接手动操作DOM不符合Vue数据驱动的设计思路,后续容易出现状态和视图不一致的问题,维护成本很高
推荐实现方案(符合Vue开发规范)
用响应式数组存储所有通知数据,通过v-for渲染列表,完全不需要手动操作DOM:
<template> <div> <button @click="addStatus">Add Status</button> <div id="slide" class="slide-modal" v-show="visible"> <div class="clear-notifications" @click="clearAllNotifications">Clear all notifications</div> <div class="status-div" v-for="(item, index) in notifications" :key="index"> <div>{{ item }}</div> <div @click="closeStatus(index)"> <img src="../assets/cross.svg" alt="关闭" /> </div> </div> </div> </div> </template> <script lang="ts"> export default { name: 'SlideModal', data() { return { // 响应式通知列表,初始值放你默认的两条通知 notifications: Array<string>(['11:00 Booking requested', '11:30 Booking requested']), // 控制弹窗显隐的响应式变量 visible: true } }, methods: { clearAllNotifications() { this.notifications = [] this.visible = false }, addStatus() { this.visible = true this.notifications.push('Another Message') }, closeStatus(index: number) { this.notifications.splice(index, 1) if (this.notifications.length === 0) { this.visible = false } } } } </script>
实现逻辑说明
- 所有通知内容存储在响应式数组
notifications中,数组内容变更时视图会自动更新 - 点击关闭按钮时传入对应通知的数组索引,直接删除数组中对应位置的项,对应的DOM会被Vue自动销毁
- 弹窗显隐通过
v-show绑定响应式变量控制,不需要手动操作DOM修改样式
如果你非要保留原有DOM操作写法(非常不推荐)
可以按以下方式修改解决调用失败的问题:
- 模板中的
@click="closeStatus(this)"修改为@click="closeStatus($event.currentTarget)",$event.currentTarget才是你绑定点击事件的DOM元素 addStatus方法中不要在innerHTML里写onclick,改为手动绑定组件内的方法:
addStatus() { document.getElementById('slide').style.visibility='visible'; const statusMessage = "Another Message" const div = document.createElement('div'); div.setAttribute('class', 'status-div'); // 先加文本节点 const textDiv = document.createElement('div') textDiv.innerText = statusMessage div.appendChild(textDiv) // 创建关闭按钮,手动绑定事件 const closeBtn = document.createElement('div') closeBtn.innerHTML = '<img src="/src/assets/cross.svg" />' closeBtn.addEventListener('click', () => this.closeStatus(closeBtn)) div.appendChild(closeBtn) document.getElementById('slide').appendChild(div); }
内容的提问来源于stack exchange,提问作者user581733
相关产品推荐
相关产品推荐

