[英]Using Vue refs with Pinia
我正在尝试使用Pinia状态存储来保留一个使用Vue refs的对象。
该对象是此类的一个实例(简化示例):
class Foo {
constructor() {
this.field = ref('')
}
setField(value) {
this.field.value = value
}
}
const foo = new Foo
foo.setField('bar') // all happy — no errors here
(我使用这些对象作为数据记录,并且字段需要是 refs,因为它们是在模板中呈现的,我希望它们是响应式的)。
因此,我定义了一个 Pinia 商店并将对象设置为它:
const useState = defineStore('main', {
state: () => {
return {
foo: null
}
}
})
const state = useState()
state.foo = foo
现在,当我尝试对从商店中检索到的对象进行操作时,我得到:
state.foo.setField('baz') // this fails with the error
TypeError: Cannot create property 'value' on string 'bar'
我猜这里发生的情况是 Pinia 在从商店访问foo
对象时取消引用它的field
属性。 但是,见鬼,我不需要那个! 我希望foo
对象的行为始终如一,无论它是从哪里检索的。
知道怎么做吗? 我看到 Pinia 有一个名为skipHydrate
的方法,它可能与这些东西有关,但我找不到如何使用它。
Pinia 在内部使用 Vue 组合 API 并共享其行为。
正如文件所说,
反应式转换是“深度”的:它影响所有嵌套属性。 反应式对象还可以在保持反应性的同时深入解开任何作为 refs 的属性。
还应该注意的是,当引用作为反应数组的元素或像 Map 这样的本机集合类型访问时,不会执行引用解包。
为避免深度转换并仅在根级别保留反应性,请改用 shallowReactive()。
为了保持类实例完整,可以使用markRaw
:
state: () => {
return {
foo: markRaw(new Foo())
}
}
可能没有必要在类实现中显式使用ref
之类的组合 API; 相反,类实例可以像reactive(new Foo())
一样具有反应性,但有明显的例外(在此处和此处进行解释)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.