First let's install laravel with inertia JS and vue 3.
composer create-project laravel/laravel appname
cd appname
composer require laravel/jetstream
php artisan jetstream:install inertia
npm install
npm run build
php artisan migrate
These instructions are taken from official Jetstream installation page.
And after that got to this directory, resources\js\Components
You will see lot of components. Check on TextInput.vue.
<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-500 focus:ring-indigo-500 rounded-md shadow-sm"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
</template>
This is how we call it.
<TextInput id="title" class="w-full" v-model="form.title" placeholder="Give it a great title…" />
const form = useForm({
title: ''
});
This is the explanation of it. This is common input with useForm. This useForm is a helper function from inertiajs. And v-model is associated with two way data binding.
<input type="text" v-model="form.title">
const form = useForm({
title: '',
});
Now let's got to inertia component.
defineProps({
modelValue: String,
});
This is the way of vue 3 composition api to call v-model from sub component. Now this,
defineEmits(['update:modelValue']);
In Vue.js, the emit function is used for child components to send custom events to their parent components. This link says more about emits,
@input="$emit('update:modelValue', $event.target.value)"
Same as here we update parents v-model value with our child component input value.
Now with this knowledge let's create a custom component.
<script setup>
import { ref, defineProps, defineEmits } from 'vue';
const props = defineProps({
modelValue: File,
});
const emit = defineEmits(['update:modelValue']);
const input = ref(null);
function handleChange(event) {
const file = event.target.files[0] || null;
emit('update:modelValue', file);
}
defineExpose({ focus: () => input.value.focus() });
</script>
<template>
<input
type="file"
ref="input"
class="border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm"
@change="handleChange"
>
</template>
And this is how we use it
<ImageUpload id="image" v-model="form.image" />
const form = useForm({
image: null
});
Top comments (0)