Emulate render props in Vuejs

Render props explained

React has a nice pattern to reuse code, it’s called render-props. This pattern allow the developer to elegantly replace the popular High Order Component. We can imagine a component that take a promise as a props and that render a component when the promise is pending, another component when the promise is fulfilled and another when the promise is rejected.

const AsyncHOC = HOCAsyncConstructor(promise)(onPending, onFulFilled, onRejected); 

What we learnt from react

React come with a pattern named: Render props.

<Async 
promise="promise"
onPending={() => (<div> Pending... </div)}
onFulFilled={(value) => (<div> {value} </div>)}
onRejected={(error) => (<div> {error} </div>)} />

Use this pattern with scoped slots in vue

Since this pattern is easy to produce with react (jsx). It not goes well with vue templates. But we can use scoped slot to emulate the behavior very easily.

<template>
<div>
<slot name="onFulFilled" :value="value" v-if="value !== null" />
<slot name="onRejected" :error="error" v-else-if="error !== null" />
<slot name="onPending" v-else /> </div>
</template>
  • onRejected used when the promise is rejected
  • onPending used when the promise is pending
<script>
export default {
props: ['promise'],

mounted() {
this.promise
.then(value => this.value = value)
.catch(error => this.error = error);
}, data: () => ({
value: null,
error: null
})
};
</script>
<Async :promise=mypromise>  <template slot="onFulFilled" slot-scope="props">
<div> Promise is resolved with value: {props.value} </div>
</template>
<template slot="onRejected" slot-scope="props">
<div> Promise is rejected with error: {props.error} </div>
</template>
<template slot="onPending">
<div> Pending... </div>
</template>
</Async>