Vue.js笔记应用删除功能求助:点击按钮获取邻接元素HTML值
Hey there! Let's figure out a better way to implement the delete functionality for your Vue note app. The approach you're using right now relies on digging into the DOM to find the card title, which isn't very "Vue-like"—Vue is all about data-driven development, so we can make this cleaner and more efficient by working with the data directly instead of DOM elements.
First, let's look at the issues in your current code:
- You're using jQuery to grab input values (
$("#title").val()) instead of using Vue'sv-modelto bind form data to your component's state. This breaks Vue's reactive data flow. - In your
removemethod,$(this)doesn't refer to the clicked delete link (sincethisin Vue methods is the component instance), so your DOM traversal won't work as expected. - Using
location.reload()after every add/clear/remove is a poor user experience—we can update the UI reactively without reloading the page.
Here's a refined approach that leverages Vue's strengths:
Step 1: Bind Form Data with v-model
Instead of using jQuery to get input values, bind the title and body inputs to properties in your Vue data. This keeps everything reactive.
Step 2: Pass the Note Key Directly to the Remove Method
In your v-for, you can access both the key (note title) and value (note body) directly. Pass the key to the remove method when clicking delete—no need to hunt for it in the DOM.
Step 3: Update Data and localStorage Without Reloading
When deleting a note, remove it from both localStorage and your notes object. Vue will automatically update the UI for you.
Updated HTML:
<div id="notes"> <div class="container"> <div class="form-group"> <label for="title">Enter title</label> <!-- Use v-model to bind input to Vue data --> <input class="form-control" id="title" v-model="newNoteTitle"/> </div> <div class="form-group"> <label for="body">Enter body</label> <!-- Use v-model for textarea too --> <textarea class="form-control" id="body" v-model="newNoteBody"></textarea> </div> <div class="form-group"> <button class="btn btn-primary" @click="add">Add</button> <button class="btn btn-danger" @click="clear">Delete all</button> </div> <!-- Correct v-for syntax: (value, key) in notes --> <div class="card" v-for="(noteData, noteTitle) in notes" :key="noteTitle"> <div class="card-body"> <h5 class="card-title">{{ noteTitle }}</h5> <p class="card-text">{{ noteData[0] }}</p> <!-- Pass the noteTitle directly to remove --> <a class="card-link" @click="remove(noteTitle)">Delete</a> </div> </div> </div> </div>
Updated Vue Code:
new Vue({ el: "#notes", data: { notes: {}, newNoteTitle: '', // New property for title input newNoteBody: '' // New property for body input }, methods: { add: function() { // Only add if title isn't empty if (this.newNoteTitle.trim()) { localStorage.setItem(this.newNoteTitle, this.newNoteBody); // Update notes data directly instead of reloading this.notes[this.newNoteTitle] = [this.newNoteBody, "red"]; // Clear form inputs this.newNoteTitle = ''; this.newNoteBody = ''; } }, clear: function() { localStorage.clear(); // Empty the notes object to update UI this.notes = {}; }, remove: function(noteTitle) { // Delete from localStorage localStorage.removeItem(noteTitle); // Delete from notes object (Vue will update the UI) delete this.notes[noteTitle]; } }, created: function() { // Simplify localStorage traversal for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); this.notes[key] = [localStorage.getItem(key), "red"]; } } });
Let's break down the key improvements:
- Reactive Form Binding:
v-modellinks the input fields tonewNoteTitleandnewNoteBody, so we don't need jQuery to fetch values. - Direct Key Passing: The
v-forgives usnoteTitledirectly, so we can pass it toremove()—no DOM traversal needed. This is much more reliable. - No Page Reloads: Instead of
location.reload(), we update thenotesobject directly. Vue's reactivity system will automatically re-render the list of notes. - Cleaner Code: We've removed unnecessary DOM manipulation, making the code easier to read and maintain.
This approach aligns with Vue's data-driven philosophy, provides a smoother user experience (no reloads), and is more maintainable than your original DOM-based method.
内容的提问来源于stack exchange,提问作者user8690818

