I found out that having a property, in this case with the type Object, doesnt execute the default() method.
taken this component:
<style>
#item {
width: 98%;
padding: 10px;
}
#itemBody {
width: 99%;
}
</style>
<template>
<div id="item">
<h1>{{item.title}}</h1>
<div id="itemBody" v-html="item.body | marked"></div>
</div>
</template>
<script>
import marked from '../libs/marked'
export default {
props: {
item: {
type: Object,
default () {
return {
title: 'Please select a item from the left to view details.',
body: '# hello'
}
}
}
},
filters: {
marked: marked
}
}
</script>
Please note that i already tried the old way of calling default with a anonymous function to rule out babel having a bad day.
Where you can see i have a props called item that i call from the parent <app> template like this:
<item-detail v-bind:item.sync="currentItem"></item-detail>
currentItem is then again filled though a $dispatch event from the items component, that looks like so:
<style scoped>
.item {
margin: 5px;
padding: 10px;
background-color: #fff;
min-height: 80px;
}
.item:hover {
cursor: pointer;
}
</style>
<template>
<div id="base">
Showing x of y items
<div class="item" v-for="item in items" v-on:click="fireSelectedItem($index)">
<h4>{{item.title}}</h4>
<p>{{item.body}}</p>
</div>
</div>
</template>
<script>
export default {
data () {
return {
items: [
{title: 'nice title 1', body: 'A body indeed!'},
{title: 'nice title 2', body: 'A body indeed 2!'}
]
}
},
methods: {
fireSelectedItem (index) {
this.$dispatch('detailItem', this.items[index])
}
}
}
</script>
The result i expected was that the itemDetail would use the function default () of property item on initial load, but instead the whole page stays blank (although webpack says the bundle is valid) and in the Vue devtools i noticed that it says item is empty for the itemDetails component...
Is there a piece of the puzzle missing here? if so, could somebody be so kind to enlighten me?
The way i worked around this now is that i used the created method on the items component to $dispatch the first object in the array items
The version of Vue i am using is: 1.0.15
I hope this makes sense, i tried doing this in a jsfiddle but got frustrated with it.
The default value is only used if the prop is not present in the template. If a value is passed, even it's undefined it will overwrite the default.
For your use case you can use the coerce function instead.
Just to set my mind straight:
the use case for the default method is when the property is not defined (missing)
the use case for coerce method is when the property is defined but its value is undefined (or falsy?)
Thanks for you time.
coerce is simply a hook that allows the child component to cast the value before it's set. It does not matter if the value is falsy.
Apologies for bringing an old thread back to life, but I'm having the same issue in V2, but coerce seems to have been removed. If I'm conditionally passing a string as a prop that I want to have a default of, what's the best way to do that, computed or default within a prop?
You're correct @robsterlini - coerce was remove in V2. The migration guide suggests an alternative:
https://vuejs.org/v2/guide/migration.html#coerce-Prop-Option-removed
Most helpful comment
The default value is only used if the prop is not present in the template. If a value is passed, even it's
undefinedit will overwrite the default.For your use case you can use the
coercefunction instead.