It is a problem with order of execution. The main Vue instance isn't "ready" until the things inside it have been compiled. This includes the hello component.
If you need to know that bar has been set before you use it, you can monitor for that in a couple of ways. You could $broadcast an event in the parent to let the child know that bar has been loaded. Or you could use a watch function in the child component to make changes when bar is updated.
Your example does work if you $set bar in created(), however with vue-resource you're going to have a delay anyway, so you need to account for the fact that greeting won't be ready during the child's ready() function. You'll either have to design your DOM structure to handle the fact that greeting could be undefined, or you'll have to use an event or watch function to wait for it yourself.
Example with $broadcast:
Vue.component('hello', {
template: 'From hello tag: {{ greeting }}',
props: ['greeting'],
ready: function() {
},
events:{
'bar-ready':function(){
alert(this.greeting)
}
}
});
new Vue({
el: '#app',
created: function() {
this.$http.get('/path')
.then(function(response){
this.$set('bar',response.data);
this.$broadcast('bar-ready')
}.bind(this))
}
});
$broadcast docs: https://vuejs.org/api/#vm-broadcast