ijpatricio / mingle

Use JS components with Vue or React in a Laravel Livewire and/or Filament application
MIT License
205 stars 6 forks source link

Variable value not updating in Vue Component #7

Closed vidneu closed 2 months ago

vidneu commented 2 months ago

I am not sure if this is a bug or if I am missing something here. I am thankful for every advice.

I have expanded the example from the documentation with an $amount var in the Livewire component. I want to reactively display it in my Vue Component. Via console.log I have confirmed, that the wire.amount value updates in JS. But the displayed value does not seem to update.

<script setup>
import {ref, defineProps} from 'vue'

const props = defineProps({
  wire: {},
  mingleData: {},
})

const {wire, mingleData} = props

const message = mingleData.message;

</script>

<template>
  <div>
    <h1> we are building something amazing {{ wire.amount }}</h1>
    <button class="btn" type="button" @click="wire.doubleIt(wire.amount)">Double it</button>
  </div>
</template>
class GraphWithEditWindow extends Component implements HasMingles
{
    use InteractsWithMingles;

    public $amount = 1;

    public function component(): string
    {
        return 'resources/js/GraphWithEditWindow.js';
    }

    public function mingleData()
    {
        return [
            'message' => 'Message in a bottle 🍾',
        ];
    }

    public function doubleIt($amount)
    {
        $this->amount = $amount * 2;
    }
}
ijpatricio commented 2 months ago

Right. So the Livewire state does not get directly updated with the Vue/React state nor vice-versa. They're independent.

You can make them update by $wire.set() and $wire.watch, or other event bus you might want to put in place.

Maybe there's space to evolve for something like that, in the future.

The best approach, 100% reliable is to think of this as a "separate" world, but that communicates easily.

Ok, so this is pseudo-code, just coded here, it might fail something, but I hope you get the idea.

I will have demos set in place, and make this more clear.

And of course, let me know if it worked for you!

(...)

// Set initial value
const amount = ref(mingleData.amount)

const doubleTheAmount = () => {
    wire.doubleIt(amount.value)
        .then(data => amount.value = data)
}

(...)

<button class="btn" type="button" @click="doubleTheAmount">Double it</button>
(...)
(...)
    public function doubleIt($amount)
    {
        // you return a value so that JS will have it
        return $amount * 2;
    }

(...)
vidneu commented 2 months ago

Yup, that worked for me. Thanks a lot!