本文介绍: 最近做了一个公司官网工作记录一下容易踩到的坑供大家参考,主要记录的是升级所用技术一个更换

最近做了一个公司官网nuxt框架升级工作记录一下容易踩到的坑供大家参考,主要记录的是升级所用技术一个更换

vue2 -> vue3

nuxt3支持vue3,而nuxt2支持vue2,所以此次迁移需要vue2升级为vue3。由于在项目vue2使用@vue-class-component来支持ts语法,而在vue3中对ts更好的支持。

首先就是<script>添加lang=“ts,其次是选择使用vue组合式API选项式API进行开发

使用组合式API请参考https://cn.vuejs.org/guide/typescript/composition-api.html
使用选项式API请参考:https://cn.vuejs.org/guide/typescript/options-api.html
@vueclasscomponent迁移vue3语法可以参考文章https://levelup.gitconnected.com/from-vue-class-component-to-composition-api-ef3c3dd5fdda

此次迁移选择使用组合式API,组合式API可以使用 <script setup> 语法也可以使用 setup() 选项,本次使用setup选项defineComponent() API来支持ts组件选项类型进行正确推导

IDE推荐使用vscode + volar插件(全面支持vue3语法ts,相当于vue2的vetur,提供语法提示高亮、以及templatescriptstyle代码分隔功能,详见:https://zhuanlan.zhihu.com/p/375096539 有的功能一定要正确的姿势(vscode版本等等)安装才会生效…),!!!使用volar一定要禁用vetur,不然volar失效

Vuex3 -> Vuex4

nuxt2中完全支持了vuex3,框架也会处理vue注册vuex,做到开箱即用。升级为nuxt3官方建议是用对nuxt系列支持更高的pinia。但是项目为了方便还是使用了vuex,将其升级为vuex4使用。vuex4对ts更好的支持(其实也还好)

官方对ts支持的指南里指出要定义类型化的store需要定义类型化的InjectionKey原因
在这里插入图片描述
vuexstore 安装到 Vue 应用中使用了 Vue 的Provide/Inject 特性,所以InjectionKey是很重要的因素

// store/index.ts
import { InjectionKey } from 'vue';
import { createStore, useStore as baseUseStore, Store } from 'vuex'

export interface State {
  isBannerLayoutHasFootBanner: boolean
}

export const key: InjectionKey<Store<State&gt;> = Symbol()

export const store = createStore<State>({
  state () {
    return {
      isBannerLayoutHasFootBanner: true
    }
  }
})

// 将store封装一下,不然每次都要再引入key给vuexuseStore传入key来获取store
export function useStore () {
  return baseUseStore(key)
}

nuxt3中通过useNuxtApp()来获取vue实例,使用nuxt3的plugin机制,在plugins目录创建一个专门用来注册vuex文件,一定要将key加进去!如下

// plugins/vuex-register.ts
import { store, key } from '@/store'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(store, key)
})

获取store使用vuex提供的usestore接口但是其只能在setup中使用,在外部使用为undefined外部使用可以配置全局变量$store来获取没有配置成功大家要是有成功案例可以分享一下】项目中我是通过nuxtApp提供的vue实例上的config全局属性获取的,如下

// page/index.vue
// setup内使用
import { useStore } from '@/store''

export default defineComponent({
  setup () {
    const store = useStore()
  }
})

// 外部文件使用
import { useNuxtApp } from 'nuxt/app'

const vueApp = useNuxtApp().vueApp
const $store = vueApp.config.globalProperties.$store

关于vuex中嵌套module的使用这次没有涉及到,可以搜一下相关文章

请求库@nuxt/axios -> ohmyfetch

nuxt2所使用@nuxt/axios不支持nuxt3 【哭了,费劲】
在这里插入图片描述
nuxt3推荐使用框架自带fetch hook或者ohmyfetch

简单封装(不太好轻喷)

// common/fetch.ts
import { $fetch } from 'ohmyfetch'
import util from './util'

