hi 大家好, 我想實作一個Vue table可以checked單一選項與依user_id判斷check all這個user內所有選項的功能, 但目前點選clickCheckAll()是全部所有user內的選項都被勾選, 想請問是哪邊有問題還是有什麼更好的做法可以實現呢?
Script部分:
export default {
data() {
return {
userlistes: [
{
id: 2,
username: "Larry",
department_id: 3,
department: {
department_name: "IT",
id: 3,
},
worklists: [
{
id: 278,
user_id: 2,
task_id: 1,
date: "2021-07-30",
hour: 2,
description: "A",
is_overtime: false,
overtime_hour: 0,
task: {
taskname: "Task A",
},
hr_checked: false,
},
{
id: 277,
user_id: 2,
task_id: 1,
date: "2021-07-30",
hour: 3,
description: "B",
is_overtime: false,
overtime_hour: 0,
task: {
taskname: "Task B",
},
hr_checked: false,
},
],
},
{
id: 4,
username: "Tom",
department_id: 2,
department: {
department_name: "Business",
id: 2,
},
worklists: [
{
id: 259,
user_id: 4,
task_id: 7,
date: "2021-07-27",
hour: 6.5,
description:
"A",
is_overtime: false,
overtime_hour: 0,
task: {
taskname: "Task A",
},
hr_checked: false,
},
{
id: 260,
user_id: 4,
task_id: 7,
date: "2021-07-27",
hour: 0.5,
description: "B",
is_overtime: false,
overtime_hour: 0,
task: {
taskname: "Task B",
},
hr_checked: false,
},
],
},
],
isChecklist: [],
checkAll: false,
};
},
methods: {
clickCheckAll() {
var _this = this;
_this.checkAll = !_this.checkAll;
for (var i = 0; i < _this.userlistes.length; i++) {
var checkedData1 = _this.userlistes[i];
var user_id = _this.userlistes[i].id;
console.log("user_id = " + user_id);
for (var y = 0; y < checkedData1.worklists.length; y++) {
var checkedData = checkedData1.worklists[y];
var checkdata_userId = checkedData1.worklists[y].user_id;
console.log("checkdata_userId = " + checkdata_userId);
if (user_id === checkdata_userId) {
checkedData1.worklists[y].hr_checked = _this.checkAll;
}
console.log(checkedData);
// updateWorkhourAPI(checkedData.id, checkedData);
}
}
},
clickCheckbox(id, worklist) {
var _this = this;
worklist.hr_checked = !worklist.hr_checked;
if (worklist.manager_checked) {
_this.isChecklist.push(id);
updateWorkhourAPI(id, worklist);
} else {
var last = _this.isChecklist.length - 1;
_this.isChecklist.splice(last, 1);
updateWorkhourAPI(id, worklist);
}
if (_this.isChecklist.length == _this.userlistes.length) {
_this.checkAll = true;
} else {
_this.checkAll = false;
}
},
},
};
HTML:
<b-card no-body class="mb-1" v-for="users in userlistes" :key="users.id">
<b-card-header header-tag="header" class="p-0" role="tab">
<div class="d-grid gap-2">
<b-button
block
variant="outline-primary"
v-b-toggle="`accordion-${users.id}`"
>
{{ users.username }}
</b-button>
</div>
</b-card-header>
<b-collapse
:id="`accordion-${users.id}`"
accordion="table-accordion"
role="tabpanel"
>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th colspan="10">
<h3 style="text-align: center">
{{ users.username }} Work-Lists
</h3>
</th>
</tr>
<tr>
<th>Task Name</th>
<th>Date</th>
<th>Description </th>
<th>Hour (hr)</th>
<th>Overtime </th>
<th>Overtime Hour (hr)</th>
<th>
<label class="form-checkbox">
<input
type="checkbox"
@click="clickCheckAll()"
v-model="checkAll"
/>
<i class="form-icon"></i>
</label>
</th>
</tr>
</thead>
<tbody>
<tr v-for="worklist in users.worklists" :key="worklist.id">
<td>{{ worklist.task.taskname }}</td>
<td>{{ worklist.date }}</td>
<td>{{ worklist.description }}</td>
<td>{{ worklist.hour }}</td>
<td>{{ worklist.is_overtime ? "Yes" : "No" }}</td>
<td>{{ worklist.overtime_hour }}</td>
<td>
<label class="form-checkbox">
<input
type="checkbox"
@click="clickCheckbox(worklist.id, worklist)"
v-model="worklist.hr_checked"
/>
<i class="form-icon">
{{ worklist.hr_checked }}
</i>
</label>
</td>
</tr>
</tbody>
</table>
</b-collapse>
</b-card>
帶 index 進去就不用再去多找一次 users 的資料,另外如果使用 v-model="checkAll" 除非變數是陣列,不然 render 出來的 checkbox 都還是參照同一個變數,可以用 watch 或 computed 去讓他自動更新,這邊就要看要怎麼判斷怎樣算 check all 了。
<b-card no-body class="mb-1" v-for="(users, idx) in userlistes" :key="users.id">
<!-- ... -->
<b-collapse
:id="`accordion-${users.id}`"
accordion="table-accordion"
role="tabpanel"
>
<table class="table table-striped table-bordered">
<thead>
<!-- ... -->
<th>
<label class="form-checkbox">
<input
type="checkbox"
@click="clickCheckAll(idx)"
:value="allChecked(idx)"
/>
<i class="form-icon"></i>
</label>
</th>
</tr>
</thead>
<!-- ... -->
</table>
</b-collapse>
</b-card>
export default {
data() {
return { /* ... */ };
},
methods: {
allChecked(idx) {
return this.userlistes[idx].worklists.some((el) => el.hr_checked)
},
clickCheckAll(idx) {
this.checkAll = !this.checkAll;
const currentUser = this.userlists[idx]
for (let i = 0; i < currentUser.worklists.length; i++) {
currentUser.worklists[i].hr_checked = this.ccheckAll;
}
},
},
// ...
}
謝謝 listennn08大大的解惑, 抱歉我剛開始接觸Vue, 剛剛套用您提供的方法用index去判斷, 但console出現Error如圖 是因為currentUser.worklists.length
讀到空值嗎??請問要怎麼排除這個Error
抱歉以上問題解決了 再次感謝!!