Piana:Vue专属最新状态管理库(Vuex状态管理工具的替代)
- 提供更简单的API(去掉mutation)
- 提供与vue3语法一致的组合式风格API
- 去掉modules概念,每一个store都是独立模块
- 搭配TypeScript 一起使用提供可靠类型判断
安装Piana
可以查看Piana官方文档进行操作
用自己喜欢的包管理器执行安装命令就好了,个人喜好npm
npm install pinia
安装成功后,需要吧Piana添加到项目中如下代码所示:
//1、导入creatPiana
import { createPinia } from 'pinia'
//2、执行方法得到实例
const piana = createPinia()
//3、把Piana实例加入到app应用中
createApp(App).use(piana).mount('#app')
初步使用Piana完成计数器自增
store:一个放数据的仓库(可以算公共组件)我们需要使用defineStore方法来创建,这个store会存放全局使用的数据如下代码所示
import { defineStore } from "pinia";
import { ref } from "vue";
export const useCounterStore = defineStore(
'counter' , () => {
//定义数据
const count = ref(0)
//定义修改数据的方法(action 同步+异步)
const increment = () => {
count.value ++
}
//以对象形式return供数组使用
return {
count,
increment
}
}
)
需要在src目录下创建stores文件夹用来存放创建的各种store
主页面把这个store引入后当对象调用就好了,如下代码所示:
<script setup>
import { useCounterStore } from './stores/counter';
const counterStore = useCounterStore()
console.log(counterStore)
</script>
<template>
<div>
<button @click="counterStore.increment">{{counterStore.count}}</button>
</div>
</template>
getters实现
使用computed函数模拟
import { defineStore } from "pinia";
import { computed, ref } from "vue";
export const useCounterStore = defineStore(
'counter' , () => {
//定义数据
const count = ref(0)
//定义修改数据的方法(action 同步+异步)
const increment = () => {
count.value ++
}
//getter定义
const doubleCount = computed(() => count.value * 2)
//以对象形式return供数组使用
return {
count,
increment,
doubleCount
}
}
)
异步action
Piana去掉mutation只使用action来实现同步和异步
<script setup>
import { useCounterStore } from './stores/counter';
import { onMounted } from 'vue';
const counterStore = useCounterStore()
console.log(counterStore)
onMounted(() => {
counterStore.getList()
})
</script>
<template>
<div>
<button @click="counterStore.increment">{{counterStore.count}}</button>
<div>{{counterStore.doubleCount}}</div>
<ul>
<li v-for="item in counterStore.list" :key="item.id">
{{item.name}}
</li>
</ul>
</div>
</template>
import { defineStore } from "pinia";
import { computed, ref } from "vue";
import axios from "axios";
export const useCounterStore = defineStore(
'counter' , () => {
//定义数据
const count = ref(0)
//定义修改数据的方法(action 同步+异步)
const increment = () => {
count.value ++
}
const API_URL = "https://geek.itheima.net/V1_0/channels"
//getter定义
const doubleCount = computed(() => count.value * 2)
//action 实现异步
const list = ref([])
const getList = async () => {
const res = await axios.get(API_URL)
list.value = res.data.data.channels
}
//以对象形式return供数组使用
return {
count,
increment,
doubleCount,
list,
getList
}
}
)
直接对store解构赋值会导致响应式丢失(数据类型),解决这个问题我们需要使用storeToRefs方法对需要解构的store(数据)进行包裹,方法直接解构即可
//直接解构会导致响应式丢失
//const {count , doubleCount} = useCounterStore
//使用storeToRefs对需要解构的store响应式不会丢失
const {count , doubleCount} = storeToRefs(useCounterStore)
//在对方法进行结构时,直接解构即可,storeToRefs只用来包裹数据
const{ increment } = useCounterStore