vue通過vue-router攔截實現登入驗證

przlovecsdn發表於2018-08-31

在實際開發中,有些頁面需要登入之後才能訪問,採用vue-router+vuex+elememt-ui+axios的方式實現。

以下是案列程式碼:

login.vue

<template>
  <div class="login">
    <el-input type="text" v-model="username" placeholder="請輸入使用者名稱"></el-input>
    <el-input type="password" v-model="userpsd" placeholder="請輸入密碼"></el-input>
    <el-button type="primary" @click="toLogin">登入</el-button>
  </div>
</template>

<script>
  import {mapActions,mapState} from 'vuex'
  export default {
    name: 'login',
    props: [''],
    data() {
      return {
        username: "",
        userpsd: "",
      };
    },

    computed: {
      ...mapState(["userinfo", "isLogin"])
    },

    mounted() {
      console.log(this.$route.params.path);
    },

    methods: {
      ...mapActions(["getUserInfo"]),
      toLogin() {
        if (this.username == "") {//自行驗證使用者名稱規則
          return;
        } else if (this.userpsd == "") {//自行驗證密碼規則
          return;
        } else {
          let data = {};
          data.username = this.username;
          data.password = this.userpsd;
          this.getUserInfo(data).then(() => {
              if (this.isLogin) {
                //若是使用使用者資訊,則本地儲存使用者資訊,根據需求自行使用本地儲存方式
                sessionStorage.setItem("userinfo", JSON.stringify(this.userinfo));
                //是否登入的標誌位
                sessionStorage.setItem("isLogin", true);
                //登入成功後返回訪問的頁面
                this.$router.push({
                  path: this.$route.params.path
                });
              } else {//登入未成功to do sth
                sessionStorage.setItem("userinfo", '');
                sessionStorage.setItem("isLogin", '');
              }
            })
            .catch(err => {
              console.log(err);
            });

        }
      },
    }

  }

</script>
<style lang='' scoped>
  .login .el-input {
    margin: .5rem 0;
  }

  .login .el-button--primary {
    width: 100%;
    margin: .5rem 0;
  }

</style>

router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import store from '../store/index'
const home = r => require.ensure([], () => r(require('@/components/home')), 'home');
const personCenter= r => require.ensure([], () => r(require('@/components/personCenter')), 'personCenter');
const login = r => require.ensure([], () => r(require('@/components/login')), 'login');
const notFound = r => require.ensure([], () => r(require('@/components/notFound')), 'notFound');

Vue.use(Router);
const router = new VueRouter({
    routes: [{
            path: '/home',
            name: 'home',
            component: home
        },
        {
            path: '/personCenter',
            name: 'personCenter',
            component: personCenter,
            meta: {
                need2Login: true
            }
        },
        {
            path: '/login',
            name: 'login',
            component: login,
        },
        {
            path: "/404",
            name: "notFound",
            component: notFound
        },
        {
            path: "*", // 此處需特別注意置於最底部
            redirect: "/404"
        },

    ]

})
router.beforeEach((to, from, next) => { //全域性鉤子函式
    to.matched.some((route) => {
        // to.matched.forEach((route) => {
        if (route.meta.need2Login) { //通過此操作可以判斷哪些頁面需要登入
            if (store.state.isLogin || sessionStorage.getItem('isLogin')) {
                next()
            } else {
                next({ name: 'login', params: { path: route.path } })
            }
        } else {
            next();
        }
    });

});
export default router;

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import actions from './action'

Vue.use(Vuex);

const state = {
    userinfo: {}, //登入資訊
    isLogin: '', //是否已登入
}

export default new Vuex.Store({
    state,
    actions,
    mutations,
})

store/mutation-types.js

export const GETUSERINFO = 'GETUSERINFO'

store/action.js

import {login} from '@/service/api'
export default {
    async getUserInfo({ state, commit }, payload) {
        let res = await login(payload);
        if (res.result.code === 10000) {//登入成功dispatch
            commit('GETUSERINFO', { info: res.data, isLogin: true })
        } else {
            commit('GETUSERINFO', { info: res, isLogin: false })
        }

    }
}

store/mutations.js

import { GETUSERINFO } from './mutation-types'

export default {
    [GETUSERINFO](state, { info, isLogin }) {
        state.userinfo = info;
        state.isLogin = isLogin;
    }
}

service/api.js

import ajax from './apiConfig';

export const login = (data) => {
    return ajax.post('/app/login', data)
}

service/apiConfig.js

import axios from 'axios';
import qs from 'qs';

// 設定 POST 請求頭
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

// 在向伺服器傳送前,修改請求資料(只能用在 'PUT', 'POST' 和 'PATCH' 這幾個請求方法)
axios.defaults.transformRequest = [(data) => { return qs.stringify(data) }]


// 在傳遞給 then/catch 前,允許修改響應資料
// axios.defaults.transformResponse = [(data) => { return JSON.parse(data) }]

// 配置 CORS 跨域
// 表示跨域請求時是否需要使用憑證
axios.defaults.withCredentials = true;

axios.defaults.crossDomain = true;

// 設定超時
axios.defaults.timeout = 40000;


// 攔截器的說明
// 1、interceptor必須在請求前設定才有效。
// 2、直接為axios全域性物件建立interceptor, 會導致全域性的axios發出的請求或接收的響應都會被攔截到, 所以應該使用axios.create() 來建立單獨的axios例項。
//設定地址
const baseUrl='';

// 建立axios例項
let instance = axios.create({
    baseURL: baseUrl
})


// Add a request interceptor
instance.interceptors.request.use(function(config) {
    return config;
}, function(error) {
    return Promise.reject(error);
});

// Add a response interceptor
instance.interceptors.response.use(function(response) {
    // Do something with response data

    return response.data;
}, function(error) {
    // Do something with response error

    return Promise.reject(error);
});

 export { instance };

 

相關文章