Navbar не обновляется при успешном входе пользователя - PullRequest
0 голосов
/ 28 июня 2019

Я строю свой первый проект Vue-Cli 3 с Rails 6 Api в качестве бэкэнда.

У меня есть компонент навигации, который должен обновляться при успешном входе пользователя, прямо сейчас, когда пользователь входит в него, перенаправляет на панель пользователя, но навигация остается в виде просмотра навигации. Это успешно изменится, когда я заставлю обновить страницу.

Быть настолько новым для Vue, это может быть небольшой проблемой, однако я изо всех сил пытаюсь найти какие-либо ссылки на эту проблему.

Я использую Axios Axios-Vue и JWTSessions для обработки токенов / сессий

вот мой код компонента Navigation.vue:

<template>
  <div class="font-sans antialiased">
    <nav class="flex items-center justify-between flex-wrap bg-loadze-blue p-6 fixed w-full">
      <div class="flex items-center flex-no-shrink text-gray-900 mr-6">
        <span class="font-semibold text-xl tracking-tight text-white">Loadze.co</span>
      </div>
      <div class="block sm:hidden">
        <button @click="toggle" class="flex items-center px-3 py-2 border rounded text-teal-lighter border-teal-light hover:text-white hover:border-white">
          <svg class="fill-current h-3 w-3" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><title>Menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg>
        </button>
      </div>
      <div :class="open ? 'block': 'hidden'" class="w-full flex-grow sm:flex sm:items-center sm:w-auto">
        <div class="text-sm sm:flex-grow">
          <router-link to="/home" class="no-underline block mt-4 sm:inline-block sm:mt-0 text-teal-lighter hover:text-white mr-4" v-if="!signedIn()">Home</router-link>
          <router-link to="/about" class="no-underline block mt-4 sm:inline-block sm:mt-0 text-teal-lighter hover:text-white mr-4" v-if="!signedIn()">About</router-link>
          <router-link to="/features" class="no-underline block mt-4 sm:inline-block sm:mt-0 text-teal-lighter hover:text-white mr-4" v-if="!signedIn()">Features</router-link>
          <router-link to="/pricing" class="no-underline block mt-4 sm:inline-block sm:mt-0 text-teal-lighter hover:text-white mr-4" v-if="!signedIn()">Pricing</router-link>
          <router-link to="/contact" class="no-underline block mt-4 sm:inline-block sm:mt-0 text-teal-lighter hover:text-white mr-4" v-if="!signedIn()">Contact Us</router-link>
        </div>
        <div>
          <router-link to="/signup" class="text-sm no-underline block mt-4 sm:inline-block sm:mt-0 text-teal-lighter hover:text-white mr-4" v-if="!signedIn()">Sign up</router-link>
          <router-link to="/signin" class="text-sm no-underline block mt-4 sm:inline-block sm:mt-0 text-teal-lighter hover:text-white mr-4" v-if="!signedIn()">Sign in</router-link>
          <a href="#" @click.prevent="signOut" class="text-sm no-underline block mt-4 sm:inline-block sm:mt-0 text-teal-lighter hover:text-white mr-4" v-if="signedIn()">Logout</a>
        </div>
      </div>
    </nav>
  </div>
</template>

<script>
export default {
  name: 'Navigation',
  data () {
    return {
      open: false
    }
  },
  methods: {
    toggle () {
      this.open = !this.open
    },
    setError (error, text) {
      this.error = (error.response && error.response.data && error.response.data.error) || text
    },
    signedIn () {
      return localStorage.signedIn
    },
    signOut () {
      this.$http.secured.delete('/signin')
        .then(response => {
          delete localStorage.csrf
          delete localStorage.signedIn
          this.$router.replace('/')
        })
        .catch(error => this.setError(error, 'Can not sign out'))
    }
  }
}
</script>

<style>

</style>

и это компонент Signin.vue (скрипт, код формы длинный .. пожалуйста, дайте мне знать, если вам нужно его увидеть) code:

<script>
export default {
  name: 'Signin',
  data () {
    return {
      email: '',
      password: '',
      error: ''
    }
  },
  created () {
    this.checkSignedIn()
  },
  updated () {
    this.checkSignedIn()
  },
  methods: {
    signin () {
      this.$http.plain.post('/signin', { email: this.email, password: this.password })
        .then(response => this.signinSuccessful(response))
        .catch(error => this.signinFailed(error))
    },
    signinSuccessful (response) {
      if (!response.data.csrf) {
        this.signinFailed(response)
        return
      }
      localStorage.scrf = response.data.csrf
      localStorage.signedIn = true
      this.error = ''
      this.$router.replace('/dashboard')
    },
    signinFailed (error) {
      this.error = (error.response && error.response.data && error.response.data.error) || ''
      delete localStorage.csrf
      delete localStorage.signedIn
    },
    checkSignedIn () {
      if (localStorage.signedIn) {
        this.$router.replace('/dashboard')
      }
    }
  }
}
</script>

Ответы [ 2 ]

2 голосов
/ 29 июня 2019

Вы используете функцию для своего условного отображения (v-if="!signedIn()"), но функция ничего не возвращает, что означает, что в шаблоне ничего не визуализируется реактивно.

Попробуйте добавить новое свойство данных, которое можно обновить при входе:

<template>
  ...
  <div class="text-sm sm:flex-grow">
    <router-link to="/home" v-if="!isSignedIn">Home</router-link>
    <router-link to="/about" v-if="!isSignedIn">About</router-link>
    <router-link to="/features" v-if="!isSignedIn">Features</router-link>
    <router-link to="/pricing" v-if="!isSignedIn">Pricing</router-link>
    <router-link to="/contact" v-if="!isSignedIn">Contact Us</router-link>
  </div>
  ...
</template>
<script>
export default {
  name: 'Signin',
  data () {
    return {
      email: '',
      password: '',
      error: '',
      isSignedIn: false // <= here
    }
  },
  //...
  methods: {
    signin () {
      this.$http.plain.post('/signin', { email: this.email, password: this.password })
        .then(response => {
          this.signinSuccessful(response)
          this.isSignedIn = true // <= and here
        }).catch(error => this.signinFailed(error))
    },
    //...
  }
}
</script>

Затем в функции выхода из системы вы можете установить для isSignedIn значение false.

1 голос
/ 28 июня 2019

Чтобы ваш объект localStorage был реактивным, он должен быть частью данных компонентов или вычисляемых свойств. Самым простым решением было бы сохранить состояние аутентификации в vuex и затем передать его своим компонентам с помощью vuex mapGetter. Затем вы обновляете состояние с помощью действия vuex, когда пользователь входит в систему. Если вы не знакомы с vuex, на их веб-сайте есть пример, которого должно быть достаточно для этого.

...