
vue
🚀
laravel
🚀
VueJS and sharing modelValue state with a Component
Thanks to the code that comes with Laravel Jetstream we have examples of components that can be easily used in multiple forms.
For example I can use the shared Label, Input, InputError
<!--more--><div class="col-span-6">
<Label for="password" value="Password"/>
<Input id="password" type="text"
class="mt-1 block w-full"
v-model="form.user.password"
autofocus
placeholder="leave empty to not update"
autocomplete="off"/>
<InputError class="mt-2" :message="form.errors['user.password']"/>
</div>
And get all the updates in the component I am using it in. Looking into the shared component, Input in this example.
<script setup>
import { onMounted, ref } from 'vue';
defineProps({
modelValue: String,
});
defineEmits(['update:modelValue']);
const input = ref(null);
onMounted(() => {
if (input.value.hasAttribute('autofocus')) {
input.value.focus();
}
});
defineExpose({ focus: () => input.value.focus() });
</script>
<template>
<input
ref="input"
class="border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
</template>
Which means my component Edit.vue which has form.user.password will get updated as the person types into the field of the child component.
Here is another example of a select list:
<template>
<select
v-model="modelValue"
@change="$emit('update:modelValue', $event.target.value)"
class="w-full">
<option v-for="option in options" :for="option.id"
:value="option.id">
{{ option.name }}
</option>
</select>
</template>
<script>
export default {
name: "TeamSelect",
props: {
modelValue: String,
options: Object
},
}
</script>
<style scoped>
</style>
It is using the modelValue shared state that can then be emitted on change. This is seen in the VueJs docs here and in a good Laracast Videos here