// App.vue
<template>
  <div id="app">
    <h3>App</h3>
    <input type="text" v-model="query" />
    <hr />
    <h3>komponenta A</h3>
    <A v-model="query" />
  </div>
</template>

<script>
import A from './components/A';

export default {
  name: 'App',
  components: {
    A,
  },
  data() {
    return {
      query: '',
    };
  },
};
</script>


// A.vue
<template>
  <div>
    <input type="text" v-model="computedQuery" />
    <hr />
    <h3>komponenta B</h3>
    <B v-model="computedQuery" />
  </div>
</template>

<script>
import B from './B';
import ComputedModel from '../mixins/ComputedModel';
export default {
  name: 'A',
  mixins: [ComputedModel],
  components: {
    B,
  },
};
</script>


// B.vue
<template>
  <div>
    <input type="text" v-model="computedQuery" />
    <hr />
    <h3>komponenta C</h3>
    <C v-model="computedQuery" />
  </div>
</template>

<script>
import C from './C';
import ComputedModel from '../mixins/ComputedModel';
export default {
  name: 'B',
  mixins: [ComputedModel],
  components: {
    C,
  },
};
</script>


// C.vue
<template>
  <div>
    <input type="text" v-model="computedQuery" />
  </div>
</template>

<script>
import ComputedModel from '../mixins/ComputedModel';
export default {
  name: 'C',
  mixins: [ComputedModel],
};
</script>


// ComputedModel.js - mixin
export default {
  emits: ['update:modelValue'],
  props: ['modelValue'],
  computed: {
    computedQuery: {
      get() {
        return this.modelValue;
      },
      set(val) {
        this.$emit('update:modelValue', val);
      },
    },
  },
};