Как добавить функцию редактирования в приложение todolist

В настоящее время я работаю над приложением todolist.

Что я хочу сделать, так это добавить функцию редактирования в это приложение, как показано на изображении ниже.

Прежде всего, я попытался передать только this.item.name из дочернего компонента (listItem.vue) в родительский компонент (addItemForm.vue), чтобы он отображался в поле ввода при нажатии на значок редактирования, но это не так. работай.

Если кто-нибудь может помочь мне понять, что я пытаюсь сделать, пожалуйста, дайте мне знать.

вот vue-файл.

app.vue

<template>
  <div class = "todoListContainer">
    <div class = "heading">
      <h2 id = "title">TodoList</h2>
      <add-item-form v-on:reloadlist = "getList()" />
    </div>
    <list-view :items = "items" v-on:reloadlist = "getList()" />
  </div>
</template>
<script>
import addItemForm from "./addItemForm.vue";
import listView from "./listView.vue";
export default {
  components: {
    addItemForm,
    listView,
  },
  data: function () {
    return {
      items: [],
    };
  },
  methods: {
    getList() {
      axios
        .get("api/items")
        .then((response) => {
          this.items = response.data;
          console.info(this.items);
        })
        .catch((error) => {
          console.info(error);
        });
    },
  },
  created() {
    this.getList();
    console.info("create success!");
  },
};
</script>

<style scoped>
.todoListContainer {
  width: 350px;
  margin: auto;
}

.heading {
  background: #e6e6e6;
  padding: 10px;
}

#title {
  text-align: center;
}
</style>

addItemForm.vue

<template>
  <div class = "addItem">
    <input type = "text" v-model = "item.name" />
    <font-awesome-icon
      icon = "plus-square"
      @click = "addItem()"
      :class = "[item.name ? 'active' : 'inactive', 'plus']"
    />
  </div>
</template>
<script>
export default {
  data: function () {
    return {
      item: {
        name: "",
      },
    };
  },
  methods: {
    addItem() {
      if (this.item.name == "") {
        return;
      }
      axios
        .post("api/item/store", {
          item: this.item,
        })
        .then((response) => {
          if (response.status == 201) {
            this.item.name = "";
            this.$emit("reloadlist");
          }
        })
        .catch((error) => {
          console.info(error);
        });
    },
  },
};
</script>

<style scoped>
.addItem {
  display: flex;
  justify-content: center;
  align-items: center;
}

input {
  background: #f7f7f7;
  border: 0px;
  outline: none;
  padding: 5px;
  margin-right: 10px;
  width: 100%;
}

.plus {
  font-size: 20px;
}

.active {
  color: #00ce25;
}

.inactive {
  color: #999999;
}
</style>

listView.vue

<template>
  <div>
    <div v-for = "(item, index) in items" :key = "index">
      <list-item
        :item = "item"
        class = "item"
        v-on:itemchanged = "$emit('reloadlist')"
      />
    </div>
  </div>
</template>
<script>
import listItem from "./listItem.vue";
export default {
  props: ["items"],
  components: {
    listItem,
  },
};
</script>

<style scoped>
.item {
  background: #e6e6e6;
  padding: 5px;
  margin-top: 5px;
}
</style>

listItem.vue

<template>
  <div class = "item">
    <input type = "checkbox" @change = "updateCheck()" v-model = "item.completed" />
    <span :class = "[item.completed ? 'completed' : '', 'itemText']">{{
      item.name
    }}</span>
    <button @click = "removeItem()" class = "trashcan">
      <font-awesome-icon icon = "trash" />
    </button>
    <button @click = "editItem" class = "pencil">
      <font-awesome-icon icon = "pencil" />
    </button>
  </div>
</template>
<script>
export default {
  props: ["item"],
  methods: {
    updateCheck() {
      axios
        .put("api/item/" + this.item.id, {
          item: this.item,
        })
        .then((response) => {
          if (response.status == 200) {
            this.$emit("itemchanged");
          }
        })
        .catch((error) => {
          console.info(error);
        });
    },
    removeItem() {
      axios
        .delete("api/item/" + this.item.id)
        .then((response) => {
          if (response.status == 200) {
            this.$emit("itemchanged");
          }
        })
        .catch((error) => {
          console.info(error);
        });
    },

    editItem() {
      const text = this.item .name;
      this.$emit('custom-click', text);
    }
  },
};
</script>

<style scoped>
.completed {
  text-decoration: line-through;
  color: #999999;
}
.itemText {
  width: 100%;
  margin-left: 20px;
}
.item {
  display: flex;
  justify-content: center;
  align-items: center;
}
.trashcan {
  background: #e6e6e6;
  border: none;
  color: #ff0000;
  outline: none;
}
.pencil {
  background: #e6e6e6;
  border: none;
  color: #1df548;
  outline: none;
}
</style>

