英文:
Only show when JSON value is true
问题
如何只显示JSON数组中"checked"值设置为true的th/tr,使用v-if语句?
如果checked === true
,我想要显示它。如果checked === false
,我想要隐藏它。
App.vue:
<Overview
:activeColumns="items"
></Overview>
<script lang="ts" setup>
const items = [
{ id: 0, text: 'date', checked: true },
{ id: 1, text: 'name', checked: false },
{ id: 2, text: 'day', checked: false },
{ id: 3, text: 'time', checked: false },
{ id: 4, text: 'created', checked: false },
{ id: 5, text: 'reason', checked: true },
{ id: 6, text: 'comment', checked: true },
];
</script>
Overview.vue:
<script lang="ts" setup>
const props = defineProps<{
activeColumns: {};
}>();
const reactiveProps = reactive({
activeColumns: props.activeColumns,
});
<table>
<thead>
<tr>
<th class="date"><!-- 仅在 (text === 'date' && checked === true) 时显示 -->
<CustomComponent /> <!-- 不使用JSONArray数据中的任何内容 -->
</th>
<th class="name"> <!-- 仅在 (text === 'name' && checked === true) 时显示 -->
<OtherCustomComponent /> <!-- 不使用JSONArray数据中的任何内容 -->
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="date"><!-- 不使用JSONArray数据中的任何内容 --></td><!-- 仅在 (text === 'date' && checked === true) 时显示 -->
<td class="name"><!-- 不使用JSONArray数据中的任何内容 --></td><!-- 仅在 (text === 'name' && checked === true) 时显示 -->
</tr>
</tbody>
</table>
</script>
英文:
How can I only show the th/tr where the value of "checked" in the JSON Array is set to true using a v-if statement?
If checked === true
, I want to display it. If checked === false
, I want to hide it.
App.vue:
<Overview
:activeColumns="items"
></Overview>
<script lang="ts" setup>
const items = [
{ id: 0, text: 'date', checked: true },
{ id: 1, text: 'name', checked: false },
{ id: 2, text: 'day', checked: false },
{ id: 3, text: 'time', checked: false },
{ id: 4, text: 'created', checked: false },
{ id: 5, text: 'reason', checked: true },
{ id: 6, text: 'comment', checked: true },
];
</script>
Overview.vue:
<script lang="ts" setup>
const props = defineProps<{
activeColumns: {};
}>();
const reactiveProps = reactive({
activeColumns: props.activeColumns,
});
<table>
<thead>
<tr>
<th class="date"><!-- Only show if (text === 'date' && checked === true) -->
<CustomComponent /> <!-- Does not use any of the JSONArray data -->
</th>
<th class="name"> <!-- Only show if (text === 'name' && checked === true) -->
<OtherCustomComponent /> <!-- Does not use any of the JSONArray data -->
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="date"><!-- Does not use any of the JSONArray data --></td><!-- Only show if (text === 'date' && checked === true) -->
<td class="name"><!-- Does not use any of the JSONArray data --></td><!-- Only show if (text === 'name' && checked === true) -->
</tr>
</tbody>
</table>
</script>
答案1
得分: 1
以下是您要翻译的内容:
"It appears that your goal is to display table columns depending on the checked status of a data property that represents the column. If so, then again, I'd make all data reactive, and then I'd use Vue's computed properties to help us decide what to show.
So, assuming that this represents a simplification of the columns data:
const items = ref([
{ id: 0, text: 'date', checked: true },
{ id: 1, text: 'name', checked: false },
{ id: 2, text: 'day', checked: false },
{ id: 3, text: 'reason', checked: true },
{ id: 4, text: 'comment', checked: true },
]);
Then we can give the second component, Overview.vue, a props called "columns":
const props = defineProps(['columns']);
And then a computed property called activeColumns
that holds only the "checked" column objects:
const activeColumns = computed(() => {
return props.columns.filter((c) => c.checked);
});
Then let's assume that the data to display in the table looks something like this (again, a simplification):
const tableData = ref([
{
"id": 1,
"date": "2/1/2023",
"name": "SNAFU",
"day": "Wednesday",
"reason": "Whatever 1",
"comment": "Comment 1"
},
{
"id": 2,
"date": "2/2/2023",
"name": "FUBAR",
"day": "Thurday",
"reason": "Whatever 2",
"comment": "Comment 2"
},
//.... more data here
Then we can use the computed property, activeColumns
in a v-for to decide which data to show:
<tbody>
<tr v-for="row in tableData" :key="row.id">
<td v-for="col in activeColumns" :key="col.id">{{ row[col.text] }}</td>
</tr>
</tbody>
You also mention,
In each div I have different components, so I can not loop over them with a v-for.
But this isn't necessarily true since you can put your components into an array or an object and use dynamic components to allow you to loop over them:
// components that show the related table headers
import Date from './Date.vue';
import Name from './Name.vue';
import Day from './Day.vue';
import Reason from './Reason.vue';
import Comment from './Comment.vue';
const props = defineProps(['columns']);
const activeColumns = computed(() => {
return props.columns.filter((c) => c.checked);
});
// an object that holds all the table headers
const columnHeaders = ref({
'date': Date,
'name': Name,
'day': Day,
'reason': Reason,
'comment': Comment
});
Displayed as dynamic components:
<thead>
<tr>
<th v-for="col in activeColumns" :key="col.id">
<component :is="columnHeaders[col.text]"></component>
</th>
</tr>
</thead>
For example:
App.vue
<template>
<h2>Columns To Display</h2>
<div v-for="(item, index) in items">
<label for="item.id">
<input type="checkbox" v-model="item.checked" :value="item.id" :name="item.id" />
{{ item.text }}
</label>
</div>
<hr>
<Overview :columns="items"></Overview>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import Overview from './Overview.vue';
const items = ref([
{ id: 0, text: 'date', checked: true },
{ id: 1, text: 'name', checked: false },
{ id: 2, text: 'day', checked: false },
{ id: 3, text: 'reason', checked: true },
{ id: 4, text: 'comment', checked: true },
]);
</script>
and Overview.vue
<template>
<h2>
Overview
</h2>
<table>
<thead>
<tr>
<th v-for="col in activeColumns" :key="col.id">
<component :is="columnHeaders[col.text]"></component>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in tableData" :key="row.id">
<td v-for="col in activeColumns" :key="col.id">{{ row[col.text] }}</td>
</tr>
</tbody>
</table>
</template>
<script lang="ts" setup>
import { ref, computed, defineProps } from 'vue';
import Date from './Date.vue';
import Name from './Name.vue';
import Day from './Day.vue';
import Reason from './Reason.vue';
import Comment from './Comment.vue';
const props = defineProps(['columns']);
const activeColumns = computed(() => {
return props.columns.filter((c) => c.checked);
});
const columnHeaders = ref({
'date': Date,
'name': Name,
'day': Day,
'reason': Reason,
'comment': Comment
});
const tableData = ref([
{
"id": 1,
"date": "2/1/2023",
"name": "SNAFU",
"day": "Wednesday",
"reason": "Lorem ipsum",
"comment": "dolor sit amet, consectetur adipiscing elit"
},
{
"id": 2,
"date": "2/2/2023",
"name": "FUBAR",
"day": "Thurday",
"reason": "Ut enim",
"comment": "ad minim veniam, quis nostrud exercitation"
},
{
"id": 3,
"date": "2/3/2023",
"name": "BUZBAF",
"day": "Friday",
"reason": "Duis aute irure",
"comment": "dolor in reprehenderit in voluptate velit esse cillum dolore"
},
{
"id": 4,
"date": "2/4/2023",
"name": "FOO",
"day": "Saturday",
"reason": "Excepteur sint occaecat",
"comment": "cupidatat non proident, sunt in culpa qui officia"
},
{
"id": 5,
"date": "2/5/2023",
"name": "BAR",
"day": "Sunday",
"reason": "Sed ut perspiciatis",
"comment":
<details>
<summary>英文:</summary>
It appears that your goal is to display table columns depending on the checked status of a data property that represents the column. If so, then again, I'd make all data reactive, and then I'd use Vue's computed properties to help us decide what to show.
So, assuming that this represents a simplification of the columns data:
```lang-js
const items = ref([
{ id: 0, text: 'date', checked: true },
{ id: 1, text: 'name', checked: false },
{ id: 2, text: 'day', checked: false },
{ id: 3, text: 'reason', checked: true },
{ id: 4, text: 'comment', checked: true },
]);
Then we can give the second component, Overview.vue, a props called "columns":
const props = defineProps(['columns']);
And then a computed property called activeColumns
that holds only the "checked" column objects:
const activeColumns = computed(() => {
return props.columns.filter((c) => c.checked);
});
Then let's assume that the data to display in the table looks something like this (again, a simplification):
const tableData = ref([
{
"id": 1,
"date": "2/1/2023",
"name": "SNAFU",
"day": "Wednesday",
"reason": "Whatever 1",
"comment": "Comment 1"
},
{
"id": 2,
"date": "2/2/2023",
"name": "FUBAR",
"day": "Thurday",
"reason": "Whatever 2",
"comment": "Comment 2"
},
//.... more data here
Then we can use the computed property, activeColumns
in a v-for to decide which data to show:
<tbody>
<tr v-for="row in tableData" :key="row.id">
<td v-for="col in activeColumns" :key="col.id">{{ row[col.text] }}</td>
</tr>
</tbody>
You also mention,
> In each div I have different components, so I can not loop over them with a v-for.
But this isn't necessarily true since you can put your components into an array or an object and use dynamic components to allow you to loop over them:
// components that show the related table headers
import Date from './Date.vue';
import Name from './Name.vue';
import Day from './Day.vue';
import Reason from './Reason.vue';
import Comment from './Comment.vue';
const props = defineProps(['columns']);
const activeColumns = computed(() => {
return props.columns.filter((c) => c.checked);
});
// an object that holds all the table headers
const columnHeaders = ref({
'date': Date,
'name': Name,
'day': Day,
'reason': Reason,
'comment': Comment
});
Displayed as dynamic components:
<thead>
<tr>
<th v-for="col in activeColumns" :key="col.id">
<component :is="columnHeaders[col.text]"></component>
</th>
</tr>
</thead>
For example:
App.vue
<template>
<h2>Columns To Display</h2>
<div v-for="(item, index) in items">
<label for="item.id">
<input type="checkbox" v-model="item.checked" :value="item.id" :name="item.id" />
{{ item.text }}
</label>
</div>
<hr>
<Overview :columns="items"></Overview>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import Overview from './Overview.vue';
const items = ref([
{ id: 0, text: 'date', checked: true },
{ id: 1, text: 'name', checked: false },
{ id: 2, text: 'day', checked: false },
{ id: 3, text: 'reason', checked: true },
{ id: 4, text: 'comment', checked: true },
]);
</script>
and Overview.vue
<template>
<h2>
Overview
</h2>
<table>
<thead>
<tr>
<th v-for="col in activeColumns" :key="col.id">
<component :is="columnHeaders[col.text]"></component>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in tableData" :key="row.id">
<td v-for="col in activeColumns" :key="col.id">{{ row[col.text] }}</td>
</tr>
</tbody>
</table>
</template>
<script lang="ts" setup>
import { ref, computed, defineProps } from 'vue';
import Date from './Date.vue';
import Name from './Name.vue';
import Day from './Day.vue';
import Reason from './Reason.vue';
import Comment from './Comment.vue';
const props = defineProps(['columns']);
const activeColumns = computed(() => {
return props.columns.filter((c) => c.checked);
});
const columnHeaders = ref({
'date': Date,
'name': Name,
'day': Day,
'reason': Reason,
'comment': Comment
});
const tableData = ref([
{
"id": 1,
"date": "2/1/2023",
"name": "SNAFU",
"day": "Wednesday",
"reason": "Lorem ipsum",
"comment": "dolor sit amet, consectetur adipiscing elit"
},
{
"id": 2,
"date": "2/2/2023",
"name": "FUBAR",
"day": "Thurday",
"reason": "Ut enim",
"comment": "ad minim veniam, quis nostrud exercitation"
},
{
"id": 3,
"date": "2/3/2023",
"name": "BUZBAF",
"day": "Friday",
"reason": "Duis aute irure",
"comment": "dolor in reprehenderit in voluptate velit esse cillum dolore"
},
{
"id": 4,
"date": "2/4/2023",
"name": "FOO",
"day": "Saturday",
"reason": "Excepteur sint occaecat",
"comment": "cupidatat non proident, sunt in culpa qui officia"
},
{
"id": 5,
"date": "2/5/2023",
"name": "BAR",
"day": "Sunday",
"reason": "Sed ut perspiciatis",
"comment": "unde omnis iste natus error sit voluptatem accusantium doloremque laudantium"
}
]);
</script>
<style scoped>
table {
border-collapse: collapse;
border: 1px solid #FF0000;
}
table td,
th {
border: 1px solid #FF0000;
padding: 2px 10px;
}
</style>
For the array of components used as table headers:
Date.vue
<template>
Date
</template>
Name.vue
<template>
Name
</template>
Day.vue
<template>
Day
</template>
Reason.vue
<template>
Reason
</template>
Comment.vue
<template>
Comment
</template>
答案2
得分: -2
您应该更改JSON对象。
const activeDivs = {
date: { id: 0, text: "日期", checked: true },
name: { id: 1, text: "姓名", checked: false },
day: { id: 2, text: "日期", checked: false },
time: { id: 3, text: "时间", checked: false },
created: { id: 4, text: "创建时间", checked: false },
reason: { id: 5, text: "原因", checked: true },
comment: { id: 6, text: "评论", checked: true },
};
如果您不能更改JSON结构,则可以使用find方法来访问单个对象。
```javascript
found = Object.values(activeDivs).find((element) => element.text === '日期');
或者您可以使用计算属性来将数组转换为所需的对象。
英文:
You should change the JSON object.
const activeDivs = {
date: { id: 0, text: "date", checked: true },
name: { id: 1, text: "name", checked: false },
day: { id: 2, text: "day", checked: false },
time: { id: 3, text: "time", checked: false },
created: { id: 4, text: "created", checked: false },
reason: { id: 5, text: "reason", checked: true },
comment: { id: 6, text: "comment", checked: true },
};
if you can't change the JSON structure then use find method to access single object.
found = activeDivs.find((element) => element.text == 'date');
or you can use computed to turn your array to desired object.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论