zoukankan      html  css  js  c++  java
  • vue拦截器和vue-cookies

    vue 拦截器

    假设现在有这么一个需求,页面上有些url需要登录之后才能访问,没有登录访问自动跳转到登录页面。之前项目前后端未分离的时候,直接从session中去匹配,能匹配到则render页面,没匹配成功表示没有登录则redirect到login页面。现在项目统一采用vue + restframework的方式,写vue的感觉就像是在写后台了,哈哈。在vue就能做到这个功能,但是需要后台也做最后一层屏障。因为vue是根据浏览器的cookie是否有token,后台需要判断这个token是不是合法的,至于cookie中没有token就更加走不到后台了。

    main.js

    在main.js底部加如下代码

    router.beforeEach(function (to, from, next) {
      if(to.meta.requireAuth){
        if (store.state.token) {
          next()
        } else {
          next({name: 'login',query: {next_url: to.fullPath}})
        }
      }else{
        next()
      }
    });
    

    index.js

    在router的index.js里的每个路由加上meta:{requireAuth:true}, meta是固定的,requireAuth是随意取的

    export default new Router({
      routes: [
        {
          path: '/index',
          name: 'index',
          component: index,
          meta:{
            requireAuth:true
          }
        },
        {
          path: '/course/:id',
          name: 'course',
          component: course
        }]
    

    上述表述index页面需要登录才能查看

    vue-cookies

    安装 npm install vue-cookies --save
    store目录下的store.js的内容

    import Vue from 'vue'
    import Vuex from 'vuex'
    import Cookie from 'vue-cookies'
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      // 组件中通过 this.$store.state.username 调用
      state: {
        token:Cookie.get('token'),
      },
      mutations: {
        saveToken(state, token){
          state.token = token;
          Cookie.set('token', token, '20min')
        },
        clearToken(state){
          Cookie.remove('token');
          state.token = null;
        }
      }
    })
    

    在main.js直接import store from './store/store'把store挂载到Vue实例中即可。

    axios发送请求

    安装npm install axios
    在main.js加上两句

    import axios from 'axios'
    Vue.prototype.$axios = axios;
    

    Login.vue组件

    <template>
      <div>
         <div v-if="this.$store.state.token">
            <h3>登录成功</h3>
         </div>
    
        <div v-else>
          <h3>登录页面</h3>
          <input type="text" v-model="name"/>
          <input type="password" v-model="pwd"/>
          <button @click="login">登录</button>
        </div>    
      </div>
    
    </template>
    
    <script>
    export default {
      name: 'Login',
      data () {
        return {
          name:'',
          pwd:''
        }
      },
      computed:{
    
      },
      methods:{
        login(){
          var that = this;
          this.$axios.request({
            url:'http://127.0.0.1:8000/api/v1/account/login/',
            method:'post',
            data:{
              name:this.name,
              pwd:this.pwd
            }
          }).then(function (ret) {
              if (ret.data.code === 1000){
                that.$store.commit('saveToken', ret.data.data)
                let url = that.$route.query.next_url;
                if (url){
                  that.$router.push({path: url})
                }else {
                  that.$router.push({path: '/index'})
                }
              }else {
                console.log(ret.data.error)
              }
          }).catch(function (ret) {
            console.log('发生错误')
          })
        }
      },
      created(){
    
      }
    }
    
    </script>
    
    <style scoped>
    
    </style>
    

    同url不同标识的处理

    页面组件的销毁和加载有这么一个特点,假设原url是/detail/1, 这时候在这个页面用router-link得到的/detail/2进行点击,发送浏览器地址栏发生改变,但是页面并没有重新加载,这时候可以使用绑定事件+this.$router.push({})方式解决

    <script>
    export default {
      name: 'detail',
      data () {
        return {
          detail:{
    
            }
        }
      },
      created(){
        var nid = this.$route.params.id;
        this.getDetail(nid);
      },
      methods:{
        getDetail(nid){
          var that = this;
          this.$axios.request({
            url:'http://127.0.0.1:8000/api/v1/course/' + nid + '/',
            method: 'get'
          }).then(function (ret) {
            that.detail = ret.data.data;
          }).catch(function (ret) {
            console.log('error')
          })
        },
        changeDetail(nid){
          this.getDetail(nid);
          this.$router.push({name: 'detail', params:{id:nid}})
        }
      }
    }
    </script>
    

    切换保持active样式

    <template>
      <nav class="navbar navbar-default">
      <div class="container-fluid">
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
          <ul class="nav navbar-nav">
            <li :class="{active: i == currentIndex}" v-for="(route,i) in routes" @click="changeActive(i)">
              <router-link :to="route.url">{{ route.title }}</router-link>
            </li>
          </ul>
        </div>
      </div>
    </nav>
    </template>
    
    <script>
    export default {
      name: 'Vheader',
      data () {
        return {
          routes:[
            {url:'/', title: '首页'},
            {url:'/note', title: 'note'}
          ],
          currentIndex:0
        }
      },
      methods:{
        changeActive(i){
          this.currentIndex = i;
        }
      },
      created(){
        // console.log(this.$route)
        for (var i=0;i<this.routes.length;i++){
          if (this.routes[i].url === this.$route.path) {
            this.currentIndex = i;
          }
        }
      }
    }
    </script>
    
    <style scoped>
    </style>
    
  • 相关阅读:
    Neo4j
    linux系统中如何建立与删除软连接(方便快捷使用,大量节约时间)
    eclipse/myeclipse 中,如何删除已经下载过的插件(举例:删除scala ide)
    dayday up
    元类
    sort和sorted
    反射
    继承派生
    property
    python3.5和3.6区别
  • 原文地址:https://www.cnblogs.com/longyunfeigu/p/9372013.html
Copyright © 2011-2022 走看看