items_table

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateItemsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('items', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->boolean('completed')->default(false);
            $table->timestamp('completed_at')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('items');
    }
}

Прежде всего, я попытался передать только this.item.name из дочернего компонента (listItem.vue) в родительский компонент (addItemForm.vue), чтобы он отображался в поле ввода при нажатии на значок редактирования, но это не так. работай.

Поэтому я хочу, чтобы целевой текст отображался в поле ввода при первом нажатии на символ редактирования.

Постскриптум

Постскриптум2
Я отладил его, поместив точку останова в соответствующую точку в инструментах разработчика Chrome. Я подтвердил, что значение передается @custom-click="$emit('custom-click', $event)" в listView.vue, но, похоже, оно не достигает функции редактирования. Кроме того, я получаю предупреждение об ошибке, как показано на изображении.

Постскриптум3
Инструменты разработчика Vue.js

can help me understand what I am trying to do + sharing 400 lines of code не очень хорошее совпадение. Что вы видите в своих инструментах разработки Vue?
kissu 13.11.2022 02:43
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
93
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы испускаете «пользовательский щелчок» из listItem, это хорошо. Далее нужно прослушать событие в родительском элементе (listView) и повторно передать его следующему родителю, app.vue. Как только app.vue получит элемент, вам нужно передать его обратно в качестве реквизита вашему компоненту AddItemForm.vue и установить его как v-модель <input>.

Это в основном то, что вам нужно добавить к каждому компоненту:

listView.vue (повторная передача)

<list-item
  :item = "item"
  class = "item"
  v-on:itemchanged = "$emit('reloadlist')"
  @custom-click = "$emit('custom-click', $event)"
/>

App.vue (прослушайте излучение, найдите соответствующий элемент в this.items, отправьте его как реквизит в addItemForm)

<div class = "heading">
  <h2 id = "title">TodoList</h2>
  <add-item-form v-on:reloadlist = "getList()" :editItem = "editItem" />
</div>
<list-view :items = "items" v-on:reloadlist = "getList()" @custom-click = "edit" />
data: function () {
  editItem: null
},
methods: {
  edit(item) {
    this.editItem = this.items.find(i => i.name === item);
  }
}

AddItemForm.vue (установите v-модель с помощью реквизита)

props: {
  editItem: {
    type: Object,
    default() {
      return null;
    }
  }
},
watch: {
  editItem(newItem) {
    this.item = newItem;
  }
}

Спасибо за ваш комментарий. Я отразил то, что вы описали, но когда я нажал на символ редактирования, значение не появилось в поле ввода. Я забыл упомянуть, что я использую vue3, это метод записи, который не работает с vue3? Сделанные мной изменения я прикрепил в постскриптуме.

shozo 13.11.2022 05:52

Поскольку я не могу запустить ваш код для вас, можете ли вы отладить и, возможно, сузить область, в которой может быть проблема? Используйте консольный журнал и/или инструменты разработчика и убедитесь, что 1) первая эмиссия работает, 2) вторая эмиссия работает, 3) правильный элемент находится в app.vue, 4) реквизит передается в addItemForm и установите v-модель. Пожалуйста, выясните, какой шаг терпит неудачу.

yoduh 13.11.2022 07:47

Я добавил отладочную информацию. Кстати, когда я отлаживаю vuejs, я обычно делаю это с помощью инструментов разработчика Chrome, какой самый распространенный способ отладки vuejs?

shozo 13.11.2022 10:53

@shozo с помощью инструментов разработки VueJS.

kissu 13.11.2022 12:00

@kissu Спасибо за ваш комментарий. Как я уже добавил, у меня все еще есть расширение Chrome Vue.js devtools, но это расширение не выполняет отладку, как обычные инструменты разработчика Chrome, верно? Я не знаю, как использовать это расширение.

shozo 13.11.2022 12:57

@shozo у вас есть в режиме реального времени, не нужно «останавливаться». Но оба могут хорошо работать вместе.

kissu 13.11.2022 13:09

@kissu Я также узнаю, как использовать инструменты. Приятно знать, что все используют этот инструмент.

shozo 13.11.2022 14:15

@yoduh Я сделал очень глупую ошибку. Я написал функцию редактирования в функции создания, хотя должен был написать ее внутри метода... Я подтвердил, что щелкнутое содержимое успешно отражается в поле ввода. Затем я хотел бы добавить процесс, чтобы сделать отметку плюса меткой редактирования и применить отредактированный контент. Если будут вопросы, спрошу еще раз. Большое спасибо.

shozo 14.11.2022 11:39

Другие вопросы по теме