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

<input> rerenders while changes affects only sibling elements #6929

Open
kamax1 opened this issue Oct 26, 2017 · 17 comments
Open

<input> rerenders while changes affects only sibling elements #6929

kamax1 opened this issue Oct 26, 2017 · 17 comments

Comments

@kamax1
Copy link

kamax1 commented Oct 26, 2017

Version

2.5.2

Reproduction link

https://codepen.io/anon/pen/OxKqbL?editors=1111

Steps to reproduce

Please open codepen example and type something into input

What is expected?

Input should not lose focus

What is actually happening?

input rerenders and loses focus


happens only if there is such conditional elements exists before and after input. Workaround is to use v-show instead of v-if in such cases.

@yyx990803
Copy link
Member

You can also simply give the <input> a key to ensure it is not replaced.

@kamax1
Copy link
Author

kamax1 commented Oct 26, 2017

i tried your solution in codepen and still cant get it working.

i tried this
<input type="text" v-model="inputVal" :key="1">

@IlyaOsotov
Copy link

IlyaOsotov commented Nov 6, 2017

U need to have same DOM structure before your input. Look this. It can be after update your DOM before your input tag

@kyle7zhang
Copy link

Actually, it is the same input element, but first remove from the document then move it to other places, for example:

it first renders like

 <!----> // A
<input />
 <!----> // B

then you focus input and input some words, then virtual dom insert <span>before</span>, and it then parent.insertBefore(input, A), it moves the input element before the A comment element, so it will eventually lose focus, then it will delete the comment node.

so, I think you could use v-show better to avoid the insertBefore move problem(remove from the document then insert before the reference node, in this case, which is comment A ). This is the default action for virtual dom of vue which doesn't replace comment node.

@znck znck added bug and removed improvement labels Dec 11, 2017
@znck
Copy link
Member

znck commented Dec 11, 2017

You can also simply give the <input> a key to ensure it is not replaced.

<input> element focus is lost in either case.

@Kingwl
Copy link
Member

Kingwl commented Dec 20, 2017

google/incremental-dom#237
seems like this one

@Kingwl
Copy link
Member

Kingwl commented Jan 3, 2018

I have tried to fix this issue
But I encountered some problem
have we got some way to access vnode from html element?
I want to get vnode path as google/incremental-dom#237
But I did not find a good way to do that
have i missing something? or have other better solution?😅

@dev-blinov
Copy link

@Kingwl you can use v-show. It works correctly.

@furryablack
Copy link

furryablack commented Jan 13, 2019

Alternative way:
https://codepen.io/furrya_black/pen/ZVVLpQ

Just html-layout usually has a more complex structure. What do you thing?
As a proof you can see any css framework: material disign, bulma, bootstrap, etc (what else)

UPD: if your case require rerender-mehanic (with v-if)

@janschoenherr
Copy link

janschoenherr commented Feb 19, 2019

It also seems to break (loose focus) if the spans are shown initially:

https://codepen.io/janschoenherr/pen/NoJpoY?editors=1111

I would think that it doesn't need to do insertBefore in this case.

@Akryum
Copy link
Member

Akryum commented Apr 14, 2019

@Akryum
Copy link
Member

Akryum commented Apr 14, 2019

Thread on twitter

@Justineo
Copy link
Member

F.Y.I. It seems that #9473, #9496, #9808 all share the same root cause.

@brnteka
Copy link

brnteka commented Sep 9, 2019

I'm using Vue 2.6.7 and this issue is still relevant, i was able to work it out by using v-show instead of v-if on a sibling, but it's still confusing why it doesn't work when v-if is used

@nolros
Copy link

nolros commented Mar 1, 2020

I found that @Focus is not reliable when using DOM manipulation, such as v-if and therefore, directives would be the best approach:

<template>
    <form method="POST"
          autocomplete="off"
          @submit.prevent="onSubmit">

<!--     We set the directive here v-focus with the function prop handleFocus -->
        <div class="flex mt-1 rounded-md shadow-sm">
            <input id="title"
                   type="text"
                   v-focus="handleFocus"
                   v-model="form.title">
        </div>

    </form>
</template>


<script>
        export default {
            name: "FormComponent",
            data() {
                return {
                    // A form class example, but you could just have a var
                    form: new this.$form({
                        title: null,
                    })
                }
            },
            directives: {
                focus: {
                    inserted(el,binding) {
                        // We set focus on the element
                        el.focus();
                        // optional if you had other operations. Data and props, etc. are not available inside
                        // a direective uless yoru decorate the provider, which is a pain. So we call the binding
                        // which is the handleFocus set on input. We pass the el but we could inject nothing or a event, binding, etc
                        if (!_.isUndefined(binding.value)) binding.value(el)
                    }
                }
            },
            methods: {
                handleFocus: function() {
                    // For example reset a form v-model
                    this.form.title = null;
                },
            }
        }
    </script>

@misaghkarimi
Copy link

v-show
it worked thanks.

@hljeong
Copy link

hljeong commented Feb 19, 2024

I had the problem where a v-if causes the parent modal to lose focus so that pressing <esc> does not close the modal. v-show did not fix my problem since rendering the element when the v-if condition is not met results in an error due to a null value.

I worked around this by focusing an invisible dummy <Input /> in the modal whenever the v-if condition changes.

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

No branches or pull requests