Usage with Pinia
Since Regle is headless, you can use it anywhere in your app — whether in a composable or a store.
Using a Pinia store is an excellent way to avoid prop drilling with multiple properties while maintaining type inference seamlessly across your components.
Using regle in a Pinia store
ts
import { required, minLength, email } from '@regle/rules';
import { defineStore } from 'pinia';
import { useRegle } from '@regle/core';
export const useDemoStore = defineStore('demo-store', () => {
const { r$ } = useRegle({ email: '' }, {
email: { required, minLength: minLength(4), email }
})
return {
r$
}
})
vue
<template>
<input v-model='r$.$value.email' placeholder='Type your email'/>
<button type="button" @click="r$.$resetAll">Reset</button>
</template>
<script setup lang='ts'>
import { useDemoStore } from './demo.store';
import { storeToRefs } from 'pinia';
const demoStore = useDemoStore();
const { r$ } = storeToRefs(demoStore);
</script>
vue
<template>
<ul>
<li v-for="error of r$.$errors.email" :key='error'>
{{ error }}
</li>
</ul>
</template>
<script setup lang='ts'>
import { useDemoStore } from './demo.store';
import { storeToRefs } from 'pinia';
const demoStore = useDemoStore();
const { r$ } = storeToRefs(demoStore);
</script>
Component A:
Component B:
No errors
Avoid hydration issues
If you use store.$dispose()
or Nuxt in SSR mode, you may encounter this error:
Uncaught TypeError: 'set' on proxy: trap returned falsish for property 'xxx'
This is because Pinia tries to hydrate the stateful property r$
. To avoid this, you can use skipHydrate
ts
import { skipHydrate } from 'pinia';
export const usePiniaStore = defineStore('pinia-store', () => {
const {r$} = useRegle(/** */)
return { r$: skipHydrate(r$) };
});