I have 3 select boxes, and I would like them to reset a certain field on select. How can I make it dynamic, so that it is reusable?
Here's an excerpt of my code:
v-on:select="getDate('{{ route('api.v1.get.date') }}', 'input1', ['form.company.input2', 'form.company.input3'], $event)"
getDate(url, obj, obj2, event){
let current = this
current[obj] = ''
current[obj2[0]] = ''
current[obj2[1]] = ''
}
When obj
is at the root level of the Vue instance (i.e., current[obj]
), it sets the property correctly; but not when obj
is a nested object.
In JavaScript, property accessors do not allow nested object paths, which is what you have in the dot-separated string. By using that string, you're actually creating a property on the root Vue instance instead of setting a nested property, similar to this:
this['form.company.input2'] = '' // XXX: creates `form.company.input2` prop
this.form.company.input2 = '' // sets `input2`
To set the object value by path, you could create a method that uses the object path to navigate the current Vue instance's data properties via this
:
methods: {
getDate(url, obj, obj2, event) {
this.setValue(obj, '')
this.setValue(obj2[0], '')
this.setValue(obj2[1], '')
},
setValue(path, value) {
let obj = this
const parts = path.split('.')
while (parts.length > 1 && obj.hasOwnProperty(parts[0])) {
obj = obj[parts.shift()]
}
obj[parts[0]] = value
}
}
new Vue({
el: '#app',
data() {
return {
input1: 'input1',
form: {
company: {
input2: 'input2',
input3: 'input3'
}
}
}
},
methods: {
getDate(url, obj, obj2, event) {
this.setValue(obj, '')
this.setValue(obj2[0], '')
this.setValue(obj2[1], '')
},
setValue(path, value) {
let obj = this
const parts = path.split('.')
while (parts.length > 1 && obj.hasOwnProperty(parts[0])) {
obj = obj[parts.shift()]
}
obj[parts[0]] = value
},
route(prop) {
return prop
}
}
})
<script src="https://unpkg.com/vue@2.6.10"></script>
<div id="app">
<input v-model="input1">
<input v-model="form.company.input2">
<input v-model="form.company.input3">
<button @click="getDate(route('api.v1.get.date'), 'input1', ['form.company.input2', 'form.company.input3'], $event)">
Reset data
</button>
</div>
Alternatively, you could use a library (such as lodash
's _.set
):
methods: {
getDate(url, obj, obj2, event) {
_.set(this, obj, '')
_.set(this, obj2[0], '')
_.set(this, obj2[1], '')
}
}
new Vue({
el: '#app',
data() {
return {
input1: 'input1',
form: {
company: {
input2: 'input2',
input3: 'input3'
}
}
}
},
methods: {
getDate(url, obj, obj2, event) {
_.set(this, obj, '')
_.set(this, obj2[0], '')
_.set(this, obj2[1], '')
},
route(prop) {
return prop
}
}
})
<script src="https://unpkg.com/lodash@4.17.11/lodash.js"></script>
<script src="https://unpkg.com/vue@2.6.10"></script>
<div id="app">
<input v-model="input1">
<input v-model="form.company.input2">
<input v-model="form.company.input3">
<button @click="getDate(route('api.v1.get.date'), 'input1', ['form.company.input2', 'form.company.input3'], $event)">
Reset data
</button>
</div>
Try to use this.$set
function as follows:
this.$set(current,obj,'');
this.$set(current,obj2[0],'');
this.$set(current,obj2[1],'');
learn more about that function here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With