Polyconseil/vue-gettext

Input losing focus

nkostadinov opened this issue · 8 comments

I noticed some strange behavior in my application when using v-translate attributes. The inputs are losing focus (may be they are rerendered by Vue).

When I remove the v-translate from the h elements the issue is no longer happening, This bug also causes some of the labels to change their translation with another element on the page.

I managed to isolate the case down to this js fiddle, just try to input something in the input - https://jsfiddle.net/nikolakk/038L6sfe/

kemar commented

Thank you for your report. Your fiddle helped me a lot to reproduce your issue.

It looks like it's related to the Vue’s virtual DOM algorithm. We used auto-generated keys to fix #29 and that triggers the virtual DOM algorithm which has some side effect on your <input> element depending on your HTML structure.

You can solve your problem by wrapping the code that contain your v-translate attributes in a parent element:

<div id="app">

    <div>
        <h2 v-translate>Social features</h2>
        <div>
            <label v-translate>Username</label>
            <input type="text" v-model="username">
        </div>
    </div>

    <h2 v-if="!is_beta" v-translate>Beta version</h2>
    <section v-if="!is_beta">USING BETA</section>

    <a @click="is_beta=!is_beta" v-translate>Switch to Beta</a>

</div>

This will have an effect on the virtual DOM algorithm and it will not redraw your input.

I'll think again about this issue but I'm not sure to be able to provide a better solution…

Just wanted to share this small snipet indicating the problem. I've already found that wraping in parent element fixes the issue.

I've spent many hours till I figured out that this was caused by v-translate, so I want to help someone who has the same problem.

kemar commented

Yes I know, I'm sorry you lost so much time.

I didn't close the issue. I'm still thinking about it.

Hi, just wanted to let you know we've been hit by this behaviour too. It took a while to figure out that v-translate on a child node was causing the parent node to re-render on every keyup.

After quickly browsing the code, I've found that v-translate sets a key attribute on bind(). Unfortunately, it looks like doing this will trigger a re-render of the parent, and thus going again in bind() lifecycle hook. This means that the key changes all the time...

I'm no expert on VueJS rendering. I just wanted to say that it seems to me that trying to address the v-if v-else (#29) issue is causing more problems than it solves...
From Vue's documentation, I would argue that it's up to the developper to add manually a "key" attribute for such cases. It seems out of scope for a custom directive to control "key".

I also wanted to know whether other translation libraries handle such cases, so I browsed a bit Vue i18n-s repository. There also was an issue related to v-if without "key". The maintainer declined the issue and closed it, citing the doc. I think vue-gettext should do the same.

What do you think about it ?

kemar commented

I think you're right @Hyzual, #29 is causing more problems than it solves.

I think I'll revert #29 in the coming days.

Cool :) thanks for the quick answer.

By the way thank you very much for this cool library ! It's really great

kemar commented

I published v2.1.0 in which auto generation of key attributes is off by default.

This should fix the issues we're talking about here.

People can enable the previous behaviour by turning autoAddKeyAttributes to true.

Thanks very much for the quick fix and release !
We'll use it shortly.