-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
defineStore doesn't respect readonly
ref returned from storeSetup
fn
#872
Comments
|
@posva the docs you mentioned: 'readonly takes a reactive OR a ref '😂 |
@posva my temp. workaround is using a no-setter computed ref // myStore.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export default defineStore('myStore', () => {
const x = ref(0)
// ..
return { x: computed(() => x.value) } // << no-setter = readonly
}) and users will get a warning on mutating <!-- App.vue -->
<script setup>
import useMyStore from './path/to/myStore.js'
const store = useMyStore()
</script>
<template>
<button @click='++store.x'> {{ store.x }} </button>
<!-- vue will warn when users click -->
<!-- Write operation failed: computed value is readonly -->
</template> |
@posva thanks. but its not quite related to my original issue ( my issue is on Provider <!-- App.vue -->
<script setup>
import { ref, readonly, provide } from 'vue'
import MyComp from './MyComp.vue'
const x = ref(0);
provide('x', readonly(x)); // analog : return { x: readonly(x) } in storeSetup fn
</script>
<template>
<MyComp></MyComp>
</template> Then, in injectors <!-- MyComp.vue -->
<script setup>
import { inject } from 'vue'
const x = inject('x'); // analog : get `x` from store
</script>
<template>
{{ x }}
<button @click='++x'> incr x </button>
<!-- vue will warn when users click -->
<!-- Set operation on key "value" failed: target is readonly. -->
</template> |
It’s how pinia worka |
@posva thanks, good hint. Here's my new understanding: When we call import { isReactive } from 'vue'
import useMyStore from './myStore.js'
const store = useMyStore()
isReactive(store) // true Since vue doesn't preserve Right? |
@posva it's not intended, this is actually a vue reactivity bug, may fix by vuejs/core#5048 |
Don't know if this is useful to anyone, but I found this issue while trying to find out if this is possible with Pinia, and it turns out returning a So (using an updated version of the example in the OP here): // myStore.js
import { defineStore } from 'pinia'
import { ref, readonly } from 'vue'
export default defineStore('myStore', () => {
const x = ref(0)
// ..
return { x: readonly(x) } // << readonly
}) <!-- App.vue -->
<script setup>
import useMyStore from './path/to/myStore.js'
const { x } = storeToRefs(useMyStore())
// This ^ is typed wrong! Is now Ref<boolean>, should be Readonly<Ref<boolean>>
</script>
<template>
<a @click='++x'> {{ x }} </a>
<!--
When user triggers mutating of a readonly ref, Vue warns in the console:
"Set operation on key "value" failed: target is readonly."
-->
</template> Related: #2574 |
Reproduction
Define a store
Then consume the store
Expected behavior
I expected that vue will show warnings in web console when the anchor is clicked
Actual behavior
when the anchor is clicked,
store.x
gets mutated; no warnings in web console.Additional information
deps
Thanks.
The text was updated successfully, but these errors were encountered: