nuxt.js + typescript项目开发总结

时间:2020-7-29 作者:admin

一、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…

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。