据我了解,向组件添加key
属性将使该组件在键更改时具有响应性,但是Vuetify提供的v-navigation-drawer
似乎具有没有影响。
我甚至尝试对loggedIn
之类的+= 1
键进行任意更改,该更改足以重新呈现组件。
这里的用例是我有一个全局导航抽屉,该抽屉应根据用户是否登录来显示上下文。
完整组件
<template>
<v-navigation-drawer
absolute
right
dark
color="primary"
v-if="$store.state.globalDrawer"
v-model="$store.state.globalDrawer"
:key="loggedIn"
>
<v-container class="pa-5">
<v-layout column align-center justify-center>
<v-avatar class="ma-4" size="60">
<img v-if="!twitter" src="https://pbs.twimg.com/profile_images/1173674959731867648/6kzApb83_400x400.jpg" />
<img v-else :src="twitter.profile_image_url" />
</v-avatar>
<h2 v-if="!twitter" class="title">StreamBeacon.tv</h2>
<h2 v-else class="title">{{ twitter.display_name }}</h2>
<p v-if="!twitter" class="body-2 text-center">Enhance your Going Live experience.</p>
<p v-else class="body-2 text-center">@{{ twitter.screen_name }}</p>
<v-chip v-if="twitch.live">
<font-awesome-icon :icon="['fab', 'twitch']" />
Live Now
</v-chip>
</v-layout>
</v-container>
<!-- User is authenticated -->
<v-list dense nav>
<v-subheader>Account</v-subheader>
<v-list-item-group
color="primary"
v-if="user"
>
<v-list-item
v-for="(link, i) in accountLinks"
:key="i"
:color="activeLinkColor"
:to="link.target"
@click="changeDashboardView(link.dashboardComponent)"
>
<v-list-item-icon :color="activeLinkColor">
<v-icon v-text="link.icon"></v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title v-text="link.text"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
<!-- User is NOT authenticated -->
<v-list-item-group
color="primary"
v-else
>
<v-list-item
@click="$eventHub.$emit('registration')"
:color="activeLinkColor"
>
<v-list-item-icon color="primary">
<v-icon>mdi-shield-account</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>Sign In</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
<v-subheader>Quick Links</v-subheader>
<v-list-item-group
color="primary"
>
<v-list-item
v-for="(link, i) in quickLinks"
:key="i"
:color="activeLinkColor"
>
<v-list-item-icon color="primary">
<v-icon v-text="link.icon"></v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title v-text="link.text"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-navigation-drawer>
</template>
<script>
export default {
data() {
return {
user: false,
twitter: false,
twitch: false,
loggedIn: false,
active: this.$store.state.globalDrawer,
activeLinkColor: "#fff",
accountLinks: [
{
"icon": "mdi-shield-account",
"dashboardComponent": null,
"text": "My Account",
},
{
"icon": "mdi-account-box-multiple",
"dashboardComponent": "connections",
"text": "My Connections"
},
{
"icon": "mdi-credit-card",
"dashboardComponent": "subscription",
"text": "Subscription",
},
{
"icon": "mdi-bug",
"dashboardComponent": "support",
"text": "Support"
},
{
"icon": "mdi-logout",
"target": "logout",
"text": "Logout"
}
],
quickLinks: [
{
"icon": "mdi-gift",
"click": "",
"text": "Gift a Streamer"
},
{
"icon": "mdi-mail",
"click": "",
"text": "Contact Us"
},
{
"icon": "mdi-library-video",
"click": "",
"text": "Our Streamers"
},
]
}
},
methods: {
checkIfAuthenticated() {
if(this.$store.state.authenticatedUser != null) {
this.user = JSON.parse(this.$store.state.authenticatedUser)
this.loggedIn = true
if(this.user.twitter) {
this.twitter = this.user.twitter
}
if(this.user.twitch_channel) {
this.twitch = this.user.twitch_channel
}
}
},
changeDashboardView(targetComponent) {
if(this.$route.name != 'dashboard') {
this.$router.replace('dashboard')
.then(() => {
this.$eventHub.$emit('changeDashboardComponent', targetComponent)
})
} else {
this.$eventHub.$emit('changeDashboardComponent', targetComponent)
}
}
},
mounted() {
this.checkIfAuthenticated()
},
watch: {
$route: function(to, from) {
this.loggedIn true
}
}
}
</script>
是否需要使key
更改生效的情况还是应该起作用?我已验证loggedIn
在登录时确实可以正确更改。
我的另一种理论是,由于使用v-if
指令,该组件在密钥更改期间就消失了,但是,我已经揭穿了这一理论。
答案 0 :(得分:1)
正如安东尼奥在上面提到的,潜在的问题是我没有为v-if
指令的键和依赖项使用任何反应式数据。
如果使用上面的代码查找,登录后user
仍然为false,这是经过身份验证的用户的上下文的值依赖项。在mounted()
钩上并更改路由后,我会寻找它们并进行更新,但这是一种骇人听闻的方法。
登录后:
解决方案是使用Vuex getter
使用计算属性,该属性将触发组件上的渲染。
话虽如此,我对上面代码的更改如下(可能会更改,因为这与我需要解决的当前错误相反,但请使其与原始错误尽可能接近,以便于阅读差异)。
computed: {
loggedIn: {
get() {
return this.$store.state.isLoggedIn
},
set(value) {
this.$store.commit('updateLoggedInState', value)
}
},
user: {
get() {
return JSON.parse(this.$store.state.authenticatedUser)
}
}
}
简单的解决方案,是一天的一堂好课!谢谢安东尼奥的指导。