You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js笔记组件修改编辑状态函数失效问题求助

问题:Vue3笔记组件编辑按钮点击后视图不更新

我正在开发一款简易笔记应用,当前处理NoteItem组件时遇到问题:组件的删除按钮功能正常,但点击编辑按钮调用startRedacting()后,redacting变量修改后视图没有变化,导致v-else区块无法渲染。

原组件代码

<script setup lang="ts">
import axios from "axios";
const props = defineProps(['title', 'content', 'note_id']);

let redacting = undefined;

let redTitle = props.title;
let redContent = props.content;

const deleteNote = async () => {
  await axios.delete(`http://localhost:3000/notes/${props.note_id}`)
      .then((res) => {
        if (res.status === 204) {
          location.reload()
        }
        else {
          console.log(`HTTP STATUS ${res.status}`)
        }
      })
}

const startRedacting = () => {
  redacting = true
}

const redactNote = async () => {
  await axios.put(`http://localhost:3000/notes/${props.note_id}`, {
    Title: redTitle,
    Content: redContent
  })
      .then((res) => {
        if (res.status === 200) {
          redacting = false
          location.reload()
        }
        else {
          console.log(`HTTP STATUS ${res.status}`)
        }
      })
}
</script>

<template>
<div class="flex flex-row justify-between border-2 border-r-6 border-gray-200 p-3 rounded-md">
  <div class="flex w-2.5 h-full bg-red-500 rounded-3xl resize-none flex-none" id="strip">
    <!--Poloska-->
  </div>
  <div v-if="!redacting" class="flex flex-col ml-8 text-wrap justify-self-start justify-start">
    <div id="title" class="text-xl justify-self-center text-left">
      {{ title }}
    </div>
    <div id="content" class="pt-4 text-pretty h-max truncate justify-self-start text-left">
      {{ content }}
    </div>
  </div>
  <div v-else>
    <div class="flex flex-col ml-8 text-wrap justify-self-start justify-start pr-2">
      <div class="text-xl justify-self-center text-left">
        <input type="text" v-model="redTitle" class="border-2 border-gray-200 rounded-md p-2 w-full">
      </div>
      <div id="content" class="pt-4 text-pretty h-max truncate justify-self-start text-left">
        <textarea v-model="redContent" class=" border-2 border-gray-200 rounded-md p-2 w-full"></textarea>
      </div>
      <button class="size-8  hover:shadow-neutral-300 hover:bg-green-700 rounded-lg justify-center w-full bg-green-600" @click="redactNote">
        <div class="text-white">Done</div>
      </button>
    </div>
  </div>
  <div class="flex flex-col">
    <button class="size-8 hover:shadow-neutral-300 hover:bg-neutral-200 rounded-lg" @click="startRedacting">
      <img src="../assets/pencil.svg" alt="" class="justify-self-center">
    </button>
    <button class="size-8 hover:shadow-neutral-300 hover:bg-red-400 rounded-lg mt-2" @click="deleteNote">
      <img src="../assets/trash-svgrepo-com.svg" alt="" class="pt-1">
    </button>
  </div>
</div>
</template>

<style scoped>
</style>

原因分析

在Vue3的<script setup>中,直接声明的普通变量(如let redacting = undefined;)不具备响应式特性,修改变量值不会触发视图更新。Vue3要求使用ref或reactive来创建可触发视图更新的响应式状态。

修复方案

  1. 从vue库导入ref函数,用于创建响应式变量
  2. 将redacting、redTitle、redContent改为ref包裹的响应式变量
  3. 在脚本中修改或访问ref变量时,必须通过.value属性操作;模板中使用时Vue会自动解包,无需添加.value

修改后的完整代码

<script setup lang="ts">
import axios from "axios";
import { ref } from "vue"; // 导入ref函数
const props = defineProps(['title', 'content', 'note_id']);

// 转为响应式ref变量,初始值设为false更符合逻辑
const redacting = ref(false);
const redTitle = ref(props.title);
const redContent = ref(props.content);

const deleteNote = async () => {
  await axios.delete(`http://localhost:3000/notes/${props.note_id}`)
      .then((res) => {
        if (res.status === 204) {
          location.reload()
        }
        else {
          console.log(`HTTP STATUS ${res.status}`)
        }
      })
      .catch(err => console.error('删除笔记失败:', err)) // 新增错误捕获
}

const startRedacting = () => {
  redacting.value = true; // 修改ref变量需使用.value
}

const redactNote = async () => {
  await axios.put(`http://localhost:3000/notes/${props.note_id}`, {
    Title: redTitle.value, // 访问ref变量值需使用.value
    Content: redContent.value
  })
      .then((res) => {
        if (res.status === 200) {
          redacting.value = false;
          location.reload()
        }
        else {
          console.log(`HTTP STATUS ${res.status}`)
        }
      })
      .catch(err => console.error('编辑笔记失败:', err)) // 新增错误捕获
}
</script>

<template>
<div class="flex flex-row justify-between border-2 border-r-6 border-gray-200 p-3 rounded-md">
  <div class="flex w-2.5 h-full bg-red-500 rounded-3xl resize-none flex-none" id="strip">
    <!--Poloska-->
  </div>
  <div v-if="!redacting" class="flex flex-col ml-8 text-wrap justify-self-start justify-start">
    <div id="title" class="text-xl justify-self-center text-left">
      {{ title }}
    </div>
    <div id="content" class="pt-4 text-pretty h-max truncate justify-self-start text-left">
      {{ content }}
    </div>
  </div>
  <div v-else>
    <div class="flex flex-col ml-8 text-wrap justify-self-start justify-start pr-2">
      <div class="text-xl justify-self-center text-left">
        <input type="text" v-model="redTitle" class="border-2 border-gray-200 rounded-md p-2 w-full">
      </div>
      <div id="content" class="pt-4 text-pretty h-max truncate justify-self-start text-left">
        <textarea v-model="redContent" class=" border-2 border-gray-200 rounded-md p-2 w-full"></textarea>
      </div>
      <button class="size-8  hover:shadow-neutral-300 hover:bg-green-700 rounded-lg justify-center w-full bg-green-600" @click="redactNote">
        <div class="text-white">Done</div>
      </button>
    </div>
  </div>
  <div class="flex flex-col">
    <button class="size-8 hover:shadow-neutral-300 hover:bg-neutral-200 rounded-lg" @click="startRedacting">
      <img src="../assets/pencil.svg" alt="" class="justify-self-center">
    </button>
    <button class="size-8 hover:shadow-neutral-300 hover:bg-red-400 rounded-lg mt-2" @click="deleteNote">
      <img src="../assets/trash-svgrepo-com.svg" alt="" class="pt-1">
    </button>
  </div>
</div>
</template>

<style scoped>
</style>

额外优化建议

  • 避免使用location.reload()刷新页面,可通过父组件状态更新或状态管理工具(如Pinia)同步数据,提升用户体验
  • 为axios请求添加catch块捕获网络异常,增强代码健壮性

内容的提问来源于stack exchange,提问作者Sanyokk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 04:47:34