vuex的替代品
三个概念,state、getter 和 action,相当于组件中的data、computed和methods。
1.创建一个空的vue3项目
npm create vue@latest
2.安装pinia
npm install pinia
3.导入挂载pinia
#main.js文件
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()#创建pinia实例
const app = createApp(App)
app.use(pinia)#注册使用
app.mount('#app')
Store
Store是一个保存状态和业务逻辑的实体,每个组件均可读取和写入它。它有三个概念,state、getter 和 action。
store定义
import { defineStore } from 'pinia'
// 第一个参数是Store 的唯一 ID
//1.选项式写法,第二参数为对象
export const useAlertsStore = defineStore('alerts', {
// 其他配置...
state: () => ({ count: 0 }),
getters: {
double: (state) => state.count * 2,
},
actions: {
increment() {
this.count++
},
},
})
//2.组合式写法,第二参数为函数
export const useCounterStore = defineStore('counter', () => {
const count = ref(0) #ref() 就是 state 属性
const doubleCount = computed(() => count.value * 2) #computed() 就是 getters
#function() 就是 actions
function increment() {
count.value++
}
return { count, doubleCount, increment }
})
store使用
<script setup>
import { useCounterStore } from '@/stores/counter'
// 可以在组件中的任意位置访问 `store` 变量 ✨
const store = useCounterStore()
</script>
注:不要直接解构ref,computed会丢失数据的响应式,action(方法)可直接解构(因为他不需要做修改),可使用storeToRefs进行解构
store是用reactive包装的对象,不需要使用.value获取数据
解构:相当于重新定义一个变量赋值
<script setup>
import { storeToRefs } from 'pinia'
const store = useCounterStore()
// `name` 和 `doubleCount` 是响应式的 ref
// 同时通过插件添加的属性也会被提取为 ref
// 并且会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性
const { name, doubleCount } = storeToRefs(store)
// 作为 action 的 increment 可以直接解构
const { increment } = store
</script>
pinia持久化(基本操作)(本地存储)
- 使用
localStorage进行存储 -
store.$id作为 storage 默认的 key - 使用
JSON.stringify/JSON.parse进行序列化/反序列化 - 整个 state 默认将被持久化
1.安装依赖
npm i pinia-plugin-persistedstate
2.将插件添加到 pinia 实例上
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
3.创建Store时,将persist选项设置为 true
//组合式api,在第三个参数位置加入
import { defineStore } from 'pinia'
export const useStore = defineStore(
'main',
() => {
const someState = ref('你好 pinia')
return { someState }
},
{
persist: true,
//自定义键名,
persist: {
key: 'my-custom-key',
paths: ['save.me', 'saveMeToo'],//持久化指定属性或方法
},
},
)
//选项式api
import { defineStore } from 'pinia'
export const useStore = defineStore('main', {
state: () => {
return {
someState: '你好 pinia',
}
},
persist: true,
})
小案例

同步action
异步action
import {defineStore} from 'pinia'
import { computed,ref } from 'vue'
import axios from 'axios'
export const useChanelStore=defineStore('chanel',()=>{
const chanel=ref([])
const getList= async()=>{
const {data:{data}}=await axios.get('http://geek.itheima.net/v1_0/channels')
chanel.value=data.channels
}
return {getList,chanel}
})
-----------------------------------------------------------------------------------------------------------
import { useChanelStore } from "@/stores/chanel";
const chanel = useChanelStore();
<button @click="chanel.getList">获取列表</button>
<ul>
<li v-for="item in chanel.chanel" :key="item.id">{{ item.name }}</li>
</ul>