joken-前端工程师

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::
  404 随笔 :: 39 文章 :: 8 评论 :: 20万 阅读

代码

  • store
import { defineStore } from "pinia";
import { ref } from "vue";

export const useMyTestStore = defineStore('mytestStore', () => {
  // state
  const count = ref(0);

  const count2 = ref(1);

  const increment2 = () => {
    count2.value++;
  };

  const increment = () => {
    count.value++;
  };

  return {
    count,
    count2,
    increment,
    increment2
  };
});
  • 使用方式1,直接解构,结果是不能响应式
<template>
  <div>
    <h1>Count: {{ count }}</h1>
    <button @click="increment">Increment</button>
    <div>
      {{ count2 }}
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, nextTick } from 'vue';
import { useMyTestStore } from './store/mytestStore';

const { count, increment } = useMyTestStore();


// 打印出来不是一个ref对象,会失去响应式,打印出来直接是值
console.log(count, "slkfjsdlfjsldfjsd")

const count2 = computed(() => {
  return count
})

console.log(count2.value, "sdfsdfsdfsfcvxcsfsdf")


// 打印出来是一个proxy对象
console.log(useMyTestStore(), "slfjsldfjslfjsldfjsljnvsld")



</script>
  • 正确使用的几种方式可以store 响应式
<template>
  <div>
    <h1>Count: {{ count }}</h1>
    <button @click="increment">Increment</button>
  </div>
  <div>
    <h1>Count2: {{ count2 }}</h1>
    <button @click="increment2">Increment</button>
  </div>
  <div>
    count3: {{ count3 }}
  </div>
  <div>
    <!-- 直接读取store的变量也可以响应式 -->
    count4: {{ store.count2 }}
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, nextTick } from 'vue';
import { storeToRefs } from "pinia"
import { useMyTestStore } from './store/mytestStore';

const store = useMyTestStore();
// 加上storeToRefs解构store的数据才不会失去响应式
const { count, count2 } = storeToRefs(store);
// 方法需要直接解构
const { increment, increment2 } = store;

console.log(count, "count")

// computed 读取store的自变量也可以响应式
const count3 = computed(() => store.count2)




</script>

总结

这篇文章讨论了在 Vue 3 中使用 Pinia 时,解构赋值导致响应性丢失的问题,并提供了解决方案。以下是文章的主要内容总结:

问题描述

在使用 Pinia 作为状态管理库时,通过解构赋值获取 store 中的状态可能会导致这些状态失去响应性。这是因为解构赋值会创建原始数据的浅拷贝,而这些拷贝并不是响应式的。

解决方案

  1. 使用 storeToRefs

    • 通过 storeToRefs 函数将 Pinia store 中的状态转换为响应式引用。即使通过解构赋值获取状态,这些状态仍然保持响应性。
    import { defineComponent } from 'vue';  
    import { useStore } from './stores/yourStore';  
    import { storeToRefs } from 'pinia';  
    
    export default defineComponent({  
      setup() {  
        const store = useStore();  
        const { someState, anotherState } = storeToRefs(store);  
    
        return {  
          someState,  
          anotherState,  
        };  
      },  
    });
    
  2. 使用 computedwatch

    • 如果需要基于 store 中的状态计算新值或监听这些状态的变化,可以使用 Vue 的 computedwatch。这虽然不是直接解决解构赋值响应性丢失的问题,但提供了另一种处理响应性数据的方法。
    import { defineComponent, computed } from 'vue';  
    import { useStore } from './stores/yourStore';  
    
    export default defineComponent({  
      setup() {  
        const store = useStore();  
        const computedValue = computed(() => store.someState + 1);  
    
        return {  
          computedValue,  
        };  
      },  
    });
    
  3. 直接访问 Store 属性

    • 如果不涉及解构赋值,直接在模板或计算属性中访问 store 的属性,这些属性自然是响应式的。
    <template>  
      <div>{{ store.someState }}</div>  
    </template>  
    
    <script>  
    import { defineComponent } from 'vue';  
    import { useStore } from './stores/yourStore';  
    
    export default defineComponent({  
      setup() {  
        const store = useStore();  
        return { store };  
      },  
    });  
    </script>
    
posted on   joken1310  阅读(460)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示