Stories

Detail Return Return

nuxt3 最新踩坑記錄 - Stories Detail

版本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轉發
user avatar hard_heart_603dd717240e2 Avatar shuirong1997 Avatar xiaolei_599661330c0cb Avatar zzd41 Avatar assassin Avatar nznznz Avatar yangxiansheng_5a1b9b93a3a44 Avatar user_ze46ouik Avatar sy_records Avatar happy2332333 Avatar robin_ren Avatar mi2nagemao Avatar
Favorites 56 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.