vue 用户登录 路由拦截 vuex cookie

功能:

// 页面跳转后发送ajax请求给后端 请求详细信息

//点击课程推荐跳转到推荐课程详细

 // 页面刚加载立即执行函数 = mounted

<template>
  <div>
    <img :src="detail.img" />
    <h1>{{ detail.title }}</h1>
    <h3>{{detail.slogon }}</h3>
    <h5>{{ detail.level }}</h5>
    <p>{{ detail.why }}</p>
    <div>
      <ul v-for="item in detail.chapter">
        <li>{{ item.title }}</li>
      </ul>
    </div>
    <br/>
    推荐课程:
    <div>
      <ul v-for="item in detail.recommends">
        <!-- 这个方式有问题 -->
        <!-- <li><router-link :to="{name:'index',query:{id:item.id}}">{{ item.title }}</router-link></li> -->
        <li @click="changeDetail(item.id)">{{ item.title }}</li>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
  name: "CourseDetail",
  data() {
    return {
      index: "CourseDetail",
     
      detail: {
        course: null,
        img: null,
        level: null,
        slogon: null,
        title: null,
        why: null,
        chapter: [],
        recommends: []
      }
    };
  },
  // created:在模板渲染成html前调用
  mounted() {

    var id = this.$route.query.id;
    this.getRouterData(id);
    
  },
  methods: {
    getRouterData(nid) {

      // 发送ajax请求给后端 请求详细信息
      var _this = this;

      this.$axios
        .request({
          url: this.$store.state.apiList.coursedetail+nid+'/',
          methods: "GET"
        })
        .then(function(ret) {
          // ajax请求发送成功后,获取的响应内容
          // ret.data=
          if (ret.data.code === 1000) {
            _this.detail = ret.data.data;
          }
        })
        .catch(function(ret) {
          // ajax请求发送失败后,获取的响应内容
        });
    },
    //点击课程推荐跳转到推荐课程详细
    changeDetail(id){
      // 我需要重新调用getRouterData 向后端请求数据,不然不然会显示为空
      this.getRouterData(id)
      this.$router.push({name:'CourseDetail',query:{id:id}})


    }
  }
};
</script>

<style scoped>
</style>

 功能(2)

// 登录

//使用$store

// router.beforeEach 全局页面阻拦钩子

// router.beforeEach 局部认证钩子

// cookie 设置

// router.beforeEach 全局页面认证钩子

import Vue from 'vue'
import App from './App'
import router from './router'

// 导入store组件
import store from './store/store'

// 导入axios用于发送数据给后端
import axios from 'axios'
//在vue的全局变量中设置了 $axios = axios
// 以后每个组件使用时: this.$axios
Vue.prototype.$axios = axios


Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})


// 这是一个全局路由限制钩子 一般用来做一些进入页面前的限制
router.beforeEach(function(to, from, next){
  // to    表示即将要进入的路由对象
  //from   表示即将要离开的路由对象
  //next   是继续跳转或中断的方法
 // 如果路由meta.requireAuth参数 为ture 我需要检查下他的token值有才能让他访问 
  if (to.meta.requireAuth) {
//     // 要去的url只有登录成功后才能访问
    if (store.state.token){
//       // /我就往下走
      next()
    }else{
      next(
         // 页面跳转 传了个值 一个路径 ,to.fullPath = 你当前要点击要跳转的路径
         next({name: 'Login',query: {backUrl: to.fullPath}})
           
      )
    }
// 如果 路由中 没有定义要 校验限制进入,就直接进入
  }else{
    next()
  }
})

 cookie 设置 

import Vue from 'vue'
import Vuex from 'Vuex'
import Cookie from 'vue-cookies'

Vue.use(Vuex)


// 组件中通过 this.$store.state.username 调用
const state = {
    // Cookie里面有值的话我就在cookie里面取值,没有我就自动注销
        username: Cookie.get('username'),
        token: Cookie.get('token'),
        apiList: {
            course: "http://127.0.0.1:8000/api/v1/course/",
            coursedetail:`http://127.0.0.1:8000/api/v1/coursedetail/` ,
            auth:'http://127.0.0.1:8000/api/v1/auth/',


        },
    }

