vuejs 将复选框数组传递给父模板只是传递一个值 [英] vuejs passing array of checkboxes to parent template is only passing one value

查看:32
本文介绍了vuejs 将复选框数组传递给父模板只是传递一个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我查看了这方面的潜在欺骗,例如这个 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