简体   繁体   English

Vue组件中的反应性问题

[英]Reactivity issue in vue component

Thanks for reading, I am quite puzzled by this reactivity behavior.感谢阅读,我对这种反应性行为感到非常困惑。 I had buttons on a navbar, displayed upon condition in the app component (App.vue):我在导航栏上有按钮,根据条件显示在应用程序组件(App.vue)中:

<button
 type="button"
 v-if="loggedIn()"
 @click="logout"
 class="btn btn-outline-light"
>

with the associated script:与相关的脚本:

methods: {
   loggedIn() {
     return !(auth.getUser() == null);
   },

here everything works fine and the logout button appears once you log in. Now I am directed to change the design to a sidebar, and create a sidebar component (SideBar.vue) with the exact same html and script.这里一切正常,登录后会出现注销按钮。现在我被指示将设计更改为侧边栏,并使用完全相同的 html 和脚本创建一个侧边栏组件 (SideBar.vue)。 Only issue, the button does not react to the change.唯一的问题是,按钮对更改没有反应。 the only difference is that the navbar is in the App.vue and SideBar is a component of App like so:唯一的区别是导航栏在 App.vue 中,而 SideBar 是 App 的一个组件,如下所示:

<template>
  <div id="app">
    <div id="nav">
      <nav class="navbar navbar-expand-lg navbar-light ">
        // navbar elements with reactive buttons
      </nav>
      <side-bar />
    </div>
    <main>
     <router-view />
    </main>
  </div>
</template>

Edits: I tried to use a computed property in the component without success.编辑:我尝试在组件中使用计算属性但没有成功。 I found a way to make it work by passing a property from the app to the sidebar component but I don't like it as I will have to scale probably later.我找到了一种通过将属性从应用程序传递到侧边栏组件来使其工作的方法,但我不喜欢它,因为我可能稍后必须进行扩展。 any ideas?有任何想法吗? Thanks in advance.提前致谢。

I think in general the structure isn't working out here.我认为总的来说,这个结构在这里行不通。 It's true like some others said that it's better to use a computed property but this is not the issue right here.就像其他人说的那样,使用计算属性更好,但这不是问题所在。

Basically, as soon as the app loads you should call auth.getUser() , for example inside your mounted() or created() handler;基本上,一旦应用程序加载,您应该调用auth.getUser() ,例如在您的 mounted() 或 created() 处理程序中;

// Sidebar.vue or your Root new Vue()
{
    data() {
        return {
            user: null,
        };
    },
    created() {
        this.user = auth.getUser();
    },
}
<button
 type="button"
 v-if="user"
 @click="logout"
 class="btn btn-outline-light">

You can add this to your sidebar component, but it's usually better to handle authentication on the application root component or use Vuex because you often need to know whether or not you're logged in on multiple parts of the app.您可以将其添加到侧边栏组件中,但通常最好在应用程序根组件上处理身份验证或使用 Vuex,因为您经常需要知道您是否在应用程序的多个部分登录。

If you want to add the created() handler and user variable to your root component you can access it like so;如果您想将 created() 处理程序和用户变量添加到您的根组件,您可以像这样访问它;

<button
 type="button"
 v-if="$root.user"
 @click="logout"
 class="btn btn-outline-light">

Use computed property to bind with v-if like this:使用计算属性与 v-if 绑定,如下所示:

computed: {
  loggedIn () {
    return !(auth.getUser() === null)
  }
}

More here: https://v2.vuejs.org/v2/guide/computed.html更多信息: https://v2.vuejs.org/v2/guide/computed.html

Computed cannot be used here, a computed property will never update, because return.(auth.getUser() === null) is not a reactive dependency. Computed 不能在这里使用,计算属性永远不会更新,因为return.(auth.getUser() === null)不是反应性依赖。

In comparison, a method invocation will always run the function whenever a re-render happens.相比之下,只要发生重新渲染,方法调用将始终运行 function。 The solution then, is to re-render the side bar as documented by Michael Thiessen :然后,解决方案是重新渲染Michael Thiessen记录的侧栏:

<side-bar :key="loggedIn()"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM