swuecho / chat

chat web app for teams, sass with user management and ratelimit, support chatgpt(openai & azure), claude, gemini and ollama model
508 stars 89 forks source link

refactor stores #434

Closed swuecho closed 3 months ago

swuecho commented 4 months ago

https://pinia.vuejs.org/core-concepts/plugins.html#Calling-subscribe-inside-plugins

swuecho commented 4 months ago

https://chat.bestqa.net/static/#/snapshot/4e98b22e-78ce-43fa-96c6-2a64c315daba

swuecho commented 4 months ago

system 2024-05-13T01:08:53Z: You are expert on frontend development}


user 2024-05-14T03:28:01Z: create a pinia store plugins that sync change to localStorage


assistant 2024-05-14T03:28:13Z: Pinia is an excellent state management library for Vue.js that allows you to create stores to manage your state. To sync the state changes with localStorage, you can create a Pinia plugin. Here's a step-by-step guide to creating a Pinia plugin that syncs changes to localStorage:

  1. Install Pinia

First, if you haven't already installed Pinia, you need to install it:

npm install pinia
  1. Create a Pinia Plugin

Create a file (e.g., piniaLocalStoragePlugin.js or piniaLocalStoragePlugin.ts for TypeScript) and define the plugin.

JavaScript Version

// piniaLocalStoragePlugin.js
export default function createLocalStoragePlugin(options) {
  return (context) => {
    const { store } = context;

    // Load stored state from localStorage
    const storedStateJSON = localStorage.getItem(`pinia-${store.$id}`);
    if (storedStateJSON) {
      store.$patch(JSON.parse(storedStateJSON));
    }

    // Subscribe to store changes and sync with localStorage
    store.$subscribe((mutation, state) => {
      localStorage.setItem(`pinia-${store.$id}`, JSON.stringify(state));
    });
  };
}

TypeScript Version

// piniaLocalStoragePlugin.ts
import { PiniaPluginContext, StateTree } from 'pinia';

export default function createLocalStoragePlugin(options?: any) {
  return (context: PiniaPluginContext) => {
    const { store } = context;

    // Load stored state from localStorage
    const storedStateJSON = localStorage.getItem(`pinia-${store.$id}`);
    if (storedStateJSON) {
      store.$patch(JSON.parse(storedStateJSON));
    }

    // Subscribe to store changes and sync with localStorage
    store.$subscribe((mutation, state: StateTree) => {
      localStorage.setItem(`pinia-${store.$id}`, JSON.stringify(state));
    });
  };
}
  1. Integrate the Plugin into Pinia

Now, you need to integrate the plugin into your Pinia setup. Assuming you are using Vue 3, configure your main application entry file (e.g., main.js or main.ts).

JavaScript Version

// main.js
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import createLocalStoragePlugin from './piniaLocalStoragePlugin';

const app = createApp(App);
const pinia = createPinia();

pinia.use(createLocalStoragePlugin());

app.use(pinia);
app.mount('#app');

TypeScript Version

// main.ts
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import createLocalStoragePlugin from './piniaLocalStoragePlugin';

const app = createApp(App);
const pinia = createPinia();

pinia.use(createLocalStoragePlugin());

app.use(pinia);
app.mount('#app');
  1. Create a Pinia Store

Create a Pinia store to see the plugin in action:

// stores/counter.js or stores/counter.ts
import { defineStore } from 'pinia';

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0,
  }),
  actions: {
    increment() {
      this.count++;
    },
    decrement() {
      this.count--;
    },
  },
});
  1. Use the Store in a Component

Finally, use the store within a Vue component to see the state being synced with localStorage.

<!-- CounterComponent.vue -->
<template>
  <div>
    <p>Count: {{ counter.count }}</p>
    <button @click="counter.increment">Increment</button>
    <button @click="counter.decrement">Decrement</button>
  </div>
</template>

<script>
import { useCounterStore } from '../stores/counter';

export default {
  setup() {
    const counter = useCounterStore();
    return { counter };
  },
};
</script>

That's it! Now whenever the state changes, it will be synchronized with localStorage. When you refresh the page, the state will be rehydrated from localStorage.

swuecho commented 4 months ago

https://prazdevs.github.io/pinia-plugin-persistedstate/guide/