Vue.js-在简单对象中循环,并在用户单击复选框时发送对象



我是Vue.js的新手,想了解v-model如何使用复选框。我正在使用vuetify复选框。我的组件得到一个对象作为值道具,我想根据每个键值对显示复选框,看起来像

this.value={property1:true,property2:false}因此,我想在这里显示一个具有可标记属性1的复选框,并且该复选框应该被选中,因为值为true。第二个复选框将被取消选中。

当选中复选框时,我想发送一个带有键和值的对象来保存它。我现在只能获得值,但我能用它做什么?如果我试图获得键和值,问题是当我取消选中它时,它发送null而不是键和值对,我应该如何管理?

<template>
<div class="d-flex flex-wrap justify-space-between">
<div class="d-flex flex-wrap flex-column">
<v-checkbox
class="add-checkbox"
ref="additionalDetails"
v-for="(value, key) in additionalDetails"
type="checkbox"
:key="key"
:value="{key, value}"
v-model="additionalDetails"
:label="key"
><template v-slot:label
><span class="body-2"
>{{
key
}}
</span>
</template></v-checkbox
>
</div>
</div>
</template>
<script>
export default {
name: "additional-details",
props: {
value: Object,
},
components: {},
data: function () {
return {
newAdditionalDetails: [],
};
},
computed: {
additionalDetails: {
get: function () {
return this.value;
},
set: function ({ key, value}) {
let newObject = { ...this.value };
newObject[key] = value;
this.newAdditionalDetails = newObject
},
},
},
methods: {},
beforeMount() {},
};
</script>

v-model应该是您想要跟踪的相同类型的值,在本例中是一个对象,但实际上是因为v-对于对象数组,使用您希望复选框保持/发出的值初始化。还需要明确告知v-checkbox组件什么对象键值等于"truthy"one_answers"falsy"。另一个提示:由于您也在对象属性上循环,v-for中的第三个别名将为您提供索引。这样的东西会起作用:

<template>
<div>
<v-checkbox
v-for="(value, key, index) in initValues" :key=index
:label=key
v-model=checkboxes[index]
:value="{ key: key, value: value }"
:false-value="{ key: key, value: false }"
:true-value="{ key: key, value: true }"
@change="log(checkboxes[index])"
></v-checkbox>
</div>
</template>
<script>
export default {
data: () => ({
initValues: {
'hi': true,
'bye': false,
'ok': true
},
checkboxes: []
}),
methods: {
log(newValue) {
console.log(newValue)
}
},
created() {
// initialize array of objects where each object is a key-value pair from initValues
this.checkboxes = Object.entries(this.initValues).map(( [k, v] ) => ({ [k]: v }))
}
};
</script>

这有点棘手,老实说我不会这么做。一个更简单的解决方案是只跟踪值,并在复选框输入更改时创建/发送键值对,例如

<template>
<div>
<v-checkbox
v-for="(value, key, index) in initValues" :key=index
:label="key"
v-model=checkboxes[index]
@change="log(key, checkboxes[index])"
></v-checkbox>
</div>
</template>
<script>
export default {
data: () => ({
initValues: {
'hi': true,
'bye': false,
'ok': true
},
checkboxes: []
}),
methods: {
log(key, newValue) {
console.log({ [key]: newValue })
}
},
created() {
this.checkboxes = Object.values(this.initValues)
}
};
</script>

不必编写如此复杂的逻辑,只需根据additionalDetailsv-model中绑定对象属性即可实现。

实时演示

new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
additionalDetails: [{
property1: true
}, {
property2: false
}]
}
},
methods: {
getChecboxValues() {
console.log('additionalDetails', JSON.stringify(this.additionalDetails))
}
}
})
<script src="https://unpkg.com/vue@2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify@2.6.8/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify@2.6.8/dist/vuetify.min.css"/>
<link rel="stylesheet" href="https://unpkg.com/@mdi/font@6.x/css/materialdesignicons.min.css"/>
<div id="app">
<v-app id="inspire">
<v-container
class="px-0"
fluid
>
<v-checkbox
v-for="(value, key) in additionalDetails"
:key="key"          
:label="Object.keys(value)[0]"
v-model="value[Object.keys(value)[0]]"          
></v-checkbox>
<v-btn depressed color="primary" @click="getChecboxValues">
Submit
</v-btn>
</v-container>
</v-app>
</div>

最后,我将initail对象(此处附带字符串(转换为一个数组,并添加了要在v-model中更新的已检查道具。我还必须添加一个方法来设置新对象(下面的示例代码与原来的代码有点不同,很抱歉(不知何故,计算出的additionalDetails的setter从未触发过。我不知道为什么,如果有人触发了,提前感谢您的分享。

<template>
<div class="d-flex flex-wrap justify-space-between">
<div class="d-flex flex-wrap flex-column">
<v-checkbox class="add-checkbox" ref="additionalDetails" v-for="(prop, index) in additionalDetails" type="checkbox" :label="prop.label" :key="index" :dataIndex="index" v-model="prop.checked" @change="setAdditionalDetails(prop)"><template v-slot:label><span class="body-2">{{ prop.label }} </span>
</template></v-checkbox>
</div>
</div>
</template>
<script>
export default {
name: "additional-details",
props: {
value: Object,
},
computed: {
additionalDetails: {
get: function() {
if (this.value.JsonAdditionalFields !== null) {
let res = [];
let parsedJsonAdditionalFields = JSON.parse(
this.value.JsonAdditionalFields
);
for (const [key, value] of Object.entries(
parsedJsonAdditionalFields
)) {
res = [
...res,
{
[key]: value,
checked: value,
label: "label"
},
];
}
return res;
} else {
return [];
}
},
},
},
methods: {
setAdditionalDetails(val) {
let newObject = { ...this.value
};
newObject.JsonAdditionalFields = JSON.parse(
newObject.JsonAdditionalFields
);
newObject.JsonAdditionalFields[Object.keys(val)[0]] = val.checked;
this.value.JsonAdditionalFields = JSON.stringify(
newObject.JsonAdditionalFields
);
},
},
watch: {
additionalDetails: {
handler(newVal) {
console.log("additionalDetails new Value:", newVal);
},
deep: true,
},
},
};
</script>

最新更新