一旦在子组件中更新了 prop,如何调用函数。 Vue3 组合 API

How to call a function, once a prop is updated in a child component. Vue3 composition API

我有一个待办事项列表,它是通过 for 循环生成的。每个 todo 作为 prop 传递给 <singleTodo /> 子组件。从 <SingleTodo/> 组件中删除 todo 后,如何刷新页面(意思是:调用 getTodos 函数)。使用 onUpdated 生命周期挂钩有效,但问题是一旦我删除了一个 todo,就会有一个不可阻挡的 GET 循环到 REST API。有什么想法吗?

列表组件

<template>
  <div>
    <CreateTodo />
    <hr />

    <div class="TodoContainer">
      <SingleTodo
        v-for="todo in todos"
        v-bind:key="todo.id"
        :todo="todo"
        class="TodoComponent"
      />
    </div>
    <hr />
  </div>
</template>

<script>
import CreateTodo from "./CreateTodo";
import SingleTodo from "./SingleTodo";
import { onMounted, ref } from "vue";

//
export default {
  components: {
    CreateTodo,
    SingleTodo,
  },

  props: {
    todo: Object,
  },

  setup() {
    const API_URL = "http://127.0.0.1:8000/api/todo-list/";
    const todos = ref([]);

    async function getTodos() {
      const response = await fetch(API_URL);
      const json = await response.json();
      todos.value = json;
    }


    onMounted(() => {
      getTodos();
    });

    // onUpdated(() => {
    //   getTodos();
    // });

    return {
      todos,
      getTodos,
    };
  },
};
</script>

子组件,SingleTodo.vue

<template>
  <div>
    {{ todo.id }}{{ todo.completion }}{{ todo.todo }}
    <button @click="removeTodo(todo.id)">delete</button>
  </div>
</template>

<script>
// import { getTodos } from "./TodoHooks.js";
import { getCookie } from "./TodoHooks.js";

export default {
  props: {
    todo: Object,
  },

  setup() {
    const API_DELETE = "http://127.0.0.1:8000/api/todo-delete";
    const csrftoken = getCookie("csrftoken");

    //

    async function removeTodo(id) {
      var csrftoken = getCookie("csrftoken");
      fetch(`${API_DELETE}/${id}/`, {
        method: "DELETE",
        headers: {
          "Content-type": "application/json",
          "X-CSRFToken": csrftoken,
        },
      }).then((response) => {
        // NEEDED TO UPDATE AUTOMATICALLY.
        // getTodos();
        return response;
      });
    }

    return {
      removeTodo,
      csrftoken,
    };
  },
};
</script>

尝试向父组件发出事件以刷新列表,添加 emits 选项,例如:

props: {
    todo: Object,
  },
  emits:['refresh'],
....

然后在 then 回调中发出 refresh 事件:

 }).then((response) => {
        emit('refresh')

但在你应该从设置参数 setup(_,{emit}) {

的上下文中破坏 emit 属性

完整代码:

<script>
// import { getTodos } from "./TodoHooks.js";
import { getCookie } from "./TodoHooks.js";

export default {
  props: {
    todo: Object,
  },
  emits:['refresh'],
  setup(_,{emit}) {
    const API_DELETE = "http://127.0.0.1:8000/api/todo-delete";
    const csrftoken = getCookie("csrftoken");

    //

    async function removeTodo(id) {
      var csrftoken = getCookie("csrftoken");
      fetch(`${API_DELETE}/${id}/`, {
        method: "DELETE",
        headers: {
          "Content-type": "application/json",
          "X-CSRFToken": csrftoken,
        },
      }).then((response) => {
        emit('refresh')
        return response;
      });
    }

    return {
      removeTodo,
      csrftoken,
    };
  },
};
</script>

在父组件中:

 <SingleTodo
        v-for="todo in todos"
        v-bind:key="todo.id"
        :todo="todo"
        class="TodoComponent"
        @refresh="getTodos"

      />