Vue JS CheckBoxGroup 以 prop 数组作为 v-model
Vue JS CheckBoxGroup with a prop array as v-model
我一直在制作一个带有 prop 数组作为 v-model 的 CheckBoxGroup。
我已经阅读了vuejs指南:https://vuejs.org/v2/guide/forms.html#Checkbox,其中在同一组件的数据中具有v-model数组,但是如果我想让该组件可重用并通过props和插入v-model显然是没有用的例如选中 "outside" 中的一些框。
所以我尝试了以下操作:
CheckBoxgroup.vue
<template>
<div>
<label v-for="day in allDays" :key="day">
<input v-model="checkedDays" type="checkbox" :value="day" />
<span>{{ day }}</span>
</label>
<div>Checked days: {{ checkedDays }}</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
@Component
export default class CheckBoxGroup extends Vue {
@Prop() checkedDays!: string[]
@Prop() allDays!: string[]
}
</script>
Index.vue
<template>
<div>
<checkbox-group :checked-days="checkedDays" :all-days="allDays" />
</div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import CheckboxGroup from './checkBoxGroup.vue'
@Component({
components: { CheckboxGroup },
})
export default class Index extends Vue {
// This list would usually come from an API
allDays = ['Monday', 'Tuesday', 'Wednesday']
checkedDays = ['Monday']
}
</script>
所以代码几乎可以正常工作,但我得到
[Vue warn]: Avoid mutating a prop directly since the value will be
overwritten whenever the parent component re-renders...
有什么办法吗?如有任何帮助,我们将不胜感激。
您不能直接从子级改变父状态,但是您可以将事件从子级发射到父级以从那里改变,如下所示:
Vue.component('check-box-group', {
template: `
<div>
<label v-for="day in allDays" :key="day">
<input
v-model="checkedDays"
:value="day"
@click="$emit('update-checked-days', { newCheckedDay: day })"
type="checkbox"
/>
<span>{{ day }}</span>
</label>
<div>Checked days: {{ checkedDays }}</div>
</div>
`,
props: {
checkedDays: {
type: Array, default: () => ([])
},
allDays: {
type: Array, default: () => ([])
},
}
})
new Vue({
el: "#app",
data() {
return {
allDays: ['Monday', 'Tuesday', 'Wednesday'],
checkedDays: ['Monday']
}
},
methods: {
HandleUpdateCheckedDays({newCheckedDay}) {
const indexOfCheckedDay = this.checkedDays.findIndex(checkedDay => checkedDay === newCheckedDay)
if (indexOfCheckedDay === -1) { // if not exists then add to checkedDays
this.checkedDays.push(newCheckedDay)
} else {
this.checkedDays = this.checkedDays.filter((_, i) => i !== indexOfCheckedDay)
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div id="app">
<check-box-group
:checked-days="checkedDays"
:all-days="allDays"
@update-checked-days="HandleUpdateCheckedDays"
/>
</div>
note: remember that TS class composition is deprecated.
感谢您的回答,我实际上也设法用 v-model 解决了这个问题,但它看起来有点老套,而且如果数据是从外部模型注入的,那么可重用性不高。
所以我会采用你的解决方案。
我一直在制作一个带有 prop 数组作为 v-model 的 CheckBoxGroup。 我已经阅读了vuejs指南:https://vuejs.org/v2/guide/forms.html#Checkbox,其中在同一组件的数据中具有v-model数组,但是如果我想让该组件可重用并通过props和插入v-model显然是没有用的例如选中 "outside" 中的一些框。 所以我尝试了以下操作:
CheckBoxgroup.vue
<template>
<div>
<label v-for="day in allDays" :key="day">
<input v-model="checkedDays" type="checkbox" :value="day" />
<span>{{ day }}</span>
</label>
<div>Checked days: {{ checkedDays }}</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
@Component
export default class CheckBoxGroup extends Vue {
@Prop() checkedDays!: string[]
@Prop() allDays!: string[]
}
</script>
Index.vue
<template>
<div>
<checkbox-group :checked-days="checkedDays" :all-days="allDays" />
</div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import CheckboxGroup from './checkBoxGroup.vue'
@Component({
components: { CheckboxGroup },
})
export default class Index extends Vue {
// This list would usually come from an API
allDays = ['Monday', 'Tuesday', 'Wednesday']
checkedDays = ['Monday']
}
</script>
所以代码几乎可以正常工作,但我得到
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders...
有什么办法吗?如有任何帮助,我们将不胜感激。
您不能直接从子级改变父状态,但是您可以将事件从子级发射到父级以从那里改变,如下所示:
Vue.component('check-box-group', {
template: `
<div>
<label v-for="day in allDays" :key="day">
<input
v-model="checkedDays"
:value="day"
@click="$emit('update-checked-days', { newCheckedDay: day })"
type="checkbox"
/>
<span>{{ day }}</span>
</label>
<div>Checked days: {{ checkedDays }}</div>
</div>
`,
props: {
checkedDays: {
type: Array, default: () => ([])
},
allDays: {
type: Array, default: () => ([])
},
}
})
new Vue({
el: "#app",
data() {
return {
allDays: ['Monday', 'Tuesday', 'Wednesday'],
checkedDays: ['Monday']
}
},
methods: {
HandleUpdateCheckedDays({newCheckedDay}) {
const indexOfCheckedDay = this.checkedDays.findIndex(checkedDay => checkedDay === newCheckedDay)
if (indexOfCheckedDay === -1) { // if not exists then add to checkedDays
this.checkedDays.push(newCheckedDay)
} else {
this.checkedDays = this.checkedDays.filter((_, i) => i !== indexOfCheckedDay)
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div id="app">
<check-box-group
:checked-days="checkedDays"
:all-days="allDays"
@update-checked-days="HandleUpdateCheckedDays"
/>
</div>
note: remember that TS class composition is deprecated.
感谢您的回答,我实际上也设法用 v-model 解决了这个问题,但它看起来有点老套,而且如果数据是从外部模型注入的,那么可重用性不高。 所以我会采用你的解决方案。