Vue компонент не перерисовывается / обновляется - PullRequest
0 голосов
/ 15 октября 2019

У меня есть заголовок страницы (Navbar), на котором есть ссылка [LOG IN], и, щелкая по ней, вы переходите к / логину маршрута. Компонент 'login' показывает модальную форму и аутентифицирует / login () пользователя, после чего маршрут снова устанавливается на домашнюю страницу. В это время заголовок [LOG IN] должен измениться на ["loggedinUser"], но это не так. Вот код

(использует bootstrap-vue для css)

. / App.vue

<template>

  <component :is="layout">
    <router-view :layout.sync="layout"/>
  </component>

</template>

<script>

export default {
  name: 'App',

  data () {
    return {
      layout: 'div'
    }
  }

}
</script>

. / Components/BaseLayout.vue

<template>
<div>
    <Header/>
    <slot />
    <Footer/>
</div>
</template>

<script>

import Header from './Header'
import Footer from './Footer'

export default {
  name: 'BaseLayout',

  props: [],

  components: { Header, Footer },

  methods: {}
}
</script>

Navbar отображается через этот компонент. . / Components / Header.vue

<template>
  <b-navbar
    type="dark"
    variant="dark"
    fixed="top"
    class="text-monospace text-white"
  >
    <b-navbar-brand to="/">MyWebapp</b-navbar-brand>

    <b-navbar-toggle target="nav-collapse"></b-navbar-toggle>

    <b-collapse id="nav-collapse" is-nav>
      <b-navbar-nav>
        <b-nav-item href="#" disabled>DISABLED</b-nav-item>
      </b-navbar-nav>

      <!-- Right aligned nav items -->
      <b-navbar-nav class="ml-auto">

        <b-nav-item to="/about">ABOUT</b-nav-item>

        <header-user></header-user>

      </b-navbar-nav>
    </b-collapse>

  </b-navbar>
</template>

<script>
import HeaderUser from '@/components/HeaderUser.vue'

export default {
  components: { HeaderUser }
}
</script>

"header-user" ранее был частью Header, но я сделал его отдельным компонентом.

./HeaderUser.vue

<template>
    <div>
        <b-nav-item
          v-show="!isAuthenticated"
          @click="signin"
        >&lbbrk;LOG IN&rbbrk;
        </b-nav-item>

        <b-nav-item-dropdown
          v-show="isAuthenticated"
        >
          <template slot="button-content">&lbbrk;{{ loggedinUser }}&rbbrk;</template>
          <b-dropdown-item href="#" disabled>profile</b-dropdown-item>
          <b-dropdown-item @click="signout">log off</b-dropdown-item>
        </b-nav-item-dropdown>
    </div>
</template>

<script>

import { mapGetters, mapActions } from 'vuex'

export default {
  name: 'HeaderUser',

  data () {
    return {
      authenticated: false
    }
  },

  methods: {
    ...mapActions('user', ['logout']),

    signin () {
      this.$router.push('/login')
    },

    signout () {
      // this.$store.dispatch('logout')
      this.logout()
      this.authenticated = false
      this.$router.push('/landingpage')
    }

  },

  computed: {
    ...mapGetters('user', ['isAuthenticated', 'getCurrentUser']),

    loggedinUser: function () {
      if (this.getCurrentUser) {
        return this.getCurrentUser['name'].toUpperCase()
      } else {
        return null
      }
    }

  }

}
</script>

Вот компонент входа в систему

. / Pages / Login.vue

<template>
    <div>
    <b-modal
      size="lg"
      id="loginModal"
      title="Credentials"
      hide-footer
      centered
      no-close-on-backdrop
      >
        <b-form inline>

        <b-input
            class="mb-2 mr-sm-2 mb-sm-0"
            id="usernameInput"
            placeholder="Lab user id"
            v-model="loginForm.user"
        />

        <b-input
            type="password"
            id="passwordInput"
            placeholder="Unikix domain password"
            v-model="loginForm.password"
        />

        <b-button @click="authenticate">Submit</b-button>
        </b-form>
    </b-modal>
  </div>
</template>

<script>
import { mapActions } from 'vuex'

export default {
  name: 'Login',

  data () {
    return {
      loginForm: {
        user: '',
        password: '',
        rememberChecked: ''
      }
    }
  },

  methods: {
    ...mapActions('user', ['login']),

    authenticate () {
      this.login(this.loginForm)
        .then(() => {
          this.$emit('authenticated', true) // But who's catching?
          this.$router.push('/landingpage')
        })
        .catch(e => {
          this.$router.push('/404')
        })
    },

  },

  mounted () {
    this.$bvModal.show('loginModal')
  }
}
</script>

Так как Header и Login являются отдельными компонентами (никаких отношений), я не могу общаться между ними. После успешного входа и изменения состояния заголовок не узнает об этом и не реагирует на него. [ВХОД] остается без изменений.

Как я могу решить эту проблему?

(после успешного входа в систему, если я перезагружаю страницу в браузере, заголовок корректно отображается с "loggedinUser".

1 Ответ

0 голосов
/ 16 октября 2019

Ваш магазин предназначен для обмена информацией между компонентами.

По умолчанию геттеры должны реагировать, поэтому ваш геттер isAuthenticated должен отражаться во всех компонентах при его изменении, однако это зависит от того, как вы пишетеваши геттеры.

Если вы добавляете свойства к объектам на лету в своем штате, вам нужно использовать Vue.Set / this. $ set

Попробуйте ивзгляните на этот пример, он может вам помочь.

https://codesandbox.io/s/vuex-store-yhyj4

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...