版本nuxt3.14
依赖vite+element-plus+scss
nuxt文档不清晰,版本问题也很多,要自己琢磨。

element-plus适配

  • ele集成用的推荐@element-plus/nuxt
  • element-plus版本如果不是>=2.8.8,要手动升级,不然!global assignments告警让人奔溃

ele主题


  // 全局样式
  css: ['~/assets/scss/index.scss'],
  vite: {
    css: {
      // 全局变量
      preprocessorOptions: {
        scss: {
          additionalData: `
            @use "@/assets/scss/element/index.scss" as element;
            @use "@/assets/scss/_variables.scss" as *;
          `,
          silenceDeprecations: ['legacy-js-api', 'global-builtin']
        },
      },
    },
  },
  • element主题变量定义,用@element-plus/nuxt推荐即可

    $-colors: (
      "primary": (
        "base": rgba(107, 33, 168, 1),
      ),
      "success": (
        "base": #67c23a,
      ),
      "warning": (
        "base": #e6a23c,
      ),
      "danger": (
        "base": #f56c6c,
      ),
      "error": (
        "base": #f56c6c,
      ),
      "info": (
        "base": #909399,
      ),
    );
    
    @forward "element-plus/theme-chalk/src/common/var.scss" with (
      $colors: $-colors
    );
    
    @use "./dark.scss";
    

element默认黑暗主题

plugins/dark-mode.server.ts

export default defineNuxtPlugin({
  name: 'dp-dark-mode-plugin',
  async setup(nuxtApp) {
    if (import.meta.server) {
      useHead({
        htmlAttrs: {
          class: computed(() => "dark"),
        },
      })
    }
  }
})

useHead为nuxt内置工具函数
nitro插件亦可实现

image.png

nuxt插件示例,可访问dom元素

export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('render:html', (html, { event }) => {
    console.log('render:html', html)
    html.bodyAppend.push('<hr>由自定义插件追加的内容')
  })

  nitroApp.hooks.hook('render:response', (response, { event }) => {
    console.log('render:response', response)
  })
})

scss全局变量

  • 配置css.preprocessorOptions.scss.additionalData
  • 代码示例,同上
  • 全局样式,配置css参数即可即可。全局变量不要放这,类似tree-shaking老生常谈问题了。
  • 这里不支持老版本@import,要用@use,区别自己查询sass文档
  • @use "@/assets/scss/_variables.scss" as *,星号为全局可用。定义特定名称,即为moudle方式。
  • 全局变量名格式$head-size,不支持$-head-size
  • 关闭sass告警,配置silenceDeprecations

eslint适配

  • 推荐@nuxt/eslint
  • 修改eslint或者typescript配置,不要修改.nuxt目录下内容,这是nuxt自动生成的,下次启动会覆盖掉
  • 例子

    export default defineNuxtConfig({ 
     typescript: {
        strict: true,
        shim: false,
        tsConfig: {
          compilerOptions: {
            "module": "ESNext"
          }
        }
      },
      eslint: {
        config: {
          stylistic: {
            indent: 2,
            quotes: 'double',
            semi: true,
            // ...
          }
        }
      },
    })

自动导入

  • nuxt内置自动导入components/、composables/和utils/目录和server、plugins目录
  • @vueuse/nuxt支持vue方法自动导入
  • @element-plus/nuxt内置了element-plus的自动导入
  • 自建目录接入nuxt自动导入方式

    imports: {
      dirs: ["api"],
    }

useFetch和水合

  1. useFetch服务端和客户端都会执行
  2. 多次执行数据不一致会触发水合报错
  3. 推荐方式,客户端执行时用useFetch返回refresh
  4. ssr水合报错,配置useFetch参数key。key是$fetch缓存标识,即key相同的情况,不会重复发送请求。
key = hash( JSON.stringify(data)) // data为ajax参数
  1. key可以暂时解决水合问题。数据缓存问题,要自己取舍。
  2. 服务端渲染情况下,useFetch默认是拿不到客户端cookie的,需要配置参数credentials = "include" | "omit" | "same-origin"。对应跨域、不带cookie和同域名下携带。
  3. 插件或中间件支持useNuxtApp.isHydrating 判断是否水合,如果是客户端并且水合模式就不执行

  const nuxtApp = useNuxtApp()
  console.log('emit side = ', import.meta.server ? 'server' : 'client')
  console.log('emit isHydrating = ', nuxtApp.isHydrating)
  console.log('emit serverRendered = ', nuxtApp.payload.serverRendered)
  if (!import.meta.server && nuxtApp.isHydrating && nuxtApp.payload.serverRendered) return

环境变量

客户端可用环境变量
  runtimeConfig: {
    // 运行时常量
    public: {
      // 客户端-服务的都能访问
      apiBaseUrl: process.env.NUXT_API_URL,
      serverApiProxy: process.env.NUXT_API_PROXY,
      homeSiteUrl: process.env.NUXT_HOME_SITE,
    },
  },

这里就可用接入dotenv

接口转发

nitro原来是nuxt模块,现在已经独立,自己注意版本兼容。

  1. 开发环境接口转发nitro.devProxy。使用方式同vite,可看nitro文档
  2. 服务端渲染接口转发nitro.routeRules,生成环境和开发环境都可用
nitro: {
    // 缩小捆绑包
    minify: true,
    // 关闭源映射生成
    sourceMap: false,
    devProxy: {
      '/api': {
        target: "http://localhost:3329",
        changeOrigin: true,
        prependPath: true,
      },
    },
    // 服务端请求转发
    routeRules: {
      '/api/**': {
        proxy: 'http://127.0.0.1:3329/**',
      },
    }
  },

注意事项

  1. 如果项目部署子目录下,即app.baseURL = '/test'。接口会默认为/test/api/**。
  2. routeRules配置/test/api/**不会生效。这里不确定是否nitro的bug,他也是依赖h3实现的。
  3. 所以nuxt的/server/middleware或者/server/api的h3应该也可以实现自定义的接口转发,没试过
  4. 解决方式,ajax.baseUrl = 'http://127.0.0.1:3329',绕过nitro转发

肥皂泡
382 声望6 粉丝

码农


引用和评论

0 条评论