const defaultHeaders: Object = {
  'Content-Type': 'application/json',
  'Cache-Control': 'no-cache',
  'If-Modified-Since': '0'
}
const baseDomain = process.env.NODE_ENV === 'development' ? 'https://uc.test.dos.lixinchuxing.cn' : ''
const baseURL = `${baseDomain}/api/v1`

// fetch模板
const apiFetch = $fetch.create({
  responseType: 'json',
  baseURL,
  async onRequest ({ request, options }) {
    // 设置默认请求options['headers'] = Object.assign({}, { ...defaultHeaders }, options.headers || {})
    options['credentials'] = 'include'
  },
  async onResponse ({ request, response, options }) {
    const cookieArr = /csrf-token=[^;]+;?/i.exec(document.cookie)
    if (cookieArr) {
      const csrfToken = cookieArr[0].replace('csrf-token=', '').replace(';', '')
      defaultHeaders['X-CSRF-Token'] = csrfToken
    }

    let data: any = {}

    if (!response) {
      return data
    }

    if (!response._data &amp;&amp; !request) {
      data = response
    } else if (response._data) {
      data = response._data
    }

    if (typeof data.data !== 'undefined') {
      if (response._data.code === 0) {
        return data.data
      }
      return data
    }
    return data
  },
  onResponseError (error) {
    if (!error) {
      util.showToast('异常错误')
      return
    }

    if (error.response) {
      switch (error.response.status) {
        case 301:
          break
        case 404:
          util.showToast('请求发生404错误')
          break
        case 500:
          util.showToast('请求发生500错误')
          break
        case 504:
          util.showToast('请求超时')
          break
        default:
          util.showToast('error:' + error.response.status)
          break
      }
      return Promise.reject(error.response._data) // 返回接口返回错误信息
    }
  }
})

export const useBaseFetch = (url: string, options: object) => apiFetch(url, options)

这里一个问题,fetch跨域情况下请求默认不带cookie搜索一些解决方案没有生效大家要是过类似经验希望不吝赐教。在其他情况下会带上,但是尚未得到证实,因为还没有测试api

配置更改

nuxt3引入vite支持本地运行打包提升编译速度,也兼容webpack5,所以配置项是有较大的改变,详细请参照nuxt3配置指南

需要注意的是:

  1. 关于tsconfig.json的配置,nuxt3在.nuxt目录下已经创建了一份,在根目录的配置会合并覆盖原有配置,默认初始化tsconfig文件没有改动。

  2. 迁移到nuxt3的配置中不支持自定义babel配置,需要vitewebpack配置项顶层去配。

  3. nuxt3中列出一些特定的目录componentslayoutpage存放对应的公用组件布局组件、页面组件,nuxt会根据规定的文件夹实现自动导入自动路由功能简化开发人员的工作。所以在 components文件夹不可以有同名文件,即使文件类型不同不可,会出现错误,如 “ Class constructor cannot be invoked without ‘new’ ” 找到了错的文件生成组件。并且layouts文件下的布局组件也尽量不要和components中的重名,区分大小写不可以,若有引用关系框架也会找不到正确的组件造成自己引用自己陷入死循环
    在这里插入图片描述

  4. 如果使用nuxt3的版本为3.0.0-rc.8遇到打包错误问题,不要怀疑,是框架的问题解决方法指路:https://github.com/nuxt/framework/issues/4325

  5. 3.0.0-rc.8版本默认使用vite打包打包后的文件后缀为mjs,若项目nginx没有允许此类后缀文件需要修改nginx配置,最近发布3.0.0-rc.9则改成了文件后缀js,无需修改nginx配置大家可以参考一下。这次项目中后面再升级为rc.9又报了很多错误最后决定还是修改nginx吧【哈哈】

以上就是nuxt2迁移至nuxt3使用技术一个大概的框架,具体迁移需要大家移步到nuxt3的迁移指南详细观看,目前nuxt3都是rc版本,大家做大型项目时候谨慎使用

原文地址:https://blog.csdn.net/EIERICA/article/details/126742265

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_47434.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注