英文:
Wrap v-model changes in a $patch
问题
I need to wrap v-model changes in a $patch. I am using vue3 and pinia, and have a working solution, but wondering if there is a better way to do this.
My current working pattern is:
<script setup lang="ts">
someAttribute = computed({
get() {
return store.someAttribute;
},
set(val: string) {
store.$patch(() => {
store.someAttribute = val;
});
},
});
</script>
<template>
<input v-model="store.someAttribute" />
</template>
This does appear to work, but is a bit annoying to do for every single attribute that I'm going to bind with v-model.
I need this behavior because I have code that subscribes to store
changes. If there are dependencies to someAttribute
, then this triggers multiple change events. With the $patch
there is only one. I need there to be one event per user action since the other code is maintaining a history of the application state.
英文:
I need to wrap v-model changes in a $patch. I am using vue3 and pinia, and have a working solution, but wondering if there is a better way to do this.
My current working pattern is:
<script setup lang="ts">
someAttribute = computed({
get() {
return store.someAttribute;
},
set(val: string) {
store.$patch(() => {
store.someAttribute = val;
});
},
});
</script>
<template>
<input v-model="store.someAttribute" />
</template>
This does appear to work, but is a bit annoying to do for every single attribute that I'm going to bind with v-model.
I need this behavior because I have code that subscribes to store
changes. If there are dependencies to someAttribute
, then this triggers multiple change events. With the $patch
there is ony one. I need there to be one event per user action since the other code is maintaining a history of the application state.
答案1
得分: 2
> I need to wrap v-model changes in a $patch.
实际上,你不需要这样做。
状态属性和getter可以使用pinia
的storeToRefs
函数提取为ref
。
使用ref
与v-model
建立了存储状态和输入值之间的双向绑定。
查看它的工作原理:
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://unpkg.com/vue-demi"></script>
<script src="https://unpkg.com/pinia@2.0.11/dist/pinia.iife.prod.js"></script>
<div id="app">
<input v-model="foo" />
<pre v-text="{ reversedFoo }" />
</div>
在你的情况中:
<script setup lang="ts">
import { storeToRefs } from "pinia"
//...
const { someAttribute } = storeToRefs(store)
</script>
<template>
<input v-model="someAttribute" />
</template>
也可以在<template>
中完成,但在我看来不够简洁:
<input v-model="storeToRefs(store).someAttribute">
重要提示:
只有state
和getters
存储成员应通过storeToRefs
进行提取,而不是actions
。
以下是典型的存储使用示例:
<script setup>
//...
const { stateProp1, stateProp2, getter1, getter2 } = storeToRefs(store)
const { action1, action2 } = store
// 所有提取的存储成员现在已准备好在<template />中使用
// storeToRefs返回的是refs,可以在setup()中使用:
stateProp1.value = 'whatever';
</script>
英文:
> I need to wrap v-model changes in a $patch.
Actually, you don't.
State properties and getters can be extracted to ref
s using storeToRefs
from pinia.
Using ref
with v-model
establishes a 2-way binding between the store's state and the input's value.
See it working:
<!-- begin snippet: js hide: true console: true babel: false -->
<!-- language: lang-js -->
const { createApp } = Vue
const { defineStore, createPinia, storeToRefs } = Pinia
const useStore = defineStore("pokemon", {
state: () => ({ foo: "ledom-v htiw etats ainip" }),
getters: {
reversedFoo() {
return this.foo.split("").reverse().join("")
}
}
})
createApp({ setup: () => storeToRefs(useStore()) })
.use(createPinia())
.mount("#app")
<!-- language: lang-html -->
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://unpkg.com/vue-demi"></script>
<script src="https://unpkg.com/pinia@2.0.11/dist/pinia.iife.prod.js"></script>
<div id="app">
<input v-model="foo" />
<pre v-text="{ reversedFoo }" />
</div>
<!-- end snippet -->
In your case:
<script setup lang="ts">
import { storeToRefs } from "pinia"
//...
const { someAttribute } = storeToRefs(store)
</script>
<template>
<input v-model="someAttribute" />
</template>
It can also be done in <template>
, but it's not as neat, IMHO:
<input v-model="storeToRefs(store).someAttribute">
Important note:
Only state
and getters
store members should be extracted through storeToRefs
. Not actions
.
Here's a typical store usage:
<script setup>
//...
const { stateProp1, stateProp2, getter1, getter2 } = storeToRefs(store)
const { action1, action2 } = store
// all extracted store members are now ready for `<template />` usage
// storeToRefs returns refs, usable in `setup()` as:
stateProp1.value = 'whatever'
</script>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论