nuxt + ts +vue简单后台项目,记录一些在做的过程中遇到的问题。

一、nuxt框架是一个前端框架,这个框架我的理解就是有利于seo,就是在被人百度的时候,会优先搜索到这个框架的网站。

二、主要问题:

1.登录

主要是在页面要先进行一些验证,数据请求的时候,必须携带正确的token才能请求数据,于是涉及到token的保存,需要通过接口获取到用户信息和token,再保存在store中,因为刷新页面,store就清空了,我就采用了localStorage保存信息。

首先是在page/login.vue获取用户信息和token

export default class AdminLogin extends Vue {
  private name: string = 'admin'
  private password: string = 'admin'

  // 登录
  private userLogin () {
    const data: object = {
      name: this.name,
      password: Md5.hashStr(this.password)
    };
    this.$axios.post('/api/v1/login', data).then((res: any) => {
      if (res.success) {
        this.$store.commit('SET_TOKEN', res.data.token);
        this.$store.commit('SET_USERINFO', { name: res.data.name });
        window.localStorage.setItem('unserAllInfo', JSON.stringify(res.data));
        this.$router.push('/admin/'); // 跳转
      } else {
        this.$message.error({ message: '登录失败,请输入正确的用户名和密码' });
      }
    });
  }
}

store/index.js

import Vuex from 'vuex';

const store = () => new Vuex.Store({
  state: {
    userInfo: {},
    token: ''
  },
  mutations: {
    SET_TOKEN (state, data) {
      state.token = data || '';
    },
    SET_USERINFO (state, data) {
      state.userInfo = data || {};
    }
  },
  actions: {
    // nuxtServerInit ({ commit }, { req }) {
    //   const cookie = req.headers.cookie;
    // }
  },
  getters: {
    token: (state) => {
      return state.token;
    },
    getuserInfo: (state) => {
      return state.userInfo;
    }
  }
});

export default store;

在layout/admin.vue下面使用,防止刷新的时候store数据清空

private async created () {
      // 设置登录和token信息,防止刷新的时候store清空
      const userInfo = window.localStorage.getItem('unserAllInfo') || null;
      if (userInfo) {
        const data = JSON.parse(userInfo);
        this.$store.commit('SET_TOKEN', data.token);
        this.$store.commit('SET_USERINFO', data);
      } else {
        this.$router.push('/admin/login');
      }
    }

使用$store.getters.getuserInfo.name 可获取信息

如果要退出登录,清空localStorage即可

// 退出登录
    // GoOut() {
    //   window.localStorage.setItem('wmMonitorUsers', '')
    //   this.$router.push('/admin/login')
    // }

在登录完成以后,我们每次发起数据请求的时候就需要带上token,于是在plugins下面对axios的请求进行了封装axios.js,需要在配置里面全局引用一下,在nuxt.config.js下加入以下代码

plugins: [
    { src: '@/plugins/axios' },
  ]

在plugins/axios.js写如下内容,都是抄的其他大神的。

export default function ({ $axios, redirect, store }) {
  // http request 拦截器
  $axios.interceptors.request.use(
    (config) => {
      if (store.getters.token) {
        config.headers.Authorization = 'Bearer ' + store.getters.token;
      } else {
        config.headers.Authorization = '';
      }
      return config;
    },
    (err) => {
      return Promise.reject(err);
    });

  // http response 拦截器
  $axios.interceptors.response.use(
    (response) => {
      // 直接返回内容
      if (response.success) {
        return response.data;
      }
      return response.data;
    },
    (error) => {
      // store.commit(types.SET_LOAD, false);
      if (error.response) {
        const code = parseInt(error.response && error.response.status);
        switch (code) {
          case 401:
            sessionStorage.clear();
            redirect('/admin/login');
            console.log(401);
            break;
          case 403:
            sessionStorage.clear();
            redirect('/admin/login');
            console.log(403);
            break;
          case 404:
            sessionStorage.clear();
            console.log(404);
            break;
          case 500:
            // Message.error('Server exception');
            break;
          case 502:
            // Message.error('Bad Gateway');
            break;
          case 503:
            // Message.error(error.message);
            break;
          case 504:
            // Message.error(error.message);
            break;
          default:
            break;
        }
      }
      // console.error(error.config.url, error.response.status)
      return Promise.reject(error);
    });
}

接下来就是在页面,直接发起请求即可,为什么直接发起请求就可以了呢,因为我重新对axios进行了封装,在配置文件加载的时候就行了了这个操作,于是接下来在各个页面直接请求即可。

例如在page下面的vue文件中发起请求:

this.$axios.post('/api/v1/接口', { data: data }).then((res: any) => {
        if (res.success) {
          this.$message.success('保存成功!');
        } else {
          this.$message.error({ message: '保存失败!' });
        }
      });

2.讲讲路由方面,我使用了<nuxt-link to="/admin/product"></nuxt-link>跳转,内容在<nuxt />中显示,跟vue的路由用起来一模一样。

nuxt的路由很方便,就是page下面的vue页面的名字,相当于他自动给你配置了路由,而你直接使用地址跳转就可以。layout里面放的是布局文件,就是你框架的整体结构,比如你从layout里面的index要跳转到page下面的product.vue,只需在to后面加上/product即可。

传参的路由,我要跳转到动态路由_id页面,我需要传参id过去,下面代码相当于admin/news/id,这个id是动态的,params是我传过去的id,跳转到的_id页面到时候路由显示就是admin/news/传过来的params里面的id

文件结构

nuxt + ts +vue简单后台项目,记录一些在做的过程中遇到的问题。

          <nuxt-link :to="{name:'admin-news-id', params:{id: item._id}}">{{ item.title }}</nuxt-link>

动态路由_id页面里面获取id:this.$route.params.id,然后在根据id请求一些需要的数据

3.配置文件nuxt.config.js,我主要是配置了这些。env是配置一个全局的服务器地址,比如,我要渲染从服务器拿到的图片或其他资源,我的写法是src=process.env.serverUrl + 服务器存数据的地址,例如'/public/img/a.img',这样就可以渲染出服务器上的图片了。

module.exports = {
proxy: {
    '/api': {
      target: 'http://172.16.5.248:7001', // 目标接口域名
      changeOrigin: true, // 表示是否跨域
      pathRewrite: {
        '^/api': '' // 把 /api 替换成‘’
      }
    }
  },
  /*
    ** Axios module configuration
    ** See https://axios.nuxtjs.org/options
    */
  axios: {
    // See https://github.com/nuxt-community/axios-module#options
    proxy: true, // 表示开启代理
    prefix: '/api', // 表示给请求url加个前缀 /api
    credentials: true // 表示跨域请求时是否需要使用凭证
  },
  /*
    ** Build configuration
    */
  env: {
    serverUrl: 'http://172.16.5.248:7001' // 自己的服务器地址配置
  },
}

 

上一篇:NuxtJS项目——配置


下一篇:nuxtjs如何在单独的js文件中引入store和router