Vue 词条目录
前端Wiki/Vue/实战/路由与状态

Pinia 状态管理

Pinia 是 Vue 官方推荐的状态管理库:跨组件共享的数据(登录状态、购物车、主题)放进 store,任何组件都能读写,且修改可追踪。相比 Vuex,Pinia 没有 mutation、TS 支持更好、API 更简洁。

定义 store 用 defineStore("名字", () => {...})(组合式写法):内部 ref 是 state、普通函数是 action、computed 是 getter。组件中 const store = useCartStore() 后直接 store.items 读取、store.addItem(...) 调用。

  • 跨组件共享数据进 store,避免 props 层层透传(prop drilling)
  • state = ref,getters = computed,actions = 普通函数
  • Pinia 可拆分多个 store(用户、购物车、主题各自独立)
HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Pinia 状态管理</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/pinia/dist/pinia.iife.js"></script>
</head>
<body>
  <div id="app">
    <cart-view></cart-view>
    <cart-bar></cart-bar>
  </div>

<script>
  const { createApp, ref, computed } = Vue;
  const { createPinia, defineStore } = Pinia;

  // 定义购物车 store(组合式写法)
  const useCartStore = defineStore('cart', () => {
    const items = ref([]);                     // state
    const count = computed(() => items.value.length);   // getter
    const add = (name) => items.value.push({ name });   // action
    const clear = () => items.value = [];
    return { items, count, add, clear };
  });

  const app = createApp({});
  app.use(createPinia());

  app.component('cart-view', {
    setup() {
      const store = useCartStore();   // 两个组件共享同一 store
      return { store };
    },
    template: `<div>
        <p>商品:{{ store.items.map(i => i.name).join('、') || '空' }}({{ store.count }} 件)</p>
        <button @click="store.add('商品' + (store.count + 1))">加入</button>
      </div>`
  });
  app.component('cart-bar', {
    setup() {
      const store = useCartStore();
      return { store };
    },
    template: `<div>底部栏:共 {{ store.count }} 件
        <button @click="store.clear()">清空</button></div>`
  });

  app.mount('#app');
</script>
</body>
</html>
本节要点Pinia 三件套:ref 当 state、computed 当 getter、函数当 action;store 是跨组件共享数据的单例。