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

Vue3中通过Props初始化复选框选中状态问题求助

问题根源

  1. 复选框绑定冲突:同时使用:checked和v-model,v-model会完全接管复选框的选中状态,导致:checked="element.finish"的设置被覆盖。
  2. props直接修改违反单向数据流:tasksList是父组件传入的props,直接修改其中的task.finish不会触发视图更新,且不符合Vue的设计规范。
  3. 状态更新逻辑错误:updateTasksList方法中依赖finishedTask数组判断状态,逻辑与实际需求不匹配。

修复步骤

1. 清理复选框冗余绑定

删除v-model="finishedTask"和:value="element.id",只保留:checked="element.finish"来关联任务的完成状态:

<input
  @change="updateTasksList(element, $event)"
  type="checkbox"
  :checked="element.finish"
>

2. 把props转为本地可修改数据

Vue禁止直接修改props,所以需要将父组件传入的tasksList复制到组件本地的data中,并监听props变化同步更新:

data() {
  return {
    drag: false,
    localTasksList: [...this.tasksList] // 复制props到本地
  }
},
watch: {
  tasksList(newList) {
    this.localTasksList = [...newList] // 父组件更新时同步本地数据
  }
}

同时把draggable的v-model改为本地数据:

<draggable 
  v-model="localTasksList" 
  tag="div" 
  item-key="id"
  :move="checkMove"
  ghost-class="ghost"
  chosen-class="chosen"
>

3. 简化状态更新逻辑

直接根据复选框的选中状态设置任务的finish属性,不需要依赖额外数组:

async updateTasksList(task, event) {
  task.finish = event.target.checked; // 直接绑定复选框状态
  await this.updateTask(task);
  // 通知父组件更新列表(可选,配合父组件的.sync修饰符使用)
  this.$emit('update:tasksList', [...this.localTasksList]);
}

4. 父组件同步更新(可选)

如果需要父组件同步更新任务列表,在父组件使用组件时添加.sync修饰符:

<task-list :tasks-list.sync="parentTasksList" :list-id="xxx" :show-task-list="xxx" />

修复后完整代码

模板部分

<template >
    <div 
        :class="[ showTaskList === true ? '' : 'hidden' ] + ' mt-4 task-list list weekList flex flex-col p-6 max-w-sm mx-auto bg-gray rounded-xl shadow-lg'"
    >
        <div class="flex flex-row gap-4">
            Liste des taches ({{listId}}) <button @click="displayForm(listId)" class="px-2 rounded bg-blue text-white text-sm uppercase right">+</button>
            <hr class="text-gray1 mb-4">
        </div>
        <draggable 
            v-model="localTasksList" 
            tag="div" 
            item-key="id"
            :move="checkMove"
            ghost-class="ghost"
            chosen-class="chosen"
        >
        <template #item="{element, index}">
            <div class="container flex flex-row">
                <div class="">
                    <div class="title font-bold">{{ element.title }}</div>
                    <div class="date text-sm text-left text-gray1">Terminé
                        <input
                            @change="updateTasksList(element, $event)"
                            type="checkbox"
                            :checked="element.finish"
                            >
                    </div>{{element.id}} - {{element.finish}}
                </div>
                <div class="ml-auto font-bold text-right">
                    <button 
                        v-if="element.id" 
                        @click="$store.dispatch('removeTask', element.id)"
                    >
                    Supprimer
                    </button>
                </div>
            </div>
        </template>
        </draggable>
    </div>
</template>

脚本部分

import Draggable from 'vuedraggable';
import axios from 'axios';
axios.defaults.baseURL = 'http://localhost:3000';

export default {
    name: 'taskList',
    props: ['tasksList','listId', 'showTaskList'],
    components: {
        Draggable,
    },
    data() {
        return {
            drag: false,
            localTasksList: [...this.tasksList],
        }
    },
    watch: {
        tasksList(newList) {
            this.localTasksList = [...newList];
        }
    },
    methods: {
        displayForm() {
            this.$emit('displayForm', this.listId);
        },
        checkMove(e) {
            console.log("checkMove");
            console.log(e.draggedContext.element.position);
        },
        async updateTasksList(task, event) {
            task.finish = event.target.checked;
            await this.updateTask(task);
            this.$emit('update:tasksList', [...this.localTasksList]);
        },
        async updateTask(task) {
            try {
                const message = await axios.patch(`/task/${task.id}`, task);

                if (!message) {
                    this.$store.dispatch('setError', 'Impossible de créer la tache');
                }
                this.message = 'Tache update';

            } catch (error) {
                this.$store.dispatch('setError', error);
            }
        }
    },
    computed: {
        error() {
            return this.$store.state.error;
        },
    },
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 12:48:25