我查看了诸如此类的one这样的潜在虚假信息,但不一定能解决我的问题。
我的情况是我有一个带有标签和复选框附加到v模型的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>
选择组织组件
<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,就好像第二次单击实际上是重写了第一次单击一样。我已经通过仅选中一个复选框并单击Submit验证了这一点,并传递了1或2的值。数组方法似乎可以在组件级别上使用,而不能在父级组件上使用。
感谢您的帮助。
更新
由于来自puelo的评论,我切换了orgListing组件以发出附加到v模型的数组,如下所示:
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的值被更新之前就已经被触发了,因此它总是落后于一个“检查”。实际上,我希望emission等待$ data对象已更新,这可能吗?
答案 0 :(得分:1)
v-model
的表单绑定文档仍然适用于自定义组件,如:
v-model本质上是语法糖,用于更新用户输入上的数据 事件...
https://vuejs.org/v2/guide/forms.html#Basic-Usage和 https://vuejs.org/v2/guide/components-custom-events.html#Customizing-Component-v-model
所以在您的代码中
<list-orgs v-model="selectedOrgs"></list-orgs>
被翻译为:
<list-orgs :value="selectedOrgs" @input="selectedOrgs = $event.target.value"></list-orgs>
这意味着v-on:input="$emit('input', $event.target.value)
内部的每个发射实际上仅使用单个值(即复选框的状态)覆盖数组。
编辑以解决评论:
也许根本不使用v-model
,而只收听@orgSelectionChange="onOrgSelectionChanged"
之类的事件。
然后,您可以发出一个带有复选框状态和组织ID的对象(以防止重复):
v-on:input="$emit('orgSelectionChanged', {id: org.id, state: $event.target.value})"
最后,另一端的方法检查重复项:
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)
}
这是非常基础的,未经测试,但是应该让您了解如何解决此问题。
答案 1 :(得分:0)
非常感谢@puelo的帮助,它有助于澄清一些问题,但不一定能解决我的问题。我想要的是在填充数组的复选框上v-model
的简单性,然后将其全部传递给父级,同时保持封装。
所以,我做了一个小小的改变:
选择组织组件
<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>
这里的主要变化是,当我单击复选框并通过this。$ emit('updateOrgs',this。$传递整个updateOrgs
数组时,我现在启动一种selectedOrgs
方法。 data.selectedOrgs)`
这利用了v模型维护是否检查数组的优势。然后,在表单页面上,我只需使用v-on:updateOrgs="updateSelectedOrgs"
来侦听组件上的此事件,该事件包含已填充的数组并保持封装。