Nuxt3中Pinia Store属性补丁一组件生效另一组件失效问题
Pinia状态在Color组件无法修改的原因分析
在Nuxt3项目中,ColorManagement组件的setActive方法可正常修改Pinia store内的activeColor状态,但Color组件的cancelEdit方法无法实现该修改,相关代码如下:
组件1(ColorManagement)
<template> <div class="f-button" @click="addColor">+ Add Color</div> {{ activeColor }} <div class="f-colors"> <Color v-for="color in colors" :color="color" :edit="activeColor === color" @click="setActive(color)"/> </div> </template> <script> import {useProjectStore} from "~/stores/projects"; import {storeToRefs} from "pinia"; import Color from "~/components/Color.vue"; export default defineComponent({ name: "ColorManagement", components: {Color}, setup() { const projectStore = useProjectStore() const { getColors, getActiveColor } = storeToRefs(projectStore); return { projectStore, colors: getColors, activeColor: getActiveColor }; }, methods: { addColor() { ... }, setActive(color) { this.projectStore.$patch({ activeColor: color }) } } }); </script>
组件2(Color)
<template> <div class="f-color"> <div class="f-color__actions" v-if="edit"> <div class="f-color__action" @click="cancelEdit"> <Cancel /><span>Cancel</span> </div> </div> </div> </template> <script> import Cancel from "~/components/icons/Cancel.vue"; import {useProjectStore} from "~/stores/projects"; import {storeToRefs} from "pinia"; export default defineComponent({ name: "Color", components: {Cancel}, props: ["color","edit"], setup() { const projectStore = useProjectStore() const { activeColor } = storeToRefs(projectStore); return { projectStore, activeColor }; }, methods: { cancelEdit() { this.projectStore.$patch({ activeColor: false }) } } }); </script>
nuxt.config.ts
export default defineNuxtConfig({ vite: { css: { preprocessorOptions: { scss: { additionalData: '@use "@/assets/styles/_styles.scss" as *;' } } } }, modules: ['@pinia/nuxt'] })
Store(projects.ts)
import { defineStore } from "pinia"; export const useProjectStore = defineStore({ id: 'project', state: () => { return { project: { colors: [{ color: false, name: '' }] }, activeColor: null } }, getters: { getColors(state){ return state.project.colors || []; }, getActiveColor(state){ return state.activeColor; } } });
原因分析
核心问题是事件冒泡引发的状态覆盖:
- 在
ColorManagement组件中,给Color组件根元素绑定了@click="setActive(color)"事件。当点击Color组件内部的Cancel按钮时,点击事件会向上冒泡到Color组件的根元素,触发父组件的setActive方法,将activeColor重新设置为当前color对象。 - 尽管
cancelEdit确实执行了状态修改,但紧接着冒泡触发的setActive会将状态改回,最终导致视觉上看起来cancelEdit未生效。
解决方案
方案1:阻止事件冒泡
修改Color组件中Cancel按钮的点击事件,添加.stop修饰符阻止冒泡:
<div class="f-color__action" @click.stop="cancelEdit"> <Cancel /><span>Cancel</span> </div>
方案2:调整事件绑定范围
将ColorManagement中绑定在Color组件根元素的点击事件,转移到Color组件内部的特定可点击元素上,避免内部操作触发父级事件。
内容的提问来源于stack exchange,提问作者trrrnncy
相关产品推荐
相关产品推荐

