JSFiddle - React, Tailwind, and code Playground
by skirtle
HTML
<script src="https://unpkg.com/[email protected]/dist/vue.global.js"></script>
<div id="app">
<div v-for="i in 3" :key="i">
<input type="radio" v-model="id" :value="i"> {{ i }}
</div>
<details-panel :product-id="id"></details-panel>
</div>
CSS
.panel {
border: 1px solid #ccc;
margin: 10px;
}
JavaScript
const DetailsPanel = {
template: `
<div class="panel">
{{ track() }}
<div><button @click="expanded = !expanded">Toggle Details</button></div>
<div v-if="expanded">
<div v-if="product">
<p><strong>Name:</strong> {{ product.name }}</p>
<p><strong>Size:</strong> {{ product.size }}</p>
</div>
<div v-else>
Loading...
</div>
</div>
</div>
`,
props: ['productId'],
data () {
return {
expanded: false,
productCache: {}
}
},
computed: {
product () {
return this.productCache[this.productId]
}
},
methods: {
track () {
console.log('track')
return ''
}
},
watch: {
productId: {
flush: 'pre',
immediate: true,
handler () {
const cache = this.productCache
const productId = this.productId
const product = cache[productId]
if (cache[productId]) {
return
}
// Pretend HTTP request
setTimeout(() => {
cache[productId] = {
name: 'Product ' + productId,
size: 'SML'.charAt(productId - 1)
}
}, 1000)
}
}
}
}
Vue.createApp({
components: {
DetailsPanel
},
data () {
return {
id: 1
}
}
}).mount('#app')