vue-router+vuex+localStorage导航守卫实例

使用localStorage模拟保存token,因为localStorage默认保存的是字符串,所以就限制保存isLogin为0就是未登录,要默认直接跳到/login页面,若为1就是默认到/home页面,没有localStorage的也是默认跳转到/login登录页

1.router.js--使用beforeEach前置导航判断是否要跳转/login页面

/* eslint-disable */
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import store from '@/store'

Vue.use(Router)

const router = new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      redirect: 'home',
      meta: {
        requiresAuth: true
      }
    },
    {
      path: '/home',
      name: 'home',
      component: Home,
      meta: {
        requiresAuth: true
      }
    },
    {
      path: '/login',
      name: 'login',
      component: () => import('@/components/common/login'),
      meta: {
        requiresAuth: false
      }
    },
    {
      path: '/about/:id',
      name: 'about',
      // route level code-splitting
      // this generates a separate chunk (about.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import('./views/About.vue'),
      meta: {
        requiresAuth: true
      }
    }
  ]
})
// 页面刷新时,重新赋值有没登录
if (window.localStorage.getItem('isLogin')) {
  store.commit('setIsLogin', localStorage.getItem('isLogin'));
}

router.beforeEach((to, from, next) => {
  //xxx-0隐式转换为数字
  console.log(typeof(store.state.isLogin-0),store.state.isLogin-0)
  if (to.matched.some(r => r.meta.requiresAuth)) {  // 判断该路由是否需要登录权限
    if (store.state.isLogin-0 === 1) {  // 通过vuex 如果当前有登录
      next();
    }
    else {
      alert("没有登录哦!")
      next({
        path: '/login',
        //query: {redirect: to.fullPath}
      })
    }
  }
  else {
    next();
  }
});


export default router

/*
1.单独一个routes数组用来存放路由变量,然后每一个路由对象都需要有个meta参数,里面有个requiresAuth(也可以命其他名),
这个就是用来判断这个页面需不需要判断权限,所以login页面为false,其他页面都为true。

2.new一个router对象,刚刚在注意点1的数组作为参数,然后最后导出这个router对象给其他页面引用。

3.要有一个判断页面刷新,重新赋值有没登录。
这个时候判断localStorage中的isLogin,如果为true,所以刷新前是有登录的,则提交触发vuex更改状态。

4.vue-router提供的钩子函数,在路由更换的时候,都会触发这个函数,这个时候就要用到注意点1的meta.requiresAuth,
如果即将要进入的页面需要判断登录权限,检测vuex的isLogin,为true就可以进去,不然都跳转到登录页面。
*/

2.main.js--引入router.js,store

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

Vue.config.productionTip = false
console.log(process.env.NODE_ENV)//打印看是开发环境还是发布环境//development

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

3.vuex部分store目录

1)index.js

import Vue from 'vue'
import Vuex from 'vuex'

import state from './state'
import getters from './getter'
import mutations from './mutation'
import actions from './action'

//Vue使用插件都要use一下
Vue.use(Vuex)


export default new Vuex.Store({
    strict: process.env.NODE_ENV !== 'production',
    state,
    getters,
    mutations,
    actions
})

2.state.js

let defaultLogin = 0
try {
    if(localStorage.isLogin) {
        defaultLogin = localStorage.isLogin
    } 
} catch (error) {
    
}

export default {
    isLogin: defaultLogin
}

3.mutations.js

export default {
    setIsLogin(state, isLogin) {
        state.isLogin = isLogin
        try {
            localStorage.isLogin = isLogin
        } catch (error) {
            
        }
            
    }
}

4.登出也loginout.vue

<template>
  <div class="hello">
    <div>
        <span class="el-dropdown-link">
          欢迎你,{{name}}
        </span>
        <section>
          <button @click="handleCommand('exit')">退出登录</button>
        </section>
      </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: '亲爱的!'
    }
  },
  methods: {

  },
  methods: {
    //退出登录
    handleCommand(command) {
      if(command === "exit") {
        // 触发setIsLogin方法改变vuex中isLogin的值,
        this.$store.commit('setIsLogin', 0);

        console.log('退出登录成功')
        this.$router.push('/login')
      }
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus">

</style>

5.登录页

<template>
    <div>
        <input type="text" placeholder="用户名" ref="user">
        <input type="text" placeholder="密码" ref="pwd">
        <button @click="handleSubmit">登录</button>
    </div>
</template>
<script>
export default {
    methods: {
        handleSubmit() {
            let user = this.$refs.user.value
            let pwd = this.$refs.pwd.value
            if(user === 'admin' && pwd == '123456') {
                console.log('登录成功!')
                this.$store.commit('setIsLogin', 1);
                this.$router.push('/home');
            }
            else {
                console.log('用户名或密码失败!')
                this.$store.commit('setIsLogin', 0);
            }
        }
    }
}
</script>
<style lang="stylus" scoped>

</style>

6.ps.与上述情景无关,增加vue-router的组件间守卫钩子例子

app.vue

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link :to="{path:'/about/'+id}">About</router-link>
      <router-link :to="{path:'/about/'+2}">About2</router-link>
    </div>

    <button @click="showDialog()">出现弹窗</button>
    <v-dialog>
      <dialog-one v-if="ifShow" v-model="ifShow"></dialog-one>
    </v-dialog>
    <router-view/>
  </div>
</template>
<script>
import {getPersonInfo} from '@/axios/api.js'
import VDialog from '@/components/common/dialog'
import DialogOne from '@/components/common/dialog/dialog1'
export default {
  created: async function () {
    const params = {
      phoneNumber: 12345678901
    };
    let res = await getPersonInfo(params);
    console.log(res);
  },
  mounted() {
    this.$nextTick(() => {
      console.log(this.$route.params)// 路由参数
    })
  },
  components: {
    VDialog,
    DialogOne
  },
  data() {
    return {
      ifShow: false,
      id: 1
    }
  },
  methods: {
    showDialog() {
      this.ifShow = true
    }
  }
}
</script>
<style lang="stylus">
html
  font-size 20px
</style>

about.vue


<template>
	<div>
  </div>
</template>
<script>
	export default {
    data() {
      return {

      };
    },
    beforeRouteEnter(to, from, next) {
      console.log('before route enter',to,from)
      next()
    },
    beforeRouteUpdate (to, from, next) {
      // 在当前路由改变,但是该组件被复用时调用
      // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
      // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
      // 可以访问组件实例 `this`
      console.log('before router update')
      this.name = to.params.name
      next()
    },
    //监听当前页面返回事件
    beforeRouteLeave(to, from, next) {
      console.log('before router leave')
      //next方法传true或者不传为默认历史返回,传false为不执行历史回退
      var r=confirm("确定要退出当前页面")
      if (r==true)
      {
        next(true);
      }else{
        next(false);
      }
    },
    methods: {

    }
	}
</script>

<style>

</style>

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值