Javascript vuejs将复选框数组传递给父模板仅传递一个值

Javascript vuejs将复选框数组传递给父模板仅传递一个值,javascript,vue.js,Javascript,Vue.js,我看了一些潜在的重复,比如这个,但它不一定能解决我的问题 我的场景是,我有一个带有标签和复选框的orgs组件连接到一个v型模型。该组件将与其他表单组件组合使用。目前,它可以工作-但即使单击了两个复选框,它也只能将一个值传递回父级 表单页面: <template> <section> <h1>Hello</h1> <list-orgs v-model="selectedOrgs"></list-orgs>

我看了一些潜在的重复,比如这个,但它不一定能解决我的问题

我的场景是,我有一个带有标签和复选框的orgs组件连接到一个v型模型。该组件将与其他表单组件组合使用。目前,它可以工作-但即使单击了两个复选框,它也只能将一个值传递回父级

表单页面:

<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>