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

Select box with v-model updates lazy when mounting the component #7392

Closed
leorott opened this issue Dec 21, 2022 · 6 comments · Fixed by #7432
Closed

Select box with v-model updates lazy when mounting the component #7392

leorott opened this issue Dec 21, 2022 · 6 comments · Fixed by #7432
Labels
🐞 bug Something isn't working scope: ssr

Comments

@leorott
Copy link

leorott commented Dec 21, 2022

Vue version

3.2.45

Link to minimal reproduction

https://sfc.vuejs.org/#__SSR__eNqtVU1v2zAM/SuEL0mB2m7Xj4PnBOt62mlAO/Tki2PTiTpbEiQ5aVDkv4+SYtdpkyAdepPEx0fySaRegzspo2WLQRKkBhtZ5wanGQdIS7aEos61nmRBIbjJGUeVBc5I5sXldBk2osQaDGoDK2YW8NQiXMHj40Mak32LHBIxitFzkE1OH7HGwszEi2fYcqaxfANpB+lMxOIPsHzK6xYfsBowElxIwwSHpTUS+JKsd2nsT4/gvhHu5wm4K8Ldf8ClsU+qKzqmqv9HANH2he7T4EexyPncpjHGM5hMYbyjBUwAI5OrOZrI5Xt2VJrrLICkI7DJaZ8MluPR9cj6niLczRGWG8dyiqy3R1huHctXiv6Ly9bsCMzsyeCNub0TlRKLPx/hfoHFX7rVPUHMWtqKiy2C+JmteLB/S8MdYjnIgWjqfEZtVwm14zUI6QCfz/khL5mAWWuM4IfzVhbVJS241ae7xN9+12cv2fHknfeUvHZTPhrRrOyyi/jH706O6Lyn5HVIpG6VxoNxmOpCMWlAo2kl1NSClko79VgjhTLwCgor2EClRAMjmqij7xnPOE1OGo7vBxb1KaHHo6vRGaH2YDoAvfwe8PYiO6sdvAPA9q1srUZR+/c2r0vnSIoPiftWI/vYzw07W3Yy8vMEJpOJ1568qf2cLE4gs66tUlH/VcCrlbNkmkRcJ1DV+EI+4BZhyRRRUy8nUIi6bbgzPbfasGodWg7kJgEt8wLDGZoVoofIvCwZn4eKzRcEuLy4kJ62M9RYDc439g6kT6Whucgo4EV3HtkOGNrCmaCn35D7TedNNW4rC84Df9Vhk8voWQtOf6ZzplZyBnoPiaezZ/QE7D4LFsZIncSxrgr70z7rSKh5TKtItdywBiPUTThTYqVREXEWnA84aMSpJapQIS9R2R/4MOc76AdeS0s1bYLNPypOmAY=

Steps to reproduce

  • Open link to minimal reproduction
  • reload page

What is expected?

The select box should show option C directly from the beginning

What is actually happening?

v-model is behaving weirdly when a value is already set while mounting the component.

In the following example the select box initially shows option A then the Component re-renders and shows the correct option C. However the selected ref is set to 3 from the beginning according to the output in the console when I'm logging the selected ref.

<template>
  <div>
    <select v-model="selected">
      <option value="1">A</option>
      <option value="2">B</option>
      <option value="3">C</option>
    </select>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const selected = ref('3');
</script>

When using the v-bind directive and @change, everything works fine.

<template>
  <div>
    <select @change="(e) => selectedValue = e.target.value">
      <option value="4" :selected="isSelected('4')">A</option>
      <option value="5" :selected="isSelected('5')">B</option>
      <option value="6" :selected="isSelected('6')">C</option>
    </select>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const selected = ref('6');
const isSelected = (value) => selectedValue.value === value
</script>

Moreover, this error occurs only when using a select box. Other types of input fields (checkbox, radio button, text input) work. Also when doing the same in plain Vue 3 it works.

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
Binaries:
    Node: 16.14.2 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 7.17.0 - /usr/local/bin/npm
npmPackages:
    vue: ^3.2.25 => 3.2.45

Any additional comments?

I also created this Nuxt issue related to this topic: nuxt/nuxt#15631

@LinusBorg LinusBorg added scope: ssr 🐞 bug Something isn't working labels Dec 21, 2022
@edikdeisling
Copy link

The same happens with a checkbox. Value is set after control is added to the dom which triggers transition animations.

@edison1105
Copy link
Member

@edikdeisling
Could you provide a minimal reproduction?

@edison1105
Copy link
Member

edison1105 commented Jan 5, 2023

@edikdeisling
this is because scrollIntoView() triggers forces layout/reflow and layout/reflow will restart a CSS animation.
see https://www.harrytheo.com/blog/2021/02/restart-a-css-animation-with-javascript/

@edikdeisling
Copy link

edikdeisling commented Jan 5, 2023

@edison1105 thank you for the info, extremely interesting!
But does it mean that vue renders input without taking into account the initial value of v-model?
image
https://sfc.vuejs.org/#eNqVUk1v2zAM/SuELnGB2Ma+Lq5jdIcddu6wky+OTTdarA9ItNMi8H77KCtZ0i4YtoMhi3x8fHrkUXy2NptGFIUofeukJfBIo61qDSCVNY7gCA77NbRG2ZGwgxl6ZxSsuGwVYOFrjfYEynQ4wCbgE3Ij3t1fctNj68wQskfGjZqZCkhwuINNBceAi0gzYDaYJ85kGp/py4AKNT3K7SD1UyR8DVxtsTcOgeUz/2oNNyuzdoftHrszA4NiwVdN5rvEQ3KTu+kJ3X9Ss4HfpEIzUpJcv+4mNcl2/6/Ec/yZYeazzOO8eFJ8IVR2aAiXuZWdnGBKo+qqzPla1bRkpOYZAr1Y3NRiod+a51owepkdB5eTI/lvqsrx0GUPJzVwkLQDco32kqRhIWf+Mr+SwVdPL0NUFAQtLtR0KSzYj8E4eOeBX4uNu4+7NIdi3r4gtTg3/XnhCD5yXcFr1kVDFjeWZmIt4tamqrHZD280b3bsfEr4WhRnnlrwDod7LXZE1hd5Pmq7Z+ONyh84lzteVJ5l2hn18CF7n338xK/1dB3P0Kt068zBo+OOtVhfkeccnNClDnWHDt1fm73Bvmr4JvdH05MPs5h/Ad3AT88=

It means that mounted hook is called before input gets its value from v-model. Is it an issue? It means that vue inserts input into DOM with invalid state. Also feels a little unexpected that input already exists in the DOM during mounted hook of the previous element. But this can be expected if all component template inserted into DOM at once
From my perspective v-model should set value during beforeMount hook before the element is inserted into DOM

@edison1105
Copy link
Member

edison1105 commented Jan 9, 2023

From my perspective v-model should set value during beforeMount hook before the element is inserted into DOM

It's probably something that can be optimized

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🐞 bug Something isn't working scope: ssr
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants