使用 Vue.js 体验导航栏闪烁
Experiencing navbar flicker with Vue.js
在函数被评估为 true 或 false 之前,我的导航栏出现闪烁。
需要评估的函数如下:
export default {
methods: {
isAuthenticated () {
return this.$store.state.user.authenticated
}
},
data: () => {
return {
unauthenticated: [
{
title: 'Link1',
url: '/link1'
},
{
title: 'Link2',
url: '/link2'
},
{
title: 'Link3',
url: '/link3'
}
],
authenticated: [
{
title: 'otherLink1',
url: '/otherlink1'
},
{
title: 'otherLink2',
url: '/otherlink2'
},
{
title: 'otherLink3',
url: '/otherlink3'
}
]
}
}
}
导航栏有以下内容:
<template v-if="isAuthenticated()">
<b-nav is-nav-bar>
<b-nav-item v-for="nav in authenticated" :key="nav.title" :href="nav.url">{{nav.title}}</b-nav-item>
</b-nav>
</template>
<template v-else>
<b-nav is-nav-bar>
<b-nav-item v-for="nav in unauthenticated" :key="nav.title" :href="nav.url">{{nav.title}}</b-nav-item>
</b-nav>
</template>
但是,当我点击导航时,未经身份验证的链接出现一秒钟,然后经过身份验证的链接出现,就好像 isAuthenticated()
函数尚未计算一样。我该怎么做才能消除这种闪烁?
我的商店文件 (user.js) 文件如下所示:
export const state = () => ({
headers: {},
profile: {}
})
export const mutations = {
updateHeaders (state, headers) {
state.headers.access_token = headers['access-token']
state.headers.token_type = headers['token-type']
state.headers.client = headers['client']
state.headers.expiry = headers['expiry']
state.headers.uid = headers['uid']
if (state.headers.expiry == null) {
state.authenticated = false
} else {
let timeToExpiry = new Date(state.headers.expiry * 1000)
let now = new Date()
state.authenticated = now < timeToExpiry
}
},
signout (state) {
state.headers = {}
state.profile = {}
}
}
login/logout 方法通过 API 调用 Rails 应用程序实现。 Devise gem 处理剩下的事情。
提前致谢!
编辑:
我将 Nuxt.js 用于 layouts/pages/components,因此我相信链接在后台提交时带有 this.$router.push(url)
。
b-nav
标签来自 Bootstrap Vue
没有说明单击其中一个链接时执行的代码,我假设它类似于 this.$router.push(url)
。如果是这种情况,您可能已将导航栏包含在 <router-view>
中,因此当您切换当前路线时,<router-view>
内的组件会重新呈现,因此导航栏会闪烁。将它们移出 <router-view>
应该可以解决这个问题。
编辑:所以OP还没有使用vue-router
,在这种情况下,要么手动更改根组件的数据以使导航以外的部分发生变化,或添加 vue-router
并使用 this.$router.push()
导航,这样 <router-view>
之外的部分就不会改变或闪烁。
无论如何,我们需要 vue 组件留下来让 vue 只重新渲染视图的一部分,而简单地通过 <a>
导航或其他东西会破坏所有东西并再次重建它们,因此闪烁。
使用 bootstrap-vue 时,有两种方法可以将 link 添加到导航栏。一种是绑定到 :href
属性,这会创建一个常规的 html 锚点。另一种是使用:to
属性,它创建一个与vue-router交互的link。
<b-navbar-nav v-if="isAuthenticated()">
<b-nav-item v-for="nav in authenticated" :key="nav.title" :to="nav.url">{{nav.title}}</b-nav-item>
</b-navbar-nav>
<b-navbar-nav v-if="!isAuthenticated()">
<b-nav-item v-for="nav in unauthenticated" :key="nav.title" :to="nav.url">{{nav.title}}</b-nav-item>
</b-navbar-nav>
没有理由在这里使用 <template>
标签来封装 .另请注意 'is-nav-bar' 已弃用。请参阅 here 他们指出弃用的地方。
在函数被评估为 true 或 false 之前,我的导航栏出现闪烁。
需要评估的函数如下:
export default {
methods: {
isAuthenticated () {
return this.$store.state.user.authenticated
}
},
data: () => {
return {
unauthenticated: [
{
title: 'Link1',
url: '/link1'
},
{
title: 'Link2',
url: '/link2'
},
{
title: 'Link3',
url: '/link3'
}
],
authenticated: [
{
title: 'otherLink1',
url: '/otherlink1'
},
{
title: 'otherLink2',
url: '/otherlink2'
},
{
title: 'otherLink3',
url: '/otherlink3'
}
]
}
}
}
导航栏有以下内容:
<template v-if="isAuthenticated()">
<b-nav is-nav-bar>
<b-nav-item v-for="nav in authenticated" :key="nav.title" :href="nav.url">{{nav.title}}</b-nav-item>
</b-nav>
</template>
<template v-else>
<b-nav is-nav-bar>
<b-nav-item v-for="nav in unauthenticated" :key="nav.title" :href="nav.url">{{nav.title}}</b-nav-item>
</b-nav>
</template>
但是,当我点击导航时,未经身份验证的链接出现一秒钟,然后经过身份验证的链接出现,就好像 isAuthenticated()
函数尚未计算一样。我该怎么做才能消除这种闪烁?
我的商店文件 (user.js) 文件如下所示:
export const state = () => ({
headers: {},
profile: {}
})
export const mutations = {
updateHeaders (state, headers) {
state.headers.access_token = headers['access-token']
state.headers.token_type = headers['token-type']
state.headers.client = headers['client']
state.headers.expiry = headers['expiry']
state.headers.uid = headers['uid']
if (state.headers.expiry == null) {
state.authenticated = false
} else {
let timeToExpiry = new Date(state.headers.expiry * 1000)
let now = new Date()
state.authenticated = now < timeToExpiry
}
},
signout (state) {
state.headers = {}
state.profile = {}
}
}
login/logout 方法通过 API 调用 Rails 应用程序实现。 Devise gem 处理剩下的事情。
提前致谢!
编辑:
我将 Nuxt.js 用于 layouts/pages/components,因此我相信链接在后台提交时带有 this.$router.push(url)
。
b-nav
标签来自 Bootstrap Vue
没有说明单击其中一个链接时执行的代码,我假设它类似于 this.$router.push(url)
。如果是这种情况,您可能已将导航栏包含在 <router-view>
中,因此当您切换当前路线时,<router-view>
内的组件会重新呈现,因此导航栏会闪烁。将它们移出 <router-view>
应该可以解决这个问题。
编辑:所以OP还没有使用vue-router
,在这种情况下,要么手动更改根组件的数据以使导航以外的部分发生变化,或添加 vue-router
并使用 this.$router.push()
导航,这样 <router-view>
之外的部分就不会改变或闪烁。
无论如何,我们需要 vue 组件留下来让 vue 只重新渲染视图的一部分,而简单地通过 <a>
导航或其他东西会破坏所有东西并再次重建它们,因此闪烁。
使用 bootstrap-vue 时,有两种方法可以将 link 添加到导航栏。一种是绑定到 :href
属性,这会创建一个常规的 html 锚点。另一种是使用:to
属性,它创建一个与vue-router交互的link。
<b-navbar-nav v-if="isAuthenticated()">
<b-nav-item v-for="nav in authenticated" :key="nav.title" :to="nav.url">{{nav.title}}</b-nav-item>
</b-navbar-nav>
<b-navbar-nav v-if="!isAuthenticated()">
<b-nav-item v-for="nav in unauthenticated" :key="nav.title" :to="nav.url">{{nav.title}}</b-nav-item>
</b-navbar-nav>
没有理由在这里使用 <template>
标签来封装 .另请注意 'is-nav-bar' 已弃用。请参阅 here 他们指出弃用的地方。