乐趣区

关于前端:nuxtjs-typescript项目开发总结

一、axios

倡议间接应用 nuxtjsaxios模块。

1. 装置并引入@nuxtjs/axios

须要代理请一并装置引入@nuxtjs/proxy

nuxt.config.js 中:export default {
    modules:[
        '@nuxtjs/axios',
        '@nuxtjs/proxy'
    ],
    axios: {
        proxy: true,
        baseURL: '',
        prefix: '/api-prefix',
        credential: true
    },
    proxy: {
        '/api-prefix': {
            target: 'http://...',
            changeOrigin: true,
            pathRewrite: {
                '^/api-prefix': '',
                changeOrigin: true
            }
        }
    },
    ...
}

2.axios 拦挡

plugins 目录下,新增 axios-accessor.ts 文件:

plugins/axios-accessor.ts 中:import {Plugin} from '@nuxt/types'
import {AxiosResponse, AxiosRequestConfig, AxiosError} from 'axios'

const accessor: Plugin = ({error}) => {$axios.onRequest((config: AxiosRequestConfig) => {
    // ...
    return config
  })
  
  $axios.onError((e: AxiosError<any>) => {// ...})
  
  // response 拦截器,数据返回后,你能够先在这里进行一个简略的判断
  $axios.interceptors.response.use((response: AxiosResponse<any>) => {
    const res = response
    if (res.status === 200) {return Promise.resolve(res)
    } else {return Promise.reject(res)
    }
  },
  (e: any) => {const { status, data} = e.response
    error({statusCode: status, message: data})
    return Promise.reject(e)
  })
}

export default accessor

而后利用新增的 plugin/axios-accessor.ts

nuxt.config.js 中新增如下配置:export default {
    ...
    plugins: ['@/plugins/axios-accessor']
}

3. 非 vue 文件中应用 $axios 对象

nuxtjs中的 axios 模块会在 vue 实例上挂载一个 $axios 对象供应用,理论开发过程中,咱们往往习惯将我的项目中 api 办法放在独自的模块供全局应用,如何在非 vue 文件中应用 $axios 对象呢?

nuxtjs往往提供的 typescript 文档中,在 vuex 的 store 初始化示例中,有一并讲到,传送门:https://typescript.nuxtjs.org…

utils/api.ts 中:import {NuxtAxiosInstance} from '@nuxtjs/axios'

let $axios: NuxtAxiosInstance

export function initializeAxios (axiosInstance: NuxtAxiosInstance) {$axios = axiosInstance}

export {$axios}
plugin/axios-accessor.ts 中:import {Plugin} from '@nuxt/types'
import {AxiosResponse, AxiosRequestConfig, AxiosError} from 'axios'
// 新增引入
import {initializeAxios} from '~/utils/api'

const accessor: Plugin = ({error, app: { $axios} }) => {
  // 此处调用
  initializeAxios($axios)
  
  $axios.onRequest((config: AxiosRequestConfig) => {
    // ...
    return config
  })
  
  $axios.onError((e: AxiosError<any>) => {// ...})
  
  // response 拦截器,数据返回后,你能够先在这里进行一个简略的判断
  $axios.interceptors.response.use((response: AxiosResponse<any>) => {
    const res = response
    if (res.status === 200) {return Promise.resolve(res)
    } else {return Promise.reject(res)
    }
  },
  (e: any) => {const { status, data} = e.response
    error({statusCode: status, message: data})
    return Promise.reject(e)
  })
}

功败垂成,后续在其余文件中,只需:
import {$axios} from '@/utils/api'
就能够间接应用啦!

二、store

nuxtjs 官网文档所说,Nuxt.js 反对两种应用 store 的形式,你能够择一应用:

  • 模块形式: store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块(当然,index 是根模块)
  • Classic(不倡议应用): store/index.js返回创立 Vuex.Store 实例的办法。

联合 ts 当然是应用 vuex-module-decorators 来创立 modules。

store/mymodule.ts 中:import {Module, VuexModule, Mutation} from 'vuex-module-decorators'

@Module({
  name: 'mymodule',
  stateFactory: true,
  namespaced: true,
})
class MyModule extends VuexModule {
  wheels = 2

  @Mutation
  incrWheels(extra) {this.wheels += extra}

  get axles() {return this.wheels / 2}
}
utils/store-accessor.ts 中:import {Store} from 'vuex'
import {getModule} from 'vuex-module-decorators'
import example from '~/store/example'

let exampleStore: example

function initialiseStores(store: Store<any>): void {exampleStore = getModule(example, store)
}

export {initialiseStores, exampleStore}
store/index.ts 中:import {Store} from 'vuex'
import {initialiseStores} from '~/utils/store-accessor'

const initializer = (store: Store<any>) => initialiseStores(store)

export const plugins = [initializer]
export * from '~/utils/store-accessor'

而后就能够欢快的应用啦!

三、cookie

对于 cookie 这一块,以前始终用的是 js-cookie 这个库,这次的 nuxtjs 我的项目中,mode: 'universal'模式下,服务端渲染时没方法获取到客户端缓存的 cookie,导致页面刷新后无奈立刻通过 cookie 拿到用户缓存的登录状态,因而起初改用 cookie-universal-nuxt 这个库,api 与 js-cookie 基本一致,可在服务端应用,引入后,会在 vue 实例上新增一个 $cookie 对象,为不便全局应用,可仿照 $axios 的 accessor 逻辑,如下 example:

1. 首先装置并引入

npm install cookie-universal-nuxt --save
nuxt.config.js 中:export default {
    module: [
        '@nuxtjs/axios',
        '@nuxtjs/proxy',
        'cookie-universal-nuxt'
    ],
    ...
}

2.cookie 的 accossor

utils/api.ts 中:import {NuxtAxiosInstance} from '@nuxtjs/axios'
import {NuxtCookies} from 'cookie-universal-nuxt'

let $axios: NuxtAxiosInstance

export function initializeAxios (axiosInstance: NuxtAxiosInstance) {$axios = axiosInstance}

let $cookies: NuxtCookies

export function initializeCookies (cookiesInstance: NuxtCookies) {$cookies = cookiesInstance}

export {$axios, $cookies}
plugin/axios-accessor.ts 中:import {Plugin} from '@nuxt/types'
import {AxiosResponse, AxiosRequestConfig, AxiosError} from 'axios'
// 新增引入
import {initializeAxios, initializeCookies} from '~/utils/api'

const accessor: Plugin = ({error, app: { $axios, $cookies} }) => {
  // 此处调用
  initializeAxios($axios)
  initializeCookies($cookies)
  
  $axios.onRequest((config: AxiosRequestConfig) => {
    // ...
    return config
  })
  
  $axios.onError((e: AxiosError<any>) => {// ...})
  
  // response 拦截器,数据返回后,你能够先在这里进行一个简略的判断
  $axios.interceptors.response.use((response: AxiosResponse<any>) => {
    const res = response
    if (res.status === 200) {return Promise.resolve(res)
    } else {return Promise.reject(res)
    }
  },
  (e: any) => {const { status, data} = e.response
    error({statusCode: status, message: data})
    return Promise.reject(e)
  })
}

在其余文件中,只需:
import {$cookies} from '@/utils/api'
就能够间接应用啦!

OK,先写这么多,有问题欢送指出交换,结尾附上一个 demo,如果帮到大家,帮点给个 star,感激!https://github.com/elvira0702…。

退出移动版