请注意,store
是一个用reactive
包裹的对象,这意味着不需要在getter 之后写.value
,但是,就像setup
中的props
一样,我们不能对其进行解构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <!-- * @Description: * @Author: xiuji * @Date: 2022-11-20 09:14:30 * @LastEditTime: 2023-04-14 15:44:58 * @LastEditors: Do not edit --> <template> <div class="content"> <h2> <!-- {{ store.bikini }}--{{ store.count }} --> {{ count }} </h2> <button @click="addCount">addCount</button> </div> </template>
<script setup lang="ts"> import { useStore } from '@/store/index.ts'; const store = useStore(); // ❌ 这不起作用,因为它会破坏响应式 // 这和从 props 解构是一样的 let { count } = store; // 此时count已经不是响应式的了 const addCount = () => { count++; console.log('count', count); }; </script>
<style lang="scss" scoped> .content { position: relative; flex: 1; height: 100%; margin: 20px; border: 1px solid #ccc; overflow: auto; } </style>
|
为了从 Store 中提取属性同时保持其响应式,您需要使用storeToRefs()
。 它将为任何响应式属性创建 refs。详情参见Pinia官方文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <!-- * @Description: * @Author: xiuji * @Date: 2022-11-20 09:14:30 * @LastEditTime: 2023-04-14 15:43:45 * @LastEditors: Do not edit --> <template> <div class="content"> <h2> <!-- {{ store.bikini }}--{{ store.count }} --> {{ count }} </h2> <button @click="addCount">addCount</button> </div> </template>
<script setup lang="ts"> import { storeToRefs } from 'pinia'; import { useStore } from '@/store/index.ts'; const store = useStore(); // `count`是响应式引用 const { count } = storeToRefs(store); const addCount = () => { console.log('count', count); count.value++ }; </script>
<style lang="scss" scoped> .content { position: relative; flex: 1; height: 100%; margin: 20px; border: 1px solid #ccc; overflow: auto; } </style>
|
storeToRefs其原理跟toRefs 一样的给里面的数据包裹一层toRef
通过toRaw使store变回原始数据防止重复代理
循环store 通过 isRef isReactive 判断 如果是响应式对象直接拷贝一份给refs 对象 将其原始对象包裹toRef 使其变为响应式对象