首页 文章

Vue 2 Mixins用于全局功能

提问于
浏览
0

我想在应用程序和路由中实现一个简单的auth mixin进行全局身份验证 . auth mixin具有 loggedIn 数据,该数据为True或False,以及两个登录和注销功能 . 整个应用程序基于vue路由器webpack模板 . 问题是 loggedIn 状态不会被保存 . 因此,当我转到Login.vue并登录时, loggedIn 将被设置为true,但是当我再次转到Login.vue组件时,checkStatus函数将再次将 loggedIn 记录为 false .

我怎么能够

这是我的混音:

Auth.js

export default {
  data() {
    return {
      loggedIn: false
    }
  },
  methods: {
    logIn(user,password) {
      return new Promise((resolve, reject) => {
        console.log("Logging in ", user, password);
        this.loggedIn = true;
        resolve()
      })
    },
    logOut(){
      return new Promis ((resolve, reject) => {
        console.log("Logging out");
        this.loggedIn = false;
        resolve();
      })
    }
  }
};

main.js

import Vue from 'vue'
import App from './App'
import router from './router'
import Utils from "./mixins/Utils"
import Auth from "./mixins/Auth"

// Load mixins
Vue.mixin(Auth);
Vue.mixin(Utils);

// This part redirects to login page when authentication is needed
router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth) && this.loggedIn) {
    next({ path: '/login', query: { redirect: to.fullPath }});
  } else {
    next();
  }
});

Login.vue

<template>
  <div>
    <form class="form-signin">
      <h1 class="mb-3">Please sign in</h1>
      <label for="inputEmail" class="sr-only">Email address</label>
      <input type="email" id="inputEmail" v-model="email" class="form-control" placeholder="Email address" required autofocus>
      <label for="inputPassword" class="sr-only">Password</label>
      <input type="password" id="inputPassword" class="form-control" placeholder="Password" required v-model="password">
      <div class="checkbox mb-3">
        <label>
          <input type="checkbox" value="remember-me"> Remember me
        </label>
      </div>
      <button class="btn btn-lg btn-primary btn-block" type="submit" v-on:click="checkCredentials">Sign in</button>
    </form>
    <div class="mb-3" style="text-align: center">
      <label>
        <router-link to="/signup">Not registerd yet? Sign up!</router-link>
      </label>
    </div>
    <notifications position="bottom center" group="notifications" />
  </div>
</template>


<script>

  export default {
    name: 'Login',
    methods: {
      checkCredentials(event) {
        event.preventDefault();
        if (this.email.length <= 0 || !this.email) {
          this.notify("Enter email", "warn")
          return;
        }
        if (this.password.length <= 0 || !this.password) {
          this.notify("Enter password", "warn");
          return;
        }
        this.performLogin(this.email, this.password);
      },
      performLogin(mail, password) {
        let x = this;
        this.logIn(mail, password)
          .then(function (result) {
            x.notify("Logged in as " + mail, "success");
            if (x.loggedIn) {
              console.log("[LOG] redirecting");
              x.$router.push(x.$route.query.redirect || '/');
            }
          })
          .catch(function (error) {
            document.cookie = "Test";
            x.notify("Error loggin in (" + error + ")", "error");
          })
      },
      checkStatus() {
        this.$log.info("Checking status", this.loggedIn)
        if (this.loggedIn) {
          this.$router.push(this.$route.query.redirect || "/");
        }
      }
    },
    data() {
      return {
        email: "",
        password: ""
      }
    },
    created() {
      this.checkStatus()
    }
  }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .form-signin {
    width: 100%;
    max-width: 330px;
    padding: 15px;
    margin: auto;
  }

  .form-signin .checkbox {
    font-weight: 400;
  }

  .form-signin .form-control {
    position: relative;
    box-sizing: border-box;
    height: auto;
    padding: 10px;
    font-size: 16px;
  }

  .form-signin .form-control:focus {
    z-index: 2;
  }

  .form-signin input[type="email"] {
    margin-bottom: -1px;
    border-bottom-right-radius: 0;
    border-bottom-left-radius: 0;
  }

  .form-signin input[type="password"] {
    margin-bottom: 10px;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
  }
</style>

1 回答

  • 1

    问题是不会保存loggedIn状态 .

    确切地说,Mixins不是用于管理它们应该用于需要在组件中重用的函数/方法的状态,以维持'd need a state management system and Vue provides one, it'所称的状态 .

    使用Vuex,您可以定义一个初始状态,在您的情况下是否用户已登录,我建议您通过Vuex Docs一次

    这是一个简短的例子,说明它如何解决你的问题,

    const store = new Vuex.Store({
     state: {
      loggedIn: false
     },
     mutations: {
      logInUser (state) {
      state.loggedIn = true
     }
    }
    })
    
    /* Pass the store to your Vue App */
    const app = new Vue({
      el: '#app',
    
      // this will inject the store instance to all child components.
      store,
      components: { App },
      ..........
    

    现在,这个状态将在整个组件中可用,除非您手动从某个地方提交更改,否则不会更改 .

    Login.vue

    this.$store.commit('logInUser', true)
    

    someOtherComp.vue

    console.log(this.$store.state.loggedIn) // true
    

相关问题