const mutations = {
    // 组件中通过this.$store.commit(参数)调用
    //设置kookie   
    saveToken(state, userToken) {
   
        // userToken 传过来的是一个对象,我可以通过点取值
        state.username = userToken.username;
        state.token = userToken.token;
        Cookie.set('username', userToken.username, "20min")
        Cookie.set('token', userToken.token, "20min")
    },
    // 清除 cookie
    clearToken: function (state) {
        state.username = null
        state.token = null
        Cookie.remove('username')
        Cookie.remove('token')
    }
}




export default new Vuex.Store({
    state,
    mutations,


})

功能(3)

// 登录 (登录后我就直接 跳转到他之前点击的页面)

<template>
    <div>
        <h1>登录页面</h1>
        <div>账号
            <input type="text" placeholder="请输入用户名" v-model="username">
        </div>
        <div>
            密码
            <input type="password" placeholder="请输入密码" v-model="password">
        </div>
        <div>
            <input type="button" value="登录" @click="doLogin">

        </div>

    </div>
</template>

<script>
export default {
    name:'Login',
    data(){
        return{
            username:'',
            password:'',
            
        }
    },
    methods:{
        doLogin:function(){
            var _this = this
      
            this.$axios.request({
                url:this.$store.state.apiList.auth,
                method:'POST',
                data:{
                    user:this.username,
                    pwd:this.password
                },
                headers:{
                    'Content-Type':'application/json'
                }
            }).then(function(arg){
                // 拿到后端的状态码进行判断
                if(arg.data.code === 1000){
                    // 把token 放到state中共享
                    // _this.$store.state.token = arg.data.token
                    //  _this.$store.state.username = _this.username

                    // saveToken 是一个参数,第二个参数我传了一个对象进去
                    _this.$store.commit('saveToken',{'token':arg.data.token,'username':_this.username})


             
                    //这个是我点击后发现没有登录 跳转过来的页面$route.query.backUrl是有值的
                    //登录后我就直接 跳转到他之前点击的页面
                    var url = _this.$route.query.backUrl
                    if(url){
                        _this.$router.push({path:url})
                    // 如果是直接登录的话 我就跳转到主页面
                    }else{
                        _this.$route.push({path:'/'})

                    }
                }else{
                    alert(arg.data.error)
                    
                }
               
            }).catch(function(arg){
                console.log(发生错误)

            })
        }
    }
}
</script>>

<style scoped>


</style>

  // (局部限制) 你必须带token 才能访问我

    mounted(){
        if(!this.$store.state.token){
            this.$router.push({name:'login'})
        }
    }

 路由中的设置

import Vue from 'vue'
import Router from 'vue-router'

// 引入路由页面
import Homepag from '@/components/Homepag'
import Course from '@/components/Course'
import CourseDetail from '@/components/CourseDetail'
import Login from '@/components/Login'
import FeatureLeesion from '@/components/FeatureLeesion'

//引入elment快速搭建
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';




//使用elment组件
Vue.use(ElementUI);

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Homepag',
      component: Homepag,
      meta:{
        requireAuth:true
      }
    },
    {
      path: '/course',
      name: 'Course',
      component: Course,
      meta:{
        requireAuth:true
      }
    },
    {
      path: '/coursedetail/:id',
      name: 'CourseDetail',
      component: CourseDetail,
      meta:{
        requireAuth:true
      }
    },
    {
      path: '/login',
      name: 'Login',
      component: Login,
      meta:{
        requireAuth:false
      }
    },
    {
      path: '/featureleesion',
      name: 'FeatureLeesion',
      component: FeatureLeesion,
      meta:{
        requireAuth:true
      }
    },
  ]
})
原文地址:https://www.cnblogs.com/Rivend/p/11987593.html