vue
vue copied to clipboard
Vue mounted component before dom update
If i mounted created Vue in app beforeDomUpdate not update existing components
const app = new Vue({
el: '#app',
});
For example i have vue component
<template>
<div>
<input v-model="inputValue" @change="$emit('input', inputValue)">
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
require: true
},
},
watch: {
value(value) {
this.inputValue = value
}
},
data() {
return {
inputValue: this.value,
}
}
}
</script>
If i submit form and return validation error and vue has input or button they is blocked
But if i force update component they show correctly (like this)
<template>
<div>
<input class="form-control" v-model="inputValue" @change="$emit('input', inputValue)" :key="componentKey">
<span @click="forceRerender">forceRerender</span>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
require: true
},
},
mounted() {
console.log('mounted input', this.componentKey);
},
watch: {
value(value) {
this.inputValue = value
}
},
data() {
return {
inputValue: this.value,
componentKey: 1,
}
},
methods: {
forceRerender() {
this.componentKey += 1;
}
}
}
</script>
This is because vue render component before livewire update dom
if i log vue mounter and livewire Javascript Hooks i see like thet
mounted component
beforeDomUpdate
afterDomUpdate
Maybe I am wrong. But there is no future about Vue integration, once AlpineJs is around.
I really like approach to use pre-made components provided by Vuetify/Bueffy... that solves many UI heavy lifting.
Many do prefer Tailwind, what is great tool. But I don’t really like the idea about to write many lines of code to build a simple “input + label”.
“So, do package it into components ...”. Well, some one already did the job for Vue world: Vuetify, Buefy ...
I just wanna give a try with Livewire from @calebporzio It is perfect! Buy I really miss this UI nice components out-of-box.
Is there any fix for this? Even if using key to update the vue component, some of the v-model data inside the component does not update correctly.
Currently it's very hard to use any reactive vue components inside livewire components.
@MammutAlex I am experiencing the same problem. How did you deal with it?
@kamilkozak in a project with many vue components I do not use livewire 😔
Im using Alpine, Vue and Livewire. I know it can be a headache but I'm trying to migrate components to alpine/wire slowly.
Here's what I'm doing as a workaround now for my complex vue components when data doesn't rebind after livewire updates state/dom.
<div
x-data="{ showVueComponent: true }"
x-on:show-vue-component.window="showVueComponent = true"
x-on:hide-vue-component.window="showVueComponent = false"
wire:ignore.self>
@includeWhen($currentStep == 0, 'orders._step_one')
{{--included in $currentStep 0 --}}
<div class="mx-auto max-w-4xl" wire:ignore wire:key="vueComponent">
<my-vue-component
x-show="showVueComponent"
v-on:input="(select) => [email protected]('submit', select)">
</my-vue-component>
</div>
@includeWhen($currentStep == 1, 'orders._step_two')
@includeWhen($currentStep == 2, 'orders._step_three')
</div>
In my Livewire component I use browserDispatchEvent inside my functions to toggle the component. Not sure if this is the best way to handle the situation but works for me atm.
$this->dispatchBrowserEvent('show-vue-component');
$this->dispatchBrowserEvent('hide-vue-component');