vuejs 将复选框数组传递给父模板只是传递一个值 [英] vuejs passing array of checkboxes to parent template is only passing one value
问题描述
我查看了这方面的潜在欺骗,例如这个 one 并不一定能解决我的问题.
I looked at potential dupes of this, such as this one and it doesn't necessarily solve my issue.
我的场景是我有一个带有标签和复选框的组织组件附加到 v-model.该组件将与其他表单组件结合使用.目前,它可以工作 - 但即使点击了两个复选框,它也只会将一个值传回父级.
My scenario is that I have a component of orgs with label and checkbox attached to a v-model. That component will be used in combination of other form components. Currently, it works - but it only passes back one value to the parent even when both checkboxes are click.
表单页面:
<template>
<section>
<h1>Hello</h1>
<list-orgs v-model="selectedOrgs"></list-orgs>
<button type="submit" v-on:click="submit">Submit</button>
</section>
</template>
<script>
// eslint-disable-next-line
import Database from '@/database.js'
import ListOrgs from '@/components/controls/list-orgs'
export default {
name: 'CreateDb',
data: function () {
return {
selectedOrgs: []
}
},
components: {
'list-orgs': ListOrgs,
},
methods: {
submit: function () {
console.log(this.$data)
}
}
}
</script>
选择组织组件
<template>
<ul>
<li v-for="org in orgs" :key="org.id">
<input type="checkbox" :value="org.id" name="selectedOrgs[]" v-on:input="$emit('input', $event.target.value)" />
{{org.name}}
</li>
</ul>
</template>
<script>
import {db} from '@/database'
export default {
name: 'ListOrgs',
data: () => {
return {
orgs: []
}
},
methods: {
populateOrgs: async function (vueObj) {
await db.orgs.toCollection().toArray(function (orgs) {
orgs.forEach(org => {
vueObj.$data.orgs.push(org)
})
})
}
},
mounted () {
this.populateOrgs(this)
}
}
</script>
目前数据库中有两个假组织,ID 分别为 1 和 2.在单击两个复选框并单击提交按钮后, selectedOrgs 数组只包含 2,就好像第二次点击实际上覆盖了第一个.我已经通过只选中一个框并点击提交并传递了 1 或 2 的值来验证这一点.似乎数组方法适用于组件级别,但不适用于组件到父级.
Currently there are two fake orgs in the database with an ID of 1 and 2. Upon clicking both checkboxes and clicking the submit button, the selectedOrgs array only contains 2 as though the second click actually over-wrote the first. I have verified this by only checking one box and hitting submit and the value of 1 or 2 is passed. It seems that the array method works at the component level but not on the component to parent level.
感谢任何帮助.
更新
感谢 puelo 的评论,我切换了我的 orgListing 组件以发出附加到 v-model 的数组,如下所示:
Thanks to the comment from puelo I switched my orgListing component to emit the array that is attached to the v-model like so:
export default {
name: 'ListOrgs',
data: () => {
return {
orgs: [],
selectedOrgs: []
}
},
methods: {
populateOrgs: async function (vueObj) {
await db.orgs.toCollection().toArray(function (orgs) {
orgs.forEach(org => {
vueObj.$data.orgs.push(org)
})
})
},
updateOrgs: function () {
this.$emit('updateOrgs', this.$data.selectedOrgs)
}
},
mounted () {
this.populateOrgs(this)
}
}
然后在另一端我只是 console.log() 返回.这有效"但有一个缺点,似乎 $emit 在 selectedOrgs 的值被更新之前被触发,所以它总是一个检查".实际上,我希望发射等到 $data 对象被更新,这可能吗?
Then on the other end I am merely console.log() the return. This "works" but has one downside, it seems that the $emit is being fired before the value of selectedOrgs has been updated so it's always one "check" behind. Effectively,I want the emit to wait until the $data object has been updated, is this possible?
推荐答案
非常感谢 @puelo 的帮助,它帮助澄清了一些事情,但不一定能解决我的问题.我想要的是 v-model
在填充数组的复选框上的简单性,然后在保持封装的同时将其传递给父级.
Thank you so much to @puelo for the help, it helped clarify some things but didn't necessarily solve my problem. As what I wanted was the simplicity of v-model
on the checkboxes populating an array and then to pass that up to the parent all while keeping encapsulation.
所以,我做了一个小改动:
So, I made a small change:
选择组织组件
<template>
<ul>
<li v-for="org in orgs" :key="org.id">
<input type="checkbox" :value="org.id" v-model="selectedOrgs" name="selectedOrgs[]" v-on:change="updateOrgs" />
{{org.name}}
</li>
</ul>
</template>
<script>
import {db} from '@/database'
export default {
name: 'ListOrgs',
data: () => {
return {
orgs: []
}
},
methods: {
populateOrgs: async function (vueObj) {
await db.orgs.toCollection().toArray(function (orgs) {
orgs.forEach(org => {
vueObj.$data.orgs.push(org)
})
})
},
updateOrgs: function () {
this.$emit('updateOrgs', this.$data.selectedOrgs)
}
},
mounted () {
this.populateOrgs(this)
}
}
</script>
表单页面
<template>
<section>
<h1>Hello</h1>
<list-orgs v-model="selectedOrgs" v-on:updateOrgs="updateSelectedOrgs"></list-orgs>
<button type="submit" v-on:click="submit">Submit</button>
</section>
</template>
<script>
// eslint-disable-next-line
import Database from '@/database.js'
import ListOrgs from '@/components/controls/list-orgs'
export default {
name: 'CreateDb',
data: function () {
return {
selectedOrgs: []
}
},
components: {
'list-orgs': ListOrgs
},
methods: {
updateSelectedOrgs: function (org) {
console.log(org)
},
submit: function () {
console.log(this.$data)
}
}
}
</script>
这里的主要变化是我现在在单击复选框时触发 updateOrgs
方法,并通过 this.$emit('updateOrgs', this.$data.selectedOrgs)`
What the primary change here is I now fire a method of updateOrgs
when the checkbox is clicked and I pass the entire selectedOrgs
array via the this.$emit('updateOrgs', this.$data.selectedOrgs)`
这利用了 v-model 维护是否检查它们的数组.然后在表单页面上,我只是使用 v-on:updateOrgs="updateSelectedOrgs"
在组件上监听这个事件,它包含填充的数组并维护封装.
This takes advantage of v-model maintaining the array of whether they're checked or not. Then on the forms page I simply listen for this event on the component using v-on:updateOrgs="updateSelectedOrgs"
which contains the populated array and maintains encapsulation.
这篇关于vuejs 将复选框数组传递给父模板只是传递一个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!