JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<div id="app">
  <v-counter v-model="B" name="B" :min="0" :max="5"></v-counter>
  <v-counter v-model="Q" name="Q" :min="0" :max="3"></v-counter>
  <component
    v-if="component"
    :is="component.name"
    v-bind="component.props"
  ></component>
</div>

CSS

* {
  font-family: monospace;
}

JavaScript

Vue.component('c1', {
  template: `<div :style="{ color }">component 1</div>`,
  props: [ 'color' ],
});

Vue.component('c2', {
  template: `<div :style="{ fontSize }">component 2</div>`,
  props: [ 'fontSize' ],
});

Vue.component('c3', {
  template: `<div :style="{ letterSpacing, border }">component 3</div>`,
  props: [ 'letterSpacing', 'border' ],
});

Vue.component('c4', {
  template: `<div :style="{ backgroundColor, padding }">component 4</div>`,
  props: [ 'backgroundColor', 'padding' ],
});


Vue.component('v-counter', {
  template: `
<div>
  {{ name }}:
  <button @click="$emit('input', value - 1)" :disabled="value <= min">-</button>
  {{ value }}
  <button @click="$emit('input', value + 1)" :disabled="value >= max">+</button>
</div>`,
  props: [ 'value', 'name', 'min', 'max' ],
});

new Vue({
  el: '#app',
  data: {
    components: [
      { name: 'c1', props: { color: 'red' } },
      { name: 'c2', props: { fontSize: '32px' } },
      { name: 'c3', props: { letterSpacing: '15px', border: '2px solid lime' } },
      { name: 'c4', props: { backgroundColor: 'yellow', padding: '20px' } }
    ],
    Q: 2,
    B: 1,
  },
  computed: {
    component() {
      return [ 1, 2 ].includes(this.Q) && this.components[this.B - 1];
    },
  },
});