如何切换待办事项的完成选项?

huangapple go评论71阅读模式
英文:

How to toggle a todo completed option?

问题

I'm expecting clicking the Done/Undone individual task button to toggle the task data completed to opposite using Vuex store actions. But I'm getting the 404 error. Even though I'm passing the task id from the child component. Or should I do it with mutations?

https://stackblitz.com/edit/nuxt-bootstrap-vue-dynamic-img-bkwixg?file=store%2Findex.js,components%2FTask.vue

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->
// Child component

<template>
  <div :class="{ task: task.completed }">
    <p class="content">
      {{ task.todo }}
    </p>
    <button @click="toggleTask">
      {{ task.completed ? 'Undone' : 'Done' }}
    </button>
  </div>
</template>

<script>
export default {
  data() {
    return {};
  },
  props: ['task'],
  methods: {
    toggleTask(id) {
      this.$store.dispatch('toggleTask', id);
    },
  },
};
</script>

// Parent component

<template>
  <Task v-for="task in tasks" :key="task.id" :task="task" />
</template>

<script>
export default {
  data() {
    return {
      todo: '',
      completed: false,
      search: '',
    };
  },
  computed: {
    tasks() {
      return this.$store.getters.getTasks(this.search);
    },
  },
  mounted() {
    this.$store.dispatch('getTasks').then((data) => console.log(this.tasks));
  },
};
</script>

// Store

export const state = () => ({
  tasks: [],
});

export const actions = {
  async getTasks(context) {
    const res = await fetch('https://dummyjson.com/todos/user/5');
    if (res.ok) {
      let result = await res.json();
      context.commit('setTasks', result.todos);
    }
    return res.ok;
  },
  async toggleTask(context, id) {
    const res = await fetch(`https://dummyjson.com/todos/${id}`, {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json;charset=utf-8',
      },
      // body: JSON.stringify(data),
    });
    if (res.ok) {
      const tasks = (context.state.tasks.find(
        (task) => task.id === id
      ).completed = !completed);
      context.commit('setTask', id); // or should I commit to toggle task mutation and how can I do it ?
    }
    return res.ok;
  },
};

export const mutations = {
  setTasks(state, data) {
    state.tasks = data;
  },
  toggleTask(state, id) {
    state.tasks.find((task) => task.id === id).completed = !completed;
  },
};

export const getters = {};

Please note that the code you provided seems to contain a couple of issues, such as the undefined variable completed in the toggleTask action and the incorrect usage of this.$store.commit in the action. You may need to revise the code accordingly for it to work as intended.

英文:

I'm expecting clicking the Done/Undone individual task button to toggle the task data completed to opposite using Vuex store actions. But I'm getting the 404 error. Even though I'm passing the task id from the child component. Or should I do it with mutations?

https://stackblitz.com/edit/nuxt-bootstrap-vue-dynamic-img-bkwixg?file=store%2Findex.js,components%2FTask.vue

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

// Child component
&lt;template&gt;
&lt;div :class=&quot;{ task: task.completed }&quot;&gt;
&lt;p class=&quot;content&quot;&gt;
{{ task.todo }}
&lt;/p&gt;
&lt;button @click=&quot;toggleTask&quot;&gt;
{{ task.completed ? &#39;Undone&#39; : &#39;Done&#39; }}
&lt;/button&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;script&gt;
export default {
data() {
return {};
},
props: [&#39;task&#39;],
methods: {
toggleTask(id) {
this.$store.dispatch(&#39;toggleTask&#39;, id);
},
},
};
&lt;/script&gt;
// Parent component
&lt;template&gt;
&lt;Task v-for=&quot;task in tasks&quot; :key=&quot;task.id&quot; :task=&quot;task&quot; /&gt;
&lt;/template&gt;
&lt;script&gt;
export default {
data() {
return {
todo: &#39;&#39;,
completed: false,
search: &#39;&#39;,
};
},
computed: {
tasks() {
return this.$store.getters.getTasks(this.search);
},
},
mounted() {
this.$store.dispatch(&#39;getTasks&#39;).then((data) =&gt; console.log(this.tasks));
},
};
&lt;/script&gt;
// Store 
export const state = () =&gt; ({
tasks: [],
});
export const actions = {
async getTasks(context) {
const res = await fetch(&#39;https://dummyjson.com/todos/user/5&#39;);
if (res.ok) {
let result = await res.json();
context.commit(&#39;setTasks&#39;, result.todos);
}
return res.ok;
},
async toggleTask(context, id) {
const res = await fetch(`https://dummyjson.com/todos/${id}`, {
method: &#39;PUT&#39;,
headers: {
&#39;Content-Type&#39;: &#39;application/json;charset=utf-8&#39;,
},
// body: JSON.stringify(data),
});
if (res.ok) {
const tasks = (context.state.tasks.find(
(task) =&gt; task.id === id
).completed = !completed);
context.commit(&#39;setTask&#39;, id);  // or should I commit to toggle task mutation and how can I do it ?
}
return res.ok;
},
};
export const mutations = {
setTasks(state, data) {
state.tasks = data;
},
toggleTask(state, id) {
state.tasks.find((task) =&gt; task.id === id).completed = !completed;
},
};
export const getters = {
},
};

<!-- end snippet -->

答案1

得分: 0

在点击处理程序中

 toggleTask(id) {
this.$store.dispatch('toggleTask', id);
},

id 是一个事件对象。你需要正确传递 id。以下代码应该有效

this.$store.dispatch('toggleTask', this.task.id);
英文:

In the click handler

 toggleTask(id) {
this.$store.dispatch(&#39;toggleTask&#39;, id);
},

id is an event object. You need to properly pass the id here. Below should work

this.$store.dispatch(&#39;toggleTask&#39;, this.task.id);

答案2

得分: 0

Here is the translated code snippet:

首先,您将 task 传递给方法:

<button @click="toggleTask(task)">
  {{ task.completed ? 'Undone' : 'Done' }}
</button>

然后,在 Vuex 中创建一个动作,该动作将发送数据并提交变异:

async toggleTask(context, task) {
  const res = await fetch(`https://dummyjson.com/todos/${task.id}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json;charset=utf-8',
    },
    body: JSON.stringify({ completed: !task.completed }),
  });
  let result = await res.json();
  context.commit('updateTask', result);
}

最后,在变异中:

updateTask(state, task) {
  state.tasks = [
    ...state.tasks.map(item =>
      item.id !== task.id ? item : { ...item, ...task }
    )
  ]
}

如果您需要进一步的帮助,请告诉我。

英文:

First, You pass task to method:

&lt;button @click=&quot;toggleTask(task)&quot;&gt;
{{ task.completed ? &#39;Undone&#39; : &#39;Done&#39; }}
&lt;/button&gt;

then in Vuex create action that will put data and commit mutation:

async toggleTask(context, task) {
const res = await fetch(`https://dummyjson.com/todos/${task.id}`, {
method: &#39;PUT&#39;,
headers: {
&#39;Content-Type&#39;: &#39;application/json;charset=utf-8&#39;,
},
body: JSON.stringify({completed: !task.completed}),
})
let result = await res.json();
context.commit(&#39;updateTask&#39;, result)
},

at the end mutation:

updateTask(state, task) {
state.tasks = [
...state.tasks.map(item =&gt; 
item.id !== task.id ? item : {...item, ...task}
)
] 
},

huangapple
  • 本文由 发表于 2023年5月8日 02:36:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76195665.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定