You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PersistedState时,如何从Vuex getter中删除对象?

问题解决:Vuex PersistedState下无法正确删除收藏商品

问题根源

你直接在组件中修改了Vuex getter返回的数组(this.FAVOURITES.splice(...)),这违反了Vuex的核心规则——所有状态变更必须通过mutation完成。直接修改数组虽会暂时更新视图,但Vuex DevTools无法追踪该变更,同时vuex-persistedstate插件也不会感知到状态变化,导致DevTools中状态未同步,且刷新后数据会恢复。


解决方案

1. 在Vuex Store中添加删除逻辑

修改store.js,新增删除收藏商品的mutation和action:

// store.js
import { createStore } from 'vuex'
import axios from "axios"
import createPersistedState from "vuex-persistedstate";

export default createStore({
  state: {
    products: [],
    favourites: []
  },
  getters: {
    PRODUCTS(state){
      return state.products
    },
    PRODUCT_BY_ID(state){
      return ProductId => {
        return state.products.find(Product => Product.id === ProductId)
      }
    },
    FAVOURITES(state){
      return state.favourites
    }
  },
  mutations: {
    SET_PRODUCTS_TO_STATE: (state, products) =>{
      state.products = products
    }, 
    SET_TO_FAVOURITES: (state, favouritesItem) =>{
      // 优化:用some替代map检查商品是否存在
      const productExists = state.favourites.some(item => item.id === favouritesItem.id)
      if (!productExists) {
        state.favourites.push(favouritesItem)
      }
    },
    // 新增:删除收藏商品的mutation
    REMOVE_FROM_FAVOURITES: (state, productId) => {
      // 用filter返回新数组,确保状态变更被Vuex追踪
      state.favourites = state.favourites.filter(item => item.id !== productId)
    }
  },
  actions: {
    async GET_PRODCUTS_FROM_DB({commit}){
      try {
        const products = await axios("http://localhost:3000/products", {
          method: "GET"
        })
        commit("SET_PRODUCTS_TO_STATE", products.data)
        return products.data
      } catch (error) {
        return error
      }
    },
    ADD_TO_FAVOURITES({commit}, favouritesItem){
      commit('SET_TO_FAVOURITES', favouritesItem)
    },
    // 新增:删除收藏商品的action
    REMOVE_FROM_FAVOURITES({commit}, productId){
      commit('REMOVE_FROM_FAVOURITES', productId)
    }
  },
  modules: {},
  plugins: [
    createPersistedState()
  ]
})

2. 修改组件中的删除逻辑

修改products-item.js的addToCarts方法,通过Vuex action触发删除:

// products-item.js
<script>
import { mapGetters } from 'vuex'
export default {
    name: "ProductsCart",
    data(){
        return {
            IsProductExist: false
        }
    },
    computed: {
        ...mapGetters([
            'FAVOURITES'
        ]),
    },
    props: {
        Productsitem: {
            type: Object,
            default() {
                return {}
            }
        }
    },
    methods: {
        addToCarts(){
            if(this.$route.name === 'Favourites'){
                // 调用Vuex action删除商品,传入商品ID
                this.$store.dispatch('REMOVE_FROM_FAVOURITES', this.Productsitem.id)
            } else {
                this.$emit('addToCarts', this.Productsitem)
                this.IsProductExist = true
            }
        }
    },
    mounted(){
        this.$nextTick(() => {
            if(this.FAVOURITES.length > 0){
                this.IsProductExist = this.FAVOURITES.some(item => item.id === this.Productsitem.id)
            }
        })
    }
}
</script>

为什么这样有效

  • 遵循Vuex单向数据流原则,所有状态变更通过mutation完成,确保Vuex DevTools能正确追踪状态变化。
  • vuex-persistedstate插件会监听mutation触发,自动将更新后的状态持久化到本地存储,避免刷新后数据恢复。
  • 使用filter返回新数组的方式,比splice更符合Immutable状态更新的最佳实践,减少潜在的响应式问题。

内容的提问来源于stack exchange,提问作者Nikolay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 00:51:20