1、什么是pinia?
Pinia 是 Vue 的存储库,是 Vuex 的升级版。它允许您跨组件/页面共享状态,并且具有更小的体积、更简单的 API、支持插件扩展等功能。Pinia 中可以直接使用 store 实例去修改 state 中的数据,也可以通过调用 store 上的 $reset() 方法将状态重置到其初始值。Pinia 支持 action 支持同步和异步,并且具有良好的 Typescript 支持。
2、导入pinia,在main.js中:
// 导入App根组件
import App from './App'
// 导入pinia
import * as Pinia from 'pinia'
// 导入全局scss
import './uni.scss'
// #ifndef VUE3
// 导入Vue
import Vue from 'vue'
// 产品提示为fase
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
// 创建app
import { createSSRApp } from 'vue'
// 导入创建app方法
export function createApp() {
// 创建app实例
const app = createSSRApp(App)
// 创建pinia实例
const pinia = Pinia.createPinia();
// 使用pinia
app.use(pinia);
// 添加一个全局的的方法
app.config.globalProperties.$reverse = function(str){
return str.split('').reverse().join('');
}
// 返回了app
return {
app,
Pinia
}
}
// #endif
3、pinia在页面中的使用,在项目的根目录下(pages同级目录)创建一个文件夹stores
然后创建你的store文件,如:useAuthStore.js:
import {defineStore} from 'pinia';
import {getUserInfo} from '@/api/index.js'
import {ref} from 'vue';
// 定义了一个仓库
export const useAuthStore = defineStore("auth",()=>{
// 用户信息
const userInfo = ref({});
// 获取用户信息
function getUser(){
getUserInfo()
.then(res=>{
// 更新用户信息
userInfo.value = res.data;
})
}
// 返回用户信息与获取用户方法
return {userInfo,getUser};
})
选项式api useCounterStore.js:
import {defineStore} from 'pinia'
// 定义仓库有两种定义方式
// 01 选项options方式
export const useCounterStore = defineStore("counter",{
// 定义状态
state:()=>({count:5}),
// 计算数据
getters:{
doubleCount:(state)=>state.count*2
},
// 动作支持异步
actions:{
setCount(v){
this.count = v;
}
}
})
调用登录api接口:
import {defineStore} from 'pinia'
import {ref} from 'vue'
export const useUserStore = defineStore("user",()=>{
// state :userInfo,token,
const userInfo = ref({})
const token = ref('');
// actions:login,logout
function login(data){
var that = this;
uni.request({
url:"http://localhost:8888/api/login",
method:"POST",
data,
success(res){
console.log("res",res)
if(res.data.code===200){
// 更新store
userInfo.value = res.data.user;
token.value= res.data.token;
// 本地存储
uni.setStorageSync("userInfo",res.data.user)
uni.setStorageSync("token",res.data.token);
uni.showToast({
title:res.data.msg,
icon:'success'
})
// 跳转到首页
uni.redirectTo({
url:'/pages/index/home'
})
}else{
uni.showToast({
title:res.data.msg,
icon:'none'
})
}
},
fail(){
uni.showToast({
title:"登录失败",
icon:'error'
})
}
})
}
function logout(){
}
return {userInfo,token,login,logout}
})
设置颜色useColorStore.js:
// 导入定义仓库的方法
import {defineStore} from 'pinia';
// 导入响应式和计算
import {ref} from 'vue'
const useColorStore = defineStore("color",()=>{
// 定义一个状态颜色为 默认红色
const color=ref('red');
// 定义一个设置状态的方法
const setColor = v=>{
color.value = v;
}
// 导入
return {color,setColor}
})
export default useColorStore;
4、那么如何调用呢?
比如我们在user.vue页面中调用:
<template>
<view>
<view v-if="store.userInfo&&store.userInfo.nickName">
<view>{{store.userInfo.nickName}}</view>
<view><image :src="store.userInfo.headImgUrl" style="width:100rpx;height:100rpx;"/></view>
</view>
<view v-else>
<navigator url="../login/login">登录</navigator>
</view>
</view>
</template>
<script setup>
import {useAuthStore} from '@/stores/useAuthStore.js'
const store = useAuthStore();
</script>
选项式api的调用:
<template>
<view>
pinia 大菠萝,doubleCount:{{doubleCount}}
<button @click="setCount(count+1)">{{count}}</button> <button
@click="counterStore.count++"
type="primary">{{counterStore.count}}</button>
</view>
</template>
<script>
import {useCounterStore} from '@/stores/useCounterStore.js'
// mapState 映射状态,mapActions映射动作,mapStores 导入仓库
import {mapState,mapActions,mapStores} from 'pinia';
export default {
data(){},
computed:{
// 把pinia 的state映射到页面
...mapState(useCounterStore,["count","doubleCount"]),
...mapStores(useCounterStore)
},
methods:{
// 把pinia的方法映射到页面
...mapActions(useCounterStore,["setCount"])
},
}
</script>
登录api的调用:
<template>
<view>
首页
<navigator open-type="navigateBack">返回</navigator>
<navigator url="../log/log" open-type="redirect">日志</navigator>
<view>{{user.name}}</view>
<view>分数:{{user.score}}</view>
<view><image :src="user.avatar" style="width:100rpx;height:100rpx"></image></view>
</view>
</template>
<script setup>
// 计算方法
import {computed} from 'vue'
// 导入仓库
import {useUserStore} from '@/stores/useUserStore.js'
// 使用仓库
const userStore = useUserStore();
// 计算出简洁的用户信息
const user = computed(()=>userStore.userInfo)
</script>
<style>
</style>
<template>
<view>
<view>登录</view>
<view>
用户名:<input v-model="user.name"/>
</view>
<view>
密码:<input v-model="user.password"/>
</view>
<button type="primary" @click="userStore.login(user)">登录</button>
<navigator url="./home">首页</navigator>
</view>
</template>
<script setup>
// 导入仓库
import {useUserStore} from '@/stores/useUserStore.js'
// 导入响应方法
import {reactive} from 'vue'
const user = reactive({name:'',password:''})
// 定义仓库
const userStore = useUserStore();
</script>
设置颜色的调用:
<template>
<view>
<view :style="'background-color:'+colorStore.color">setup pinia</view>
<button size="mini" @click="colorStore.setColor('#fff')">白色</button>
<button size="mini" @click="colorStore.setColor('#36f')" type="primary">蓝色</button>
<button size="mini" @click="colorStore.color='#f36'" type="warn">橙色</button>
<view :style="'background-color:'+color">color</view>
<button size="mini" @click="colorStore.setColor('#ff0')" type="warn">黄色</button>
</view>
</template>
<script setup>
// 导入计算方法
import {computed} from 'vue'
// 导入颜色仓库
import useColorStore from '@/stores/useColorStore.js'
// 创建颜色仓库
const colorStore = useColorStore();
// 这样写颜色color并不是响应式x
// const {setColor,color} = colorStore
// 颜色简写计算
const color = computed(()=>colorStore.color) //√
</script>
2023-11-24 start
uniapp pinia持久化插件:
pinia-plugin-unistorage - DCloud 插件市场
end