Skip to content

集成插件

nuxt 官方提供了很多插件,需要的话可以直接在里面搜索。如果官方没有提供则需要自己进行配置

https://nuxt.com/modules

tailwindcss 集成

https://nuxt.com/modules/tailwindcss

1、安装依赖

shell
npx nuxi@latest module add tailwindcss

2、在 nuxt.config.js 中会自动添加配置

js
{
    modules: ["@nuxtjs/tailwindcss"];
}

3、在 pages/index.vue 中使用

vue

<div class="text-2xl text-red-600">欢迎访问首页,开启 Nuxt3 之旅!</div>

参考样式:https://rogden.github.io/tailwind-config-viewer/#Colors

4、生成 tailwind.config.js,并增加 purge 选项,在生产环境可以对未使用样式的文件进行 tree shaking

# 生成配置文件
npx tailwindcss init

写入需要配置的文件名

js
/** @type {import('tailwindcss').Config} */
module.exports = {
    content: [
        "./components/**/*.{vue,js}",
        "./layouts/**/*.vue",
        "./pages/**/*.vue",
        "./plugins/**/*.{js,ts}",
        "./nuxt.config.{js,ts}",
    ],
    theme: {
        extend: {},
    },
    plugins: [],
};

最后在 assets/css/tailwind.css 中增加以下内容(没有该文件则手动创建)。

css
@tailwind base;
@tailwind components;
@tailwind utilities;

然后在 assets/index.scss 中导入 tailwind.css ,重启 webstorm 就会有智能提示了。

ElementPlus 集成

https://nuxt.com/modules/element-plus

按需加载

目前来看按需加载仅仅针对组件,对于样式并不能实现按需加载。

安装 Element 组件库和图标插件。

pnpm install element-plus @element-plus/icons-vue

新建 assets/index.scss 并输入内容;

@use "element-plus/dist/index.css";

注意: 使用 .scss 文件,请先安装对应的 loader

pnpm install sass sass-loader -D

然后在 nuxt.config.ts 中增加如下内容。

js
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
    // 定义需要全局加载的文件。
    css: ["~/assets/index.scss"],
    build: {
        // 生产环境使用 babel 转译依赖。
        transpile: process.env.prod ? ["element-plus"] : [],
    },
});

最后在 pages/index.vue (这只是示例,实际你可以在任何地方去使用)中去使用它。

vue

<template>
  <div>
    <div>欢迎访问首页,开启 Nuxt3 之旅!</div>
    <ElButton type="primary" size="small">按钮</ElButton>
  </div>
</template>

<script setup>
  import {ElButton} from "element-plus";
</script>

全量加载

新建 plugins/element-plus.js 在此文件中新增如下配置,注册全局组件。

与按需加载唯一的区别可能就是每次使用时不再需要 import { * } from 'element-plus';但实际上按需加载也可以在这里面做。

js
import ElementPlus from "element-plus";
import * as ElementPlusIcons from "@element-plus/icons-vue";

export default defineNuxtPlugin((nuxtApp) => {
    nuxtApp.vueApp.use(ElementPlus);
    for (const [key, component] of Object.entries(ElementPlusIcons)) {
        nuxtApp.vueApp.component(key, component);
    }
});

自动导入

安装插件 unplugin-vue-components Vue 组件的按需自动导入

pnpm install unplugin-vue-components -D

然后在 nuxt.config.js 中增加如下配置。遗憾的是 ElementPlusicon 并不支持这样的操作,或者说是我没有找到对应的方案。

js
import Components from "unplugin-vue-components/vite";
import {ElementPlusResolver} from "unplugin-vue-components/resolvers";

export default defineNuxtConfig({
    vite: {
        plugins: [
            Components({
                resolvers: [ElementPlusResolver()],
            }),
        ],
        ssr: {
            noExternal: ["element-plus"],
        },
    },
});

Pinia 集成

nuxt 推荐使用内部提供的 useState 方法来做 store,这确实是一个好的办法,但对于一些企业级的应用,pinia 应该更加的适合,当然 pinia 也是 nuxt 官方比较推荐的仓库管理工具。

https://nuxt.com/modules/pinia

nuxt 集成 pinia 需要两个包支持。

pnpm install @pinia/nuxt pinia

然后在 nuxt.config.tsmodules 中注册插件。更多的配置参考

js
export default defineNuxtConfig({
    modules: ["@pinia/nuxt"],
});

至此插件就已经可以使用了,但与普通的 vue 项目中使用方式略显不同,减少了 createPinia 的步骤。

创建 /store 目录并在 /store/counter.js 中写入示例代码。

js
import {defineStore} from "pinia";

export const useCounterStore = defineStore({
    id: "counter-store",
    state: () => ({
        count: 0,
    }),
    getters: {
        doubleCount: (state) => state.count * 2,
    },
    actions: {
        countPlusOne() {
            this.count++;
        },
    },
});

在文件中去使用导入并使用它。

vue

<template>
  <div class="p-5">
    count: {{ store.count }}
    <br/>
    <ElButton type="primary" @click="store.countPlusOne">+1</ElButton>
  </div>
</template>

<script setup>
  import {useCounterStore} from "~/store/counter";

  const store = useCounterStore();
</script>

持久化 store 集成

pinia 的持久化依赖于 pinia-plugin-persistedstate

https://nuxt.com/modules/pinia-plugin-persistedstate

pnpm install pinia-plugin-persistedstate

注册该插件的方式也有两种。分别为 客户端 和 ssr 两种方式。在开始之前可以先将 counterStore 中增加如下配置。更多配置参考

js
export const useCounterStore = defineStore({
    id: "counter-store",
    state: () => ({
        /** ... */
    }),
    getters: {
        /** ... */
    },
    actions: {
        /** ... */
    },
    // 确认该仓库使用持久化
    persist: true,
});

客户端持久化:plugins 下创建 persistedstate.client.js 并输入以下内容。

js
import {createPersistedState} from "pinia-plugin-persistedstate";

export default defineNuxtPlugin((nuxtApp) => {
    nuxtApp.$pinia.use(createPersistedState());
});

如果按照示例代码去测试是否成功,可能就碰到 Hydration completed but contains mismatches. 的问题了。

对应的解决方案就是需要在使用到 store 数据的模板中用 ClientOnly 组件包裹一下,类似于这样。

vue

<ClinetOnly>
  <!-- .... -->
  </ClientOnly>

ssr 持久化:plugins 下创建 persistedstate.js 并输入以下内容。了解更多

js
import {createNuxtPersistedState} from "pinia-plugin-persistedstate/nuxt";

export default defineNuxtPlugin((nuxtApp) => {
    nuxtApp.$pinia.use(
        createNuxtPersistedState(useCookie, {
            cookieOptions: {
                maxAge: 3600,
                sameSite: "strict",
            },
        }),
    );
});

content

https://nuxt.com/modules/content

https://content.nuxtjs.org/get-started