Vue3
vue3状态管理工具pinia
什么是pinia?
pinia 是Vue的最新状态管理工具,是Vuex的替代品;
好处:
- 1、提供了更为简单的API(去掉了mutation )
- 2、提供符合组合式风格的API(和Vue3新语法统一)
- 3、去挑了modules 的概念,每一个store都是一个独立的模块;
- 4、配合 typeScript 更加友好,提供可靠的类型判断;
1、安装pinia
yarn add pinia
# 或者使用 npm
npm install pinia
配置
-
引入
import { createPinia } from 'pinia'
-
创建实例
const pinia = createPinia()
-
Vue插件使用
app.use(pinia)
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
2、创建一个store仓库
【注意】
需要使用defineStore来创建store仓库,有两个参数;
第一个参数是仓库的唯一标识;
第二个参数是一个箭头函数;(setup组合式API)
创建好仓库之后,需要有一个变量来接收;变量名最好是use开头;
import {ref} from 'vue';
import {defineStore} from "pinia";
export const useCounterStore = defineStore('counter',()=>{
//声明数据 state
const count = ref(100);
// 创建操作数据的方法 action
const addCount = ()=>count.value++;
const subCount = ()=>count.value--;
// 通过computed创建基于数据派生的计算属性,getters
const double = computed(()=>{
return count.value * 2
}
)
return{
count,
double,
addCount,
subCount
}
})
在store仓库中有三个核心概念:state,getters,action;
在组合式API中:
- ref 就相当于state,数据;
- function函数就相当于是action,是方法;
- computed 函数就相当于是getter,是基于ref,state 的数据的计算属性;
- 定义好的数据,方法,需要return出去才可以使用;
3、使用store仓库
仓库创建好之后,如何使用里面的数据呢?
在组件中使用:
//引入
import {useCounterStore} from '@/store/counter.js';
const counterStore = useCounterStore();
// 在模版中使用
<p>使用store的数据:{{counterStore.count}}</p>
<p>使用store的中的方法</p>
<button @click="counterStore.addCount">+1</button>
4、action异步写法
action中的异步写法和组件当中的异步写法是一样的;
使用axios
npm i axios
创建list仓库
import axios from "axios";
import {defineStore} from "pinia";
import {ref} from 'vue';
export const useListStore = defineStore('list', () => {
//1、声明数据,创建一个空数组,是为了异步请求过来的数据保存在空数组中;
const channelsList = ref([]);
//2、声明操作数据的方法,异步请求数据
const getList = async () => {
const {data: {data}} = await axios.get('http://geek.itheima.net/v1_0/channels');
channelsList.value = data.channels;
console.log(data.channels)
}
return {
channelsList,
getList
}
})
使用
import {useListStore} from '@/store/list.js';
const listStore = useListStore();
<button @click="listStore.getList">获取数据</button>
<ul >
<li v-for="item in listStore.channelsList" :key="item.id">{{item.name}}</li>
</ul>
5、store 的解构使用
store 是一个用 reactive 包装的对象,这意味着不需要在 getters 后面写 .value;
为了从 store 中提取属性时保持其响应性,你需要使用 storeToRefs()。它将为每一个响应式属性创建引用
<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>
6、pinia的持久化插件
官网
https://prazdevs.github.io/pinia-plugin-persistedstate/zh/guide/why.html
安装
npm i pinia-plugin-persistedstate
配置
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
用法
创建 Store 时,将 persist 选项设置为 true。
使用组合式 Store 语法:
import { defineStore } from 'pinia'
export const useStore = defineStore(
'main',
() => {
const someState = ref('你好 pinia')
return { someState }
},
{
persist: true,
}
)
现在,你的整个 Store 将使用默认持久化配置保存。