How can I show data in a component instead of composable in Vue js?
Problem
I'm facing an issue with Vuejs 3 composables. Trying to make a single composable for each of three inputs - the email type input and the text type inputs. I can't visualize the email typed in the button component template. Even though I'm importing the composable hook js file to the button the same way as to the input components. I just can't get how to get the input data to display it. The same kind of issue is how actually to send the collected input data to the parent component for submitting the form as I'm using the composable component itself. Could anyone help, please?
useInputComposable
import { ref } from 'vue'
export function useInput() { const input = ref('') let passed = ref('') function updateInput(newInput) { input.value = newInput } return [ input, updateInput ] } |
Parent component
<template> <TextInput /> <TextInput /> <EmailInput /> <Buttoncomponent /> </template> |
Text type input
<script setup> import { useInput } from '@/composables/useInput.js' const [input, updateInput] = useInput() </script>
<template> <div> <label for="input">{{ input }}</label> <input id="input" type="text" :value="input" @input="updateInput($event.target.value)" /> </div> </template> |
Email type input
<script setup> import { useInput } from '@/composables/useInput.js' const [input, updateInput] = useInput() </script>
<template> <div class="input"> <input id="input" type="email" :value="input" @input="updateEmailInput($event.target.value)" /> </div> </template> |
Button component
<script setup> import { useInput } from '@/composables/useInput.js' const [ input ] = useInput() </script>
<template> <button>{{ input }} place the email here</button> <!-- the input is empty here ('') --> </template> |
Solution
Using a composable here is unnecessary and more complicated than it should be. Change from using a composable to >v-model to two-way bind data in child components to the parent component. It's much more appropriate for what you're doing
Parent component
<script setup> import TextInput from './TextInput.vue'; import EmailInput from './EmailInput.vue'; import ButtonComponent from './ButtonComponent.vue'; import { ref } from 'vue'
const email = ref('') const input1 = ref('') const input2 = ref('') </script>
<template> <TextInput v-model="input1" /> <TextInput v-model="input2" /> <EmailInput v-model="email" /> <ButtonComponent :email="email" /> </template> |
TextInput
<script setup> defineProps(['modelValue']) defineEmits(['update:modelValue']) </script>
<template> <div> <label for="input">{{ modelValue }}</label> <input id="input" type="text" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </div> </template> |
EmailInput
<script setup> defineProps(['modelValue']) defineEmits(['update:modelValue']) </script>
<template> <div class="input"> <input id="input" type="email" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </div> </template> |
ButtonComponent
<script setup> defineProps(['email']) </script>
<template> <button>{{ email }}</button> </template> |
>Vue Playground example
Suggested blog
>Create a project using Vue.js: Beginners Guide
>Authentication with Vue 3 and Firebase
>Plugins and Presets for Vuejs project
>Create a Vue.js application with CLI Services
>Create a project using Vue.js: Beginners Guide
>Create Vue.js application API