Skip to content

Nuxt3 使用 pinia

安装

bash
pnpm i pinia @pinia/nuxt pinia-plugin-persistedstate/nuxt -S

/* 持久化*/
pnpm i pinia-plugin-persistedstate/nuxt -S

插件

  • 编写插件 plugins/pinia/pinia.ts
js
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
export default defineNuxtPlugin((nuxtApp: any) => {
  nuxtApp.$pinia.use(piniaPluginPersistedstate);
});
  • 挂载 nuxt.config.ts
js
import postCssPxToRem from "postcss-pxtorem";

export default defineNuxtConfig({
  compatibilityDate: "2025-01-07",
  devtools: { enabled: true },
  css: ["normalize.css/normalize.css"],
  // 使用scss
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@use "~/assets/scss/base.scss" as *;',
        },
      },
      postcss: {
        plugins: [
          postCssPxToRem({
            rootValue: 75, // UI设计稿的宽度/10
            unitPrecision: 3, // 转rem精确到小数点多少位
            propList: ["*"], // 需要转换的属性 *表示所有
            selectorBlackList: ["ignore"], // 不进行px转换的选择器
            replace: true, // 是否直接更换属性值,而不添加备用属性
            mediaQuery: false, // 是否在媒体查询的css代码中也进行转换
            minPixelValue: 0, // 设置要替换的最小像素值
            exclude: /node_modules/i, // 排除node_modules文件夹下的文件
          }),
        ],
      },
    },
  },
  // 测试环境读取
  runtimeConfig: {
    // 仅仅在服务端
    baseUrl: process.env.VITE_BASE_URL,
    // 客户端也读取
    public: {
      baseUrl: process.env.VITE_BASE_URL,
    },
  },
  // 这里是方便生产环境读取
  appConfig: {
    mode: process.env.VITE_MODE,
    baseUrl: process.env.VITE_BASE_URL,
  },

  // SEO配置
  app: {
    head: {
      title: "Nuxt3",
      meta: [
        { name: "description", content: "Nuxt3" },
        { name: "keywords", content: "Nuxt3" },
        {
          name: "viewport",
          content:
            "width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0",
        },
      ],
      link: [
        {
          rel: "stylesheet",
          href: "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css",
        },
      ],
      script: [
        {
          src: "https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/pace.min.js",
        },
      ],
    },
  },

  // 安装插件
  plugins: ["~/plugins/rem/flexible.ts", "~/plugins/pinia/pinia.ts"],

  // 使用pinia
  modules: ["@pinia/nuxt"],
});

使用

  • 新建 pinia/user.ts
js
import { defineStore } from "pinia";
interface State {
  activeProductName: string;
}
export const useNuxtStore = defineStore("nuxtStore", {
  state: (): State => ({
    activeProductName: "",
  }),
  actions: {
    setActiveProductName(name: string) {
      this.activeProductName = name;
    },
  },
  // 注意:persist定义要做判断,因为localStorage/sessionStorage是客户端参数,所以需要加process.client
  persist: process.client && {
    storage: sessionStorage,
  },
});
  • 在页面中使用
html
<template>
  <div class="loginpage">
    login页面
    <div>{{ useNuxtStore().activeProductName }}</div>
    <div class="partdiv"></div>
    <button @click="changeClick">点击改变</button>
  </div>
</template>

<script setup lang="ts">
  import { useNuxtStore } from "~/pinia/user.ts";
  definePageMeta({
    layout: "login",
  });

  useHead({
    title: "登录页",
    meta: [{ name: "description", content: "My amazing site." }],
  });

  console.log(useRuntimeConfig());
  console.log(useAppConfig().baseUrl); // const
  // runtimeConfig = useRuntimeConfig(); // console.log(runtimetimeConfig);

  const changeClick = () => {
    useNuxtStore().setActiveProductName("王五");
  };
</script>

<style scoped lang="scss">
  .loginpage {
    color: $primary;
    .partdiv {
      width: 750px;
      height: 750px;
      background: red;
    }
  }
</style>