I have an options prop in my Vue component that has a default value.
export default {
props: {
options: {
required: false,
type: Object,
default: () => ({
someOption: false,
someOtherOption: {
a: true,
b: false,
},
}),
},
},
};
If the options object is passed as a prop to the component, the default value is replaced. For example, when passed { someOption: true }
, now the options object contains only that value.
How can I pass a partial object and override the default values with the given values instead of replacing the whole object?
I've encountered a similar problem recently and used Object.assign
Here is the docs from mozilla https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
A concrete usage of your case would be something like that:
props: {
options: {
required: false,
type: Object,
default: () => ({}),
},
},
data(){
mergedOptions:{},
defaultOptions:{
someOption: false,
someOtherOption: {
a: true,
b: false,
},
}
},
mounted(){
//you will have the combined options inside mergedOptions
Object.assign(this.mergedOptions,this.defaultOptions,this.options)
}
By doing this, you will override only the properties that passed via props. Don't know if it's the most efficient way but it's very understandable and neat :)
So if you pass in as props :options={someOption:true}
the merged options will be equivalent to:
{
someOption: true,
someOtherOption: {
a: true,
b: false,
},
}
EDIT: If you need your data to be reactive, you might want to have a computed.
computed: {
mergedOptions(){
return {
...this.defaultOptions,
...this.options
}
}
}
You will actually never want to modify props within components. If you do, you break one-way-dataflow of parent/child components and your code will be hard to reason about what is affecting what.
Lifted right from the Vue docs, the correct solution is to either (1) use an initial prop or (2) a computed value, so your app can be reactive and respect parent components, and you can rest easy and kick your feet up :)
Both solutions assume your template will use opts for options...
Solution 1: Use an initial prop (defaults and options):
props: ['options', 'defaults'],
data: function () {
var opts = {}
Object.assign(opts, this.defaults, this.options)
return {
opts: opts
}
}
Solution 2: Define a computed property so your component can react to prop changes:
props: ['options', 'defaults'],
computed: {
opts: function () {
let opts = {}
Object.assign(opts, this.defaults, this.options)
return opts
}
}
A quick thought experiement will show, if a parent component changes your input props, your component can properly react.
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