Prevent input label animation from async data
-
Hi,
I’m trying to make a page where data should be loaded from an axios call first before displaying any components.
Everything is working so far, but I’m getting some unexpected animation from an input label. To my understanding, when you set an input’s
v-model
with existing data, itslabel
should automatically be above the field (so it looks like the input is already focused). The issue I’m having is after resolving an axios call and updatingdata()
, the input field animates the label transition and I don’t want this.Is there any way to fix this? At the moment I’ve got an
async created()
and tried looking at$nextTick()
but to no avail. I have a mock example at https://jsfiddle.net/skvc304y/ but you may need to click Run to see the animation I’m talking about. If that is not accessible, a copy of the code is available below:<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@quasar/extras/material-icons/material-icons.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/quasar/dist/quasar.min.css"> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="https://cdn.jsdelivr.net/npm/quasar/dist/quasar.umd.min.js"></script> <div id="q-app"> <div class="q-ma-md"> <q-input label="Input" v-model="inputData"></q-input> </div> <div class="q-ma-md"> Running Quasar v{{ version }} </div> </div>
new Vue({ el: '#q-app', data: function () { return { version: Quasar.version, inputData: '' } }, async created() { // Mock axios call const res = await new Promise(resolve => setTimeout(() => resolve('test'), 0) ); this.inputData = res // The above should behave like the following: // this.inputData = 'test' } })
-
Managed to solve it and I think I’ve over-analysed this! Simply put I’ve set a boolean flag to be true once
created()
has finished and av-if
on the component to wait for the flag.<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@quasar/extras/material-icons/material-icons.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/quasar/dist/quasar.min.css"> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="https://cdn.jsdelivr.net/npm/quasar/dist/quasar.umd.min.js"></script> <div id="q-app"> <div class="q-ma-md"> <q-input v-if="ready" label="Input" v-model="inputData"></q-input> </div> <div class="q-ma-md"> Running Quasar v{{ version }} </div> </div>
new Vue({ el: '#q-app', data: function () { return { version: Quasar.version, ready: false, inputData: '' } }, async created() { // Mock axios call const res = await new Promise(resolve => setTimeout(() => resolve('test'), 0) ); this.inputData = res this.ready = true } })
When I was testing I could see
inputData
appear before the component rendering, so I assumed there was something wrong with it. Instead I was mishandlingPromises
!