Skip to content

Instantly share code, notes, and snippets.

@exonomyapp
Created September 17, 2024 14:27
Show Gist options
  • Save exonomyapp/f0dc69af73359f6a22bb1472aeeaf521 to your computer and use it in GitHub Desktop.
Save exonomyapp/f0dc69af73359f6a22bb1472aeeaf521 to your computer and use it in GitHub Desktop.
Nuxt3 Settings and Preferences with Pinia

Here’s how we can implement the "Settings" architecture using Pinia following the Nuxt3 approach:

1. Set Up Pinia in Nuxt3

First, make sure Pinia is installed and integrated into our Nuxt3 app:

  • Install Pinia:

    npm install pinia
  • Add Pinia to nuxt.config.ts:

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

2. Create the Pinia Store for User Preferences

In stores/preferences.ts:

import { defineStore } from 'pinia'

export const usePreferencesStore = defineStore('preferences', {
  state: () => ({
    theme: 'light',   // Example: default preference for theme
    notifications: true, // Example: default preference for notifications
  }),
  actions: {
    setTheme(theme: string) {
      this.theme = theme
    },
    toggleNotifications() {
      this.notifications = !this.notifications
    },
  },
  getters: {
    isDarkTheme: (state) => state.theme === 'dark',
  },
})

3. Build the Settings UI

In the pages/settings.vue, we can now replace it with more specific Nuxt3 syntax:

<template>
  <div>
    <h1>User Settings</h1>

    <label for="theme">Select Theme:</label>
    <select v-model="theme" @change="updateTheme">
      <option value="light">Light</option>
      <option value="dark">Dark</option>
    </select>

    <label for="notifications">Enable Notifications:</label>
    <input type="checkbox" v-model="notifications" @change="toggleNotifications" />
  </div>
</template>

<script setup>
import { usePreferencesStore } from '~/stores/preferences'

// Access store in setup function
const preferencesStore = usePreferencesStore()

// Reactive references
const theme = $ref(preferencesStore.theme)
const notifications = $ref(preferencesStore.notifications)

// Methods to modify preferences
const updateTheme = () => {
  preferencesStore.setTheme(theme)
}

const toggleNotifications = () => {
  preferencesStore.toggleNotifications()
}
</script>
  • $ref is used for better reactivity with Nuxt3's Composition API.
  • The logic for changing theme and notifications now leverages Nuxt3's reactivity syntax.

4. Persist Preferences (Optional)

For persistence using localStorage in the Nuxt3 store, the modifications look like this:

export const usePreferencesStore = defineStore('preferences', {
  state: () => ({
    theme: localStorage.getItem('theme') || 'light',
    notifications: JSON.parse(localStorage.getItem('notifications') || 'true'),
  }),
  actions: {
    setTheme(theme: string) {
      this.theme = theme
      localStorage.setItem('theme', theme)
    },
    toggleNotifications() {
      this.notifications = !this.notifications
      localStorage.setItem('notifications', JSON.stringify(this.notifications))
    },
  },
})

5. Using Preferences in Other Components

In any Nuxt3 component, you can access the store like this:

<template>
  <div :class="{ 'dark-mode': preferencesStore.isDarkTheme }">
    <!-- Your component code here -->
  </div>
</template>

<script setup>
import { usePreferencesStore } from '~/stores/preferences'

// Access store in setup function
const preferencesStore = usePreferencesStore()
</script>
  • Here, usePreferencesStore() is used within the setup function to retrieve user preferences.
  • The state (e.g., isDarkTheme) is reactive and can be used in templates.

This structure follows Nuxt3 syntax, leveraging its capabilities such as $ref for reactivity and Composition API for organizing the logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment