I have a problem with rendering in vue.js. I made a simple login/registration app. When the user is logged in, the register link should be hidden. It works but when I reload page there is small delay. I try to use v-cloak
but it's not working. How can I fix it? I recorded loading on gif.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>michael-client</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>
<body>
<style type="text/css">
[v-cloak] {
display:none;
}
</style>
<div class="container">
<div class="col-lg-8">
<div id="app">
<!-- built files will be auto injected -->
</div>
</div>
</body>
</html>
App.vue
<template>
<div class="panel panel-default" v-cloak>
<div class="panel-heading">
<nav>
<ul class="list-inline">
<li>
<router-link :to="{ name: 'home' }">Home</router-link>
</li>
<li v-if="!$auth.check()" class="pull-right">
<router-link :to="{ name: 'login' }">Login</router-link>
</li>
<li v-if="!$auth.check()" class="pull-right" v-cloak>
<router-link :to="{ name: 'register' }">Register</router-link>
</li>
<li v-if="$auth.check()" class="pull-right">
<a href="#" @click.prevent="$auth.logout()">Logout</a>
</li>
</ul>
</nav>
</div>
<div class="panel-body">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
and main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import Home from './components/Home'
import Login from './components/Login'
import Register from './components/Register'
import Dashboard from './components/Dashboard'
import VueRouter from 'vue-router'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.config.productionTip = false
/* eslint-disable no-new */
Vue.use(VueRouter);
Vue.use(VueAxios, axios);
axios.defaults.baseURL = 'http://127.0.0.1:8888/api';
const router = new VueRouter({
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/login',
name: 'login',
component: Login,
meta: {
auth: false
}
},
{
path: '/register',
name: 'register',
component: Register,
meta: {
auth: false
}
}
]
});
Vue.router = router
Vue.use(require('@websanova/vue-auth'), {
auth: require('@websanova/vue-auth/drivers/auth/bearer.js'),
http: require('@websanova/vue-auth/drivers/http/axios.1.x.js'),
router: require('@websanova/vue-auth/drivers/router/vue-router.2.x.js'),
});
App.router = Vue.router
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>',
render: function(createElement) {
return createElement(App);
}
});
In which way are you guys waiting for page is read to display?
Instead of making Vue do the same work over and over, You could make use of the v-else
directive, which may work better for you:
<li v-if="!$auth.check()" class="pull-right" v-cloak>
<router-link :to="{ name: 'register' }">Register</router-link>
</li>
<li v-else class="pull-right">
<a href="#" @click.prevent="$auth.logout()">Logout</a>
</li>
v-cloak is not helping because that gets taken away as soon as the Vue app is ready. Apparently there's a delay from when Vue is ready and when the $auth function returns a response. I'd recommend hiding all of the login/logout links until $auth returns something.
You'd have to hook into what $auth returns somehow, and use that hook to change the authCheckDone
to true.
Vue {
data: {
authCheckDone: false
...
}
}
<ul class="list-inline">
<li>
<router-link :to="{ name: 'home' }">Home</router-link>
</li>
<span v-if="authCheckDone">
<li v-if="!$auth.check()" class="pull-right">
<router-link :to="{ name: 'login' }">Login</router-link>
</li>
<li v-if="!$auth.check()" class="pull-right" v-cloak>
<router-link :to="{ name: 'register' }">Register</router-link>
</li>
<li v-if="$auth.check()" class="pull-right">
<a href="#" @click.prevent="$auth.logout()">Logout</a>
</li>
</span>
</ul>
You have to wait a bit until vue-auth
is actually ready. From the docs :
ready
- Get binded ready property to know when user is fully loaded and checked.
- Can also set a single callback which will fire once (on refresh or entry).
<div v-if="$auth.ready()"> <vue-router></vue-router> </div> <div v-if="!$auth.ready()"> Site loading... </div>
created() { this.$auth.ready(function () { console.log(this); // Will be proper context. }); }
In other words, instead of v-cloak
use:
<div class="panel panel-default" v-if="$auth.ready()">
Note: this can do some quick "flashing" of a white page. In that case you may want to add a loading image or something, like:
<div v-if="!$auth.ready()">
<img src="loading.gif">
</div>
Naturally, if this div
is close to the other v-else
can be used.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.