Javascript vuejs将复选框数组传递给父模板仅传递一个值
我看了一些潜在的重复,比如这个,但它不一定能解决我的问题 我的场景是,我有一个带有标签和复选框的orgs组件连接到一个v型模型。该组件将与其他表单组件组合使用。目前,它可以工作-但即使单击了两个复选框,它也只能将一个值传递回父级 表单页面:Javascript vuejs将复选框数组传递给父模板仅传递一个值,javascript,vue.js,Javascript,Vue.js,我看了一些潜在的重复,比如这个,但它不一定能解决我的问题 我的场景是,我有一个带有标签和复选框的orgs组件连接到一个v型模型。该组件将与其他表单组件组合使用。目前,它可以工作-但即使单击了两个复选框,它也只能将一个值传递回父级 表单页面: <template> <section> <h1>Hello</h1> <list-orgs v-model="selectedOrgs"></list-orgs>
<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>
在另一端,我只是console.log()返回。这“有效”,但有一个缺点,似乎$emit是在selectedOrgs的值更新之前被激发的,所以它总是落后一个“检查”。实际上,我希望emit等待$data对象被更新,这可能吗?表单绑定中的
v-model
文档仍然适用于自定义组件,如下所示:
v-model本质上是用于更新用户输入数据的语法
事件
及
所以在你的代码中
<list-orgs v-model="selectedOrgs"></list-orgs>
这是非常基本的,没有经过测试,但应该会让你知道如何解决这个问题。非常感谢@puelo的帮助,它帮助澄清了一些问题,但不一定解决了我的问题。因为我想要的是在填充数组的复选框上的
v-model
的简单性,然后在保持封装的同时将其传递给父级
所以,我做了一个小小的改变:
选择组织组件
<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>
<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>
-
{{org.name}
从“@/数据库”导入{db}
导出默认值{
名称:'ListOrgs',
数据:()=>{
返回{
组织:[]
}
},
方法:{
populateOrgs:异步函数(vueObj){
等待db.orgs.toCollection().toArray(函数(orgs){
orgs.forEach(组织=>{
vueObj.$data.orgs.push(org)
})
})
},
updateOrgs:函数(){
此.$emit('updateOrgs',此.$data.selectedOrgs)
}
},
挂载(){
这个。人口组织(这个)
}
}
表单页面
<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>
你好
提交
//eslint禁用下一行
从“@/Database.js”导入数据库
从“@/components/controls/list orgs”导入列表组织
导出默认值{
名称:“CreateDb”,
数据:函数(){
返回{
已选择的目标:[]
}
},
组成部分:{
“列表组织”:列表组织
},
方法:{
updateSelectedOrgs:函数(组织){
console.log(org)
},
提交:函数(){
console.log(此.$data)
}
}
}
这里的主要变化是,我现在在单击复选框时触发一个updateOrgs
方法,并通过this.$emit('updateOrgs',this.$data.selectedOrgs)传递整个selectedOrgs
数组`
这利用了v-model维护阵列的优势,无论是否检查它们。然后在表单页面上,我只需使用
v-on:updateOrgs=“updateSelectedOrgs”
在组件上侦听此事件,该组件包含填充的数组并维护封装。Ugh,那么您知道向上传递所选数组或从父级获取它的简单方法吗(讽刺的是,这破坏了封装)我添加了一个可能的解决方案。我选择了一个类似的路线,但仍然使用v-model,因为它会自动处理选中或不选中的状态,因为最终我只希望数组包含选中的项。不过我遇到了另一个问题,我会在一分钟内更新我的问题。Nm,我想出来了-如果您将:input更改为:change,它会在数据对象更新后触发发射不确定是否可能,但从技术上来说,你的答案有点帮助,但不是最好的解决方案——有没有一种方法可以让你帮我打分,但写下我觉得效果最好的答案?
onOrgSelectionChanged: function (orgState) {
const index = selectedOrgs.findIndex((org) => { return org.id === orgState.id })
if (index >= 0) selectedOrgs.splice(index, 1, orgState)
else selectedOrgs.push(orgState)
}
<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>