Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue custom component wire:model unexpected behavior #609

Open
theomessin opened this issue Feb 13, 2020 · 1 comment
Open

Vue custom component wire:model unexpected behavior #609

theomessin opened this issue Feb 13, 2020 · 1 comment
Labels

Comments

@theomessin
Copy link

@theomessin theomessin commented Feb 13, 2020

Bug description

When using wire:model on a custom vue component, livewire documentation states:

Livewire will listen for "input" events emitted from the Vue component, and pass down "value" properties just like Vue does. It just works.

However, it turns out that the model binding doesn't just refresh for a vue input event, but for any nested input change within said component.

This can be very problematic in certain cases. I'm trying to wire up a pre-existing vue component that will prepare a large form of filters into a simple array. The vue v-model will only be updated when an apply button is clicked (only then will my component fire a input vue event). Using livewire, I bind the component to a livewire attribute using wire:model, and bind a livewire method to apply said filters using wire:change. Due to this bug, the filters are applied at the first input change [and they break the livewire apply method as the filters attribute is not as expected since vue didn't get to prepare it].

Reproducing this bug

  1. Create a Livewire component with a simple $example attribute.
  2. Use the following livewire blade template:
<div>
    {{ $example }}
    <example-component wire:model="example"></example-component>
</div>
  1. Create the following vue example-component
<template>
    <div>
        <input type="text" class="border border-black"/>
        <input type="text" class="border border-black"/>
    </div>
</template>

<script>
    export default {
        props: ['value']
    }
</script>
  1. Type something in the left input box and click elsewhere. Notice how the text above changes
  2. Type in the right input box and click elsewhere. Notice how the text above changes again
  3. Clear the left input box and click elsewhere. Notice how the text above is now gone

Expected behavior

In the example above, the text should never even appear since we never fire an input event. It should only appear when an input event is fired [and be equal to whatever value is passed to emit].

In vue, a v-model on a custom component will only listen to a input vue event. Any changes to inputs internal to that component will not trigger a change. To trigger a vue method on a model change, one can just use v-on:input="method" - this should be the equivalent of a wire:change on a custom vue component.

In my opinion, the expected [according to my interpretation of the docs] and ideal behavior would be for nothing to happen until a vue input event is fired both for a wire:model and wire:change.

@theomessin

This comment has been minimized.

Copy link
Author

@theomessin theomessin commented Feb 16, 2020

I hope I've explained this well enough. Please let me know if more info is needed. If needed, I can try write a PR if anyone can point me in the write direction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.