I use Vue.js to send data to a basic and very simple API that subscribes an e-mail address to a newsletter via the form below and to display some messages (state and errors).
I use in particularly the directives v-if and v-for to display the errors and two messages. The thing is when the page is loading, those two paragraph elements and the unordered list element "flash" until the page is fully loaded or until the Vue.js instance is mounted.
Am I doing it wrong? Is this a common issue? Is there anything I can do to prevent all those elements to flash at loading ?
Thank you in advance.
Here's the HTML:
<div id="subscribe-to-newsletter">
<form v-on:submit.prevent="storeSubscriber" novalidate>
<label for="email-address">E-mail address</label>
<input type="email" name="email_address" id="email-address" placeholder="[email protected]" v-model="emailAddress">
<input type="submit" name="submit" value="Rester informé">
</form>
<p v-if="success">Thank you, we will keep you updated</p>
<p v-if="loading">Loading</p>
<ul v-for="error in errors.email_address">
<li v-text="error"></li>
</ul>
</div>
And here's the JavaScript:
const subscribe = new Vue({
el: '#subscribe-to-newsletter',
data: {
emailAddress: '',
loading: false,
success: false,
errors: []
},
methods: {
storeSubscriber() {
subscribe.success = false;
subscribe.errors = [];
subscribe.loading = true;
var xhr = new XMLHttpRequest();
xhr.open('POST', '/api/subscriber', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
subscribe.loading = false;
if (this.status == 200) {
subscribe.success = true;
} else {
subscribe.errors = JSON.parse(xhr.responseText);
}
}
}
xhr.send(encodeURI('email_address=' + subscribe.emailAddress));
},
}
})
Edit
I tried to use the v-cloak directive and it is not solving the problem.
JSFiddle of the problem
Solution
Add this in your CSS
[v-cloak] {
display: none;
}
And here's the new HTML:
<div id="subscribe-to-newsletter">
<form v-on:submit.prevent="storeSubscriber" novalidate>
<label for="email-address">E-mail address</label>
<input type="email" name="email_address" id="email-address" placeholder="[email protected]" v-model="emailAddress">
<input type="submit" name="submit" value="Rester informé">
</form>
<p v-if="success" v-cloak>Thank you, we will keep you updated</p>
<p v-if="loading" v-cloak>Loading</p>
<ul v-for="error in errors.email_address" v-cloak>
<li v-text="error"></li>
</ul>
</div>
The v-if directive is a Vue.js directive used to toggle the display CSS property of a element with a condition. If the condition is true it will make it visible else it will make it invisible.
Vue.js | v-if directive. The v-if directive is a Vue.js directive used to toggle the display CSS property of a element with a condition. If the condition is true it will make it visible else it will make it invisible.
Vue.js | v-html directive. The v-html directive is a Vue.js directive used to update a element’s innerHTML with our data. This is what separates it from v-text which means while v-text accepts string and treats it as a string it will accept string and render it into HTML.
Parameters: This directive accepts a single parameter which is the data. Example: This example uses VueJS to update the html of a element with v-html.
Use v-cloak and it will solve it.
https://vuejs.org/v2/api/#v-cloak
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With