Пожалуйста, посмотрите этот минимальный пример. Если я использую useState
, обычно я могу написать что-то вроде этого:
<script setup>
const num = useState('num', () => 1);
</script>
<template>
<div>
{{ num }}
</div>
<div>
{{ typeof num }}
</div>
<div>
{{ JSON.stringify(num) }}
</div>
</template>
И результат тот, что я ожидал:
1
number
1
Однако когда я переместил useState
в составные элементы, все изменилось вот так:
export const useNum = () => {
const num = useState('num', () => 1);
return {
num,
};
};
<script setup>
const numStore = useNum();
</script>
<template>
<div>
{{ numStore.num }}
</div>
<div>
{{ typeof numStore.num }}
</div>
<pre>
{{ JSON.stringify(numStore.num, null, 2) }}
</pre>
</template>
результат очень странный:
1
object
{
"_object": {
"$s__nuxt_devtools__": {
"timeSsrStart": 1719387436211
},
"$snum": 1
},
"_key": "$snum",
"__v_isRef": true
}
Почему это происходит? Как мне этого избежать?
но nuxt 3 useState
уже имеет аналогичную функциональность, я могу установить ключ и использовать его как глобальное состояние.
Да, но вы не можете использовать его внутри компонуемых объектов, ссылка, которую я добавил для pinia, на самом деле является собственной документацией nuxt. По крайней мере, не так, как вы хотите использовать его в вопросе.
спасибо за совет, надо подумать.
Это нормально, вообще нечего избегать, так работает разворачивание рефов. {{ numStore.num }}
приводит к 1
, что и является предполагаемым поведением. Есть ли реальная проблема, которую вы пытаетесь решить? В шаблоне нет смысла использовать typeof или JSON.stringify.
Не знаю, какой объект useState
возвращает, но если вам нужен .value
, то это ref
(не знаю, почему его нет в первом контексте).
Вы также можете использовать toValue, если не хотите скучать, пытаясь выяснить, что именно находится внутри вашей переменной.
Что касается остального (тема Pinia), будьте осторожны с шаблоном Singleton в контексте SSR, как написано в документации, да.
На основе официальных документов:
Развертывание ссылки в шаблонах применяется только в том случае, если ссылка является свойством верхнего уровня в контексте рендеринга шаблона.
Под разворачиванием мы подразумеваем отказ от использования .value
Поэтому попробуйте разрушить возвращаемое значение вашего составного объекта, чтобы сделать ссылку свойством верхнего уровня, или используйте .value
в шаблоне:
<script setup>
const { num } = useNum();
</script>
<template>
<div>
{{ num }}
</div>
<div>
{{ typeof num }}
</div>
<pre>
{{ JSON.stringify(num, null, 2) }}
</pre>
</template>
Я не минусовал, но это не учитывает тот факт, что это {{ numStore.num }}
нормально. Интерполяция шаблона сама по себе приводит к развертыванию ссылок. По-прежнему имеет смысл использовать ссылки верхнего уровня для последовательной развертки.
Немного не по теме, но вам действительно стоит использовать официальную библиотеку pinia, если вы хотите иметь отдельный магазин для управления состоянием