Lecture10-Pinia 状态管理

文章目录

    [toc]

    单词词性音标含义
    storen./stɔː(r)/仓库,Pinia 里集中存放共享数据的容器
    staten./steɪt/状态,store 里的共享数据(类似全局变量)
    gettern./ˈɡetə(r)/派生值,由 state 算出来(类似 computed)
    actionn./ˈækʃn/动作,修改 state 的方法(类似函数)
    sharedadj./ʃeə(r)d/共享的,只有多个组件都要用、还会变的数据才进 store
    defineStore-/dɪˈfaɪn stɔː(r)/方法,用 defineStore 定义一个全局数据仓库

    Lecture10-Pinia 状态管理

    1、本节讲什么

    学会把"多个组件都要用的数据"集中管理,类似后端的全局共享上下文。适合:登录用户、购物车、主题等。

    2、概念速览

    什么是状态:应用里"多个组件共享的数据"(如登录用户、购物车)。状态管理 = 把共享数据放一个中央仓库,任何组件都能读写。

    正确 vs 误区:不是所有数据都要进 Pinia——只有"多个地方都要用、还会变"的数据才需要;组件自己的临时数据放组件里就行。

    3、先看效果

    任意组件都能读、能改同一个"计数器",且所有用到它的组件自动同步。

    ① 安装

    npm install pinia
    

    ② main.ts 启用

    import { createPinia } from 'pinia'
    createApp(App).use(createPinia()).use(router).mount('#app')
    

    ③ src/stores/counter.ts(定义 store)

    import { defineStore } from 'pinia'
    
    // useCounterStore:一个全局数据仓库。所有组件共用这一份数据
    export const useCounterStore = defineStore('counter', {
      state: () => ({ count: 0 }),            // 数据(类似全局变量)
      getters: { double: (s) => s.count * 2 }, // 派生(类似 computed)
      actions: {
        increment() { this.count++ },          // 改数据的方法(类似函数)
      },
    })
    

    ④ 任意组件使用

    <script setup lang="ts">
    import { useCounterStore } from '../stores/counter'
    const store = useCounterStore()
    </script>
    <template>
      <p>count: {{ store.count }} · double: {{ store.double }}</p>
      <button @click="store.increment()">+1</button>
    </template>
    

    4、照着做

    1. 安装并启用 Pinia。
    2. 建 src/stores/counter.ts。
    3. 在两个不同组件里都用这个 store,点一个 +1,看另一个是否同步。

    对比 props:为什么 props 不能被 Pinia 取代

    场景用什么为什么
    父组件给子组件一次性传参(如列表→行、配置→组件)props / 事件这是组件的"接口",让组件可复用、可参数化
    多个不相干组件共享一份会变的全局数据Pinia需要"中央仓库"统一管理
    跨多层(爷爷→孙子的孙子)provide/inject省得一层层传,但用得少

    一句话:props 是"组件之间的参数传递"(局部、一次性),Pinia 是"全局共享仓库"(全局、多组件)——它俩解决的不是同一类问题。

    为什么不建议全都用 Pinia:把每个父子传参都塞进全局 store,store 会越来越臃肿、组件失去独立性、数据流向不清——这恰恰是"屎山"的来源。正确做法是:能局部(props)就局部,只有真正全局共享才用 Pinia。

    5、常见疑问

    • Q:什么时候该用 Pinia,什么时候不该? A:只有"多个组件真需要共享"的数据才放 store(如登录状态、购物车)。单组件自己的数据就放组件里,别全塞 store,否则一团乱。
    • Q:state / getters / actions 各是什么? A:state=共享数据;getters=由 state 算出来的派生数据;actions=修改数据的方法。和组件里的 ref/computed/函数一一对应。
    • Q:组件能直接改 store 的 state 吗? A:能(store.count++),但更推荐通过 actions 改,方便统一处理逻辑(比如改之前先校验)。

    6、规范要点

    • store 按业务域拆(user.ts、cart.ts),别一个 store 塞所有东西。
    • 修改状态走 actions,别在组件里到处 store.xxx++。
    • 命名:store 文件名小写驼峰,导出 useXxxStore。

    7、本节验证

    • 会安装并启用 Pinia(createPinia() + .use())✅
    • 会用 defineStore 定义 state / getters / actions ✅
    • 会在任意组件里 useXxxStore() 读写同一份共享数据 ✅
    • 说得清 props 与 Pinia 各自的适用场景,不乱塞全局 store ✅
    end