【问题标题】:How to call a function, once a prop is updated in a child component. Vue3 composition API在子组件中更新道具后如何调用函数。 Vue3 组合 API
【发布时间】:2021-02-23 09:01:06
【问题描述】:

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

列表组件

<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>

【问题讨论】:

    标签: javascript vue.js vue-component vuejs3 vue-composition-api


    【解决方案1】:

    尝试向父组件发出事件以刷新列表,添加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"
    
          />
    

    【讨论】:

      猜你喜欢
      • 2019-07-08
      • 2021-03-05
      • 2021-11-05
      • 2022-10-24
      • 2019-12-19
      • 2022-11-09
      • 2021-02-23
      • 1970-01-01
      • 2021-12-23
      相关资源
      最近更新 更多