Reputation: 9644
I have a Vuejs component that edits various properties of its value object and emits an input event with a new object when things change. I don't want to modify the value object itself so I copy properties into data and I have essentially the same code in a watch on value to update them when the value changes.
It would be very much simpler if the value could just be cloned when set. Is there any way to do this? I know I can do this in the "calling" component but it shouldn't have to do that.
Example:
<template>
<div>
<v-checkbox label="Indoor" v-model="value.indoor" @change="onChange"/>
<v-checkbox label="Outdoor" v-model="value.outdoor" @change="onChange"/>
</div>
</template>
<script>
export default {
name: 'OptionsInput',
props: {
value: Object, // has indoor, outdoor properties
},
methods: {
onChange() { this.$emit('input', this.value) }
}
}
</script>
I don't want to modify value directly.
Upvotes: 1
Views: 2038
Reputation: 3353
In the example below when the component instance is created the clone
object will retain the initial content of value
.
<template>
<div>
<v-checkbox label="Indoor" v-model="clone.indoor" @change="onChange"/>
<v-checkbox label="Outdoor" v-model="clone.outdoor" @change="onChange"/>
</div>
</template>
<script>
export default {
name: 'OptionsInput',
props: {
value: Object, // has indoor, outdoor properties
},
data () {
return {
clone: Object.assign({}, this.value)
}
},
methods: {
onChange() { this.$emit('input', this.clone) }
}
}
</script>
Upvotes: 0
Reputation: 9644
Making a copy via a computed property works. If the value changes then a new copy will be made. Much easier than copying everything into data and having to watch value for changes.
<template>
<div>
<label><input type="checkbox" v-model="copy.indoor" @change="onChange"/> Indoor</label>
<label><input type="checkbox" v-model="copy.outdoor" @change="onChange"/> Outdoor</label>
</div>
</template>
<script>
export default {
name: 'OptionsInput',
props: {
value: Object, // has indoor, outdoor properties
},
computed: {
copy() { return {...this.value} }
},
methods: {
onChange() { this.$emit('input', this.copy) }
}
}
</script>
Upvotes: 2