我有这个嵌套的 foreach BalanceItemList.vue
<template>
<div v-for="category in categoryItemsStore.balanceCategories" :key="category.id" class="mt-5">
<div class="border-black border-b bg-gray-200">
<span class="font-bold w-full">{{ category.name }}</span>
</div>
<div v-for="balanceItem in category.balance_items" :key="balanceItem.id">
{{ balanceItem.total = 500 }}
<balance-item :balance-item="balanceItem" @update-balance-item="update"/>
</div>
<div>
<balance-item-create :category="category.id" @create-balance-item="update"/>
</div>
<div v-if="categoryItemsStore.totals[category.id]" class="grid grid-cols-4-b t-2 ml-2">
<div :class="category.is_positive ? '': 'text-red-600' "
class="col-start-4 border-t-2 border-black font-bold">
€{{ categoryItemsStore.totals[category.id].total }}
</div>
</div>
</div>
</template>
我像这样检查了“balanceItem”的反应性
{{ balanceItem.total = 500 }}
它在商店中更新,但随后我有了我的平衡项目组件: BalanceItem.vue
<script setup>
import {reactive} from "vue";
import {useForm} from "@inertiajs/vue3";
import NumberInput from "@/Components/NumberInput.vue";
import {UseCategoryItemsStore} from "@/Stores/UseCategoryItemsStore.js";
const categoryItemStore = UseCategoryItemsStore()
const props = defineProps({balanceItem: Object, errors: Object})
let item = reactive(props.balanceItem);
const form = useForm(item);
const emit = defineEmits(['update-balance-item'])
const submit = () => {
form.post(route('balance-item.update'), {
preserveScroll: true,
onSuccess: () => {
props.balanceItem.total = 500
categoryItemStore.updateBalanceItemsTotals(form)
emit('update-balance-item')
}
})
}
</script>
<template>
<form @submit.prevent="submit">
<div class="grid grid-cols-4-b">
<span>{{ item.name }}</span>
<NumberInput
v-model="form.count"
autofocus
class=" mr-4 mt-1 block"
type="number"
@update:model-value="submit"
/>
<div :class="item.item_category.is_positive ? '' : 'text-red-600'" class="flex place-items-center">
<div class="pt-1 mr-1">€</div>
<NumberInput
v-model="form.amount"
:class="form.errors.amount ? 'border-red-600' : ''"
autofocus
class="mt-1 mr-4 w-5/6"
type="text"
@update:model-value="submit"
/>
</div>
<div :class="item.item_category.is_positive ? '' : 'text-red-600'" class="flex place-items-center">
<div class="pt-1 mr-1 w-5/6">€</div>
<NumberInput
v-model="form.total"
autofocus
class="mt-1 block"
disabled
style="max-width: 95%"
type="text"
/>
</div>
</div>
</form>
</template>
这是我测试反应性的商店。如果我增加输入的数字,则项目的计数保持不变 UseCategoryItemsStore.js
import {defineStore} from "pinia";
import {ref} from "vue";
export const UseCategoryItemsStore = defineStore('UseCategoryItemsStore', () => {
const balanceCategories = ref([])
const totals = ref([])
function getBalanceItems() {
axios.get(route('balance-item.index')).then((response) => {
balanceCategories.value = response.data
// console.log(balanceCategories.value)
})
}
function getTotals() {
axios.get(route('balance-item.totals')).then((response) => totals.value = response.data)
}
function getData() {
getTotals()
getBalanceItems()
}
function updateBalanceItemsTotals(selectedItem) {
balanceCategories.value.forEach((category) => {
category.balance_items.forEach((item) => {
if (item.id === selectedItem.id) {
// item.total = item.count * item.amount
console.log(item)
}
})
})
}
getTotals()
getBalanceItems()
return {balanceCategories, totals, getBalanceItems, getTotals, getData, updateBalanceItemsTotals}
})
在此测试中,我执行“props.balanceItem.total = 500”。但如果我检查商店,它不会更新。看来将“balanceItem”分配给一个道具会失去与我的 Pinia 商店的反应性。我可以使用“form.total = form.count * form.amount”手动更新我的表单,但这对我来说似乎很老套,我想使用 Pinia 商店的反应性。我考虑过根据“BalanceItem”获取 Pina 项目,但这似乎也很棘手。谁知道为什么失去反应性?
我有laravel 10.39、vue3.2.41和pinia 2.1.17惯性0.6.11。到目前为止我知道的所有最新版本。
我像这样更新我的表格和商店:
<script setup>
import {useForm} from "@inertiajs/vue3";
import NumberInput from "@/Components/NumberInput.vue";
import {UseCategoryItemsStore} from "@/Stores/UseCategoryItemsStore.js";
const categoryItemStore = UseCategoryItemsStore()
const props = defineProps({balanceItem: Object, errors: Object})
let item = categoryItemStore.getItemById(props.balanceItem);
let form = useForm(item);
const emit = defineEmits(['update-balance-item'])
const submit = () => {
form.post(route('balance-item.update'), {
preserveScroll: true,
onSuccess: () => {
item = categoryItemStore.updateItem(form)
form = useForm(item)
emit('update-balance-item')
}
})
}
</script>
我将此功能添加到我的商店:
import {defineStore} from "pinia";
import {ref} from "vue";
export const UseCategoryItemsStore = defineStore('UseCategoryItemsStore', () => {
const balanceCategories = ref([])
const totals = ref([])
function getBalanceItems() {
axios.get(route('balance-item.index')).then((response) => {
balanceCategories.value = response.data
// console.log(balanceCategories.value)
})
}
function getItemById(item) {
let category = balanceCategories.value.find((category) => {
return category.id === item.item_category_id
})
return category.balance_items.find((item_from_store) => {
return item_from_store.id === item.id
})
}
function updateItem(form) {
const item = getItemById(form)
item.count = form.count
item.amount = form.amount
item.total = item.count * item.amount
return item
}
function getTotals() {
axios.get(route('balance-item.totals')).then((response) => totals.value = response.data)
}
function getData() {
getTotals()
getBalanceItems()
}
getTotals()
getBalanceItems()
return {balanceCategories, totals, getBalanceItems, getTotals, getData, getItemById, updateItem}
})
假设如果帖子获得 200,我的表单值可用于更新商店和更新表单。这是我能想到的最好的