Search code examples
vuejs3vuetify.js

How to emit one way data binding in vuetify 3


could you expose an example on how to emit the input text introduced by the user in child component to a parent component with vuetify 3.4.3 with one way data binding? here is my example doing it with two ways data bindings (using v-text-field from vuetify) visiting vuetify and vue:

Parent =>

<script setup lang="ts">
import { ref } from "vue";
let texto = ref<string>("")
</script>
<template>
<buscador v-model="texto" />
</template>

Child =>

<script setup lang="ts">
    import { ref } from "vue";
    let texto = ref<string>("");
    const props = defineProps<{
        modelValue: string;
    }>();
const emits = defineEmits<{
        (evento: "update:modelValue", value: string): void;
    }>();
    function emitir() {
        if (texto.value.length > 3) {
            emits("update:modelValue", texto.value);
        }
    }
</script>
<template>
            <v-text-field
                @update:modelValue="
                    ($event) => {
                        texto = $event;
                        emitir();
            }">
            </v-text-field>
    </template>

Solution

  • Why you use v-model in component on parent??

    You have done the intimation correctly in the child component, what you forgot is to capture the events sent from the component on the page/component that uses it.

    The way one way binding works is that the child can send data to the page component that uses it or what we usually call the parent component.

    To do this we can call the emit function in the child component, the first parameter is the name of the method for emit and the second is the value that we want to send.

    In the parent component we have to capture the value sent from emit using the @emitname syntax. In the emit name you can use a callback and use the v parameter and enter the value into the ref in the parent component.

    At child component change to like this.

    <script setup lang="ts">
      import { ref } from "vue";
    
      // create ref for store input value
      let texto = ref<string>("");
    
      const emits = defineEmits<{
          (evento: "update:modelValue", value: string): void;
      }>();
    
      function emitir() {
          if (texto.value.length > 3) {
              emits("update:modelValue", texto.value);
          }
      }
    </script>
    <template>
      <v-text-field v-model="texto" @input="emitir"></v-text-field>
    </template>
    

    And catch value from child component in parent component like this.

    <template>
      <v-app>
        <v-container>
          <Buscador @update:modelValue="(v) => texto = v" />
          <h1>Text from child component: {{ texto }}</h1>
        </v-container>
      </v-app>
    </template>
    
    <script setup>
      import { ref } from 'vue'
      import Buscador from './Buscador.vue'
    
      const texto = ref('')
    </script>