vue3+ts使用pinia状态管理

38 篇文章 3 订阅

一、pinia 是什么?

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。

Pinia官网:https://pinia.vuejs.org/zh/introduction.html

二、代码示例

1.下载pinia插件

npm i pinia

2.引入和使用插件

main.ts

import { createApp } from 'vue'
import './style.css'
// 引入createPinia方法从pinia
import { createPinia } from 'pinia';
import App from './App.vue'

const app=createApp(App)
//拿到pinia实例
const pinia=createPinia()

//使用pinia
app.use(pinia)
app.mount('#app')

3.创建store/home.ts状态管理

store/home.ts

// 每个状态管理文件都要引入此方法
import { defineStore } from 'pinia'
 
// 官方建议取名遵从 useXXXStore 形式
// 'home' 为当前store的唯一标识 类似ID 
// 取名建议与文件名称一致 便于记忆和管理
// pinia舍弃了冗长的mutations属性 
// 以下是pinia的一种写法 因与vuex相似 便于学习和记忆
export const useHomeStore = defineStore('home',{
    state:()=>{
        return{
            num:0
        }
    },
    //state也可写成这样
    // state:()=>({
    //     num:0
    // }),
    actions:{
        changeNum(){
        //这里可以使用this去拿到state里定义的变量
            this.num ++
        }
    },
    getters:{
        // 这里取名不可与state里的变量一致 所以取名getNum
        getNum:state=>state.num
    }
})

4.页面使用

home.vue

<template>
  <div class="c">this is home page</div>
  <div class="c">
    <p>使用pinia直接改变变量</p>
    <!-- 3 解构赋值后直接在template模板里调用变量和方法 -->
    <p>{{ num }}</p>
    <button @click="changeNum">点击递增</button>
  </div>
</template>
 
<script lang="ts" setup>
import { toRefs } from 'vue'
// 1 引入
import { useHomeStore } from "../store/home";
// 2 拿到实例
const homeStore = useHomeStore();
// 3 解构里面的变量和方法 toRefs作用是让解构出来的变量具有响应性 
const { num,changeNum } = toRefs(homeStore);
 
</script>
 
<style scoped>
.c {
  width: 80%;
  padding: 20px;
  margin: 0 auto;
  border: 1px solid red;
}
.c>p>span{
  color:coral;
}
</style>

在这里插入图片描述点击按钮改变变量效果:
在这里插入图片描述
如果像这样频繁改变变量 官方建议使用 $patch 方法 (官方优化加持)

具体操作如下
home.vue

<template>
  <div class="c">this is home page</div>
  <div class="c">
    <p>使用pinia直接改变变量</p>
    <!-- 3 不解构赋值 在template模板里的写法 -->
    <p>{{ homeStore.num }}</p>
    <button @click="changeNum">点击递增</button>
  </div>
</template>
<script lang="ts" setup>
// 1 引入
import { useHomeStore } from "../store/home";
// 2 拿到实例
const homeStore = useHomeStore();
 
 
// 频繁改变homeStore里面的变量 建议使用$patch方法
 
// 一 $patch的对象式写法
// const  changeNum = ()=>{
//       homeStore.$patch({
//         num: ++ homeStore.num
//       })
// }
 
// 二 $patch的函数式写法
const changeNum = ()=>{
      // 这里的state就是home.ts里的state
      homeStore.$patch((state)=>{
          state.num ++
      })
}
 
</script>
<style scoped>
.c {
  width: 80%;
  padding: 20px;
  margin: 0 auto;
  border: 1px solid red;
}
.c>p>span{
  color:coral;
}
</style>

效果:
在这里插入图片描述
除了以上定义变量后 让变量自身变化的外 我们也可以在actions里请求接口数据赋值变量

如下

home.ts

// 每个状态管理文件都要引入此方法
import { defineStore } from 'pinia'
//引入接口
import { httpPost } from '../request/api'
 
// 官方建议取名遵从 useXXXStore 形式
// 'home' 为当前store的唯一标识 类似ID 
// 取名建议与文件名称一致 便于记忆和管理
// pinia舍弃了冗长的mutations属性 
// 以下是pinia的一种写法 因与vuex相似 便于学习和记忆
export const useHomeStore = defineStore('home',{
    state:()=>{
        return{
            num:0,
            token:''
        }
    },
    //state也可写成这样
    // state:()=>({
    //     num:0
    // }),
    actions:{
        changeNum(){
        //这里可以使用this去拿到state里定义的变量 下面同理
            this.num ++
        },
        changeToken(){
        // ts 实在学的不咋地 这里就先any了
        httpPost().then((res:any)=>{
            this.token = res.data.data.token
            })
        }
    },
    getters:{
        // 这里取名不可与state里的变量一致 所以取名getNum
        //简写
        getNum:state=>state.num,
        //全写
        // getNum:(state)=>{
        //     return state.num
        // }
        getToken:state=>state.token,
    }
})

相应组件页面使用

home.vue

<template>
  <div class="c">this is home page</div>
  <div class="c">
    <p>使用pinia直接改变变量</p>
    <!-- 解构赋值后直接在template模板里调用变量和方法 -->
    <p>{{ num }}</p>
    <button @click="changeNum">点击递增</button>
  </div>
  <div class="c">
    <button @click="changeToken">使用pinia请求数据接口赋值token</button>
    <p>token: <span>{{ token }}</span></p>
  </div>
</template>
<script lang="ts" setup>
import { toRefs } from 'vue'
// 1 引入
import { useHomeStore } from "../store/home";
// 2 拿到实例
const homeStore = useHomeStore();
// 3 解构里面的变量和方法 toRefs作用是让解构出来的变量具有响应性 
const { num,changeNum,token,changeToken } = toRefs(homeStore);
 
</script>
<style scoped>
.c {
  width: 80%;
  padding: 20px;
  margin: 0 auto;
  border: 1px solid red;
}
.c>p>span{
  color:coral;
}
</style>

在这里插入图片描述

5. 数据持久化

pinia 也存在和vuex一样的弊端 就是刷新页面后 数据丢失

我们可以使用 pinia-plugin-persistedstate 插件来完成数据持久化

数据持久化具体步骤

1.下载插件 pinia-plugin-persistedstate

npm i pinia-plugin-persistedstate

2.main.ts引入和使用插件

main.ts

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'
import elementPlus from 'element-plus'
import 'element-plus/dist/index.css'
 
 
// ① 引入createPinia方法从pinia
import { createPinia } from 'pinia'
// ② 拿到pinia实例
const pinia = createPinia()
 
// 1 引入数据持久化插件
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
// 2 pinia使用数据持久化插件
pinia.use(piniaPluginPersistedstate)
 
const app = createApp(App)
 
//使用pinia
app.use(router).use(elementPlus).use(pinia).mount('#app')

3.对应状态管理文件配置参数(这里以home.ts为例)

home.ts

// 每个状态管理文件都要引入此方法
import { defineStore } from 'pinia'
//引入接口
import { httpPost } from '../request/api'
 
// 官方建议取名遵从 useXXXStore 形式
// 'home' 为当前store的唯一标识 类似ID 
// 取名建议与文件名称一致 便于记忆和管理
// pinia舍弃了冗长的mutations属性 
// 以下是pinia的一种写法 因与vuex相似 便于学习和记忆
export const useHomeStore = defineStore('home',{
    state:()=>{
        return{
            num:0,
            token:''
        }
    },
    //state也可写成这样
    // state:()=>({
    //     num:0
    // }),
    actions:{
        changeNum(){
        //这里可以使用this去拿到state里定义的变量 下面同理
            this.num ++
        },
        changeToken(){
        // ts 实在学的不咋地 这里就先any了
        httpPost().then((res:any)=>{
            this.token = res.data.data.token
            })
        }
    },
    getters:{
        // 这里取名不可与state里的变量一致 所以取名getNum
        //简写
        getNum:state=>state.num,
        //全写
        // getNum:(state)=>{
        //     return state.num
        // }
        getToken:state=>state.token,
    },
    //数据持久化配置 这里是当前所有变量都持久化
    persist:true
})

效果:
在这里插入图片描述
在实际项目里 token持久化是我们所不希望的 那如何只让num这一变量持久化呢

进一步配置参数即可

home.ts

// 每个状态管理文件都要引入此方法
import { defineStore } from 'pinia'
//引入接口
import { httpPost } from '../request/api'
 
// 官方建议取名遵从 useXXXStore 形式
// 'home' 为当前store的唯一标识 类似ID 
// 取名建议与文件名称一致 便于记忆和管理
// pinia舍弃了冗长的mutations属性 
// 以下是pinia的一种写法 因与vuex相似 便于学习和记忆
export const useHomeStore = defineStore('home',{
    state:()=>{
        return{
            num:0,
            token:''
        }
    },
    //state也可写成这样
    // state:()=>({
    //     num:0
    // }),
    actions:{
        changeNum(){
        //这里可以使用this去拿到state里定义的变量 下面同理
            this.num ++
        },
        changeToken(){
        // ts 实在学的不咋地 这里就先any了
        httpPost().then((res:any)=>{
            this.token = res.data.data.token
            })
        }
    },
    getters:{
        // 这里取名不可与state里的变量一致 所以取名getNum
        //简写
        getNum:state=>state.num,
        //全写
        // getNum:(state)=>{
        //     return state.num
        // }
        getToken:state=>state.token,
    },
    //数据持久化配置 这里是当前所有变量都持久化
    // persist:true
     
    //按需配置数据持久化 这里指定变量num保持持久化
    persist:{
        //默认名称为当前store唯一标识 这里即home
        key:'homeNum',
        //默认localStorage 本地储存 
        //这里建议临时储存sessionStorage 也可写成window.sessionStorage
        storage:sessionStorage,
        //默认当前store里的所有变量都持久化
        paths:['num']
    }
})

在这里插入图片描述

三、总结

最后总结一下pinia一些优点

  • 舍弃了冗长的 mutations 属性

  • 舍弃了模块化 modules 让状态管理更加扁平化

  • 对于 ts 的支持更加友好 支持数据推断

  • 你甚至可以让各个状态管理相互依赖、嵌套

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3是Vue.js的下一个主要版本,它引入了一些功能和改进,以提高性能和开发体验。而TypeScript(TS)是一种强类型的JavaScript扩展,它添加了静态类型检查等功能。Pinia是一个以Composition API为基础的状态管理库,它与Vue3紧密集成在一起。而Vite是一种快速的构建工具,特别适用于Vue3的开发和构建。 在具体实现登录功能时,可以按照以下步骤进行: 1. 首先,需要安装Vue3、TypeScript、Pinia和Vite。可以通过npm或yarn等包管理工具进行安装。 2. 创建一个新的Vue3项目,并设置使用TypeScript。 3. 在项目的入口文件中引入Vue、Pinia和创建Pinia实例。 4. 在Pinia实例中定义一个用于存储登录信息的状态。 5. 创建一个登录组件,在组件中定义一个表单,用于输入用户名和密码。 6. 在组件中引入定义好的Pinia实例,并使用`useStore`函数获取存储登录信息的状态。 7. 在组件的`methods`中,编写处理登录功能的方法,验证用户名和密码是否正确。 8. 在组件的模板中,使用v-model指令将输入框与组件内的数据绑定,并绑定登录按钮的点击事件。 9. 在App组件中引入登录组件,并将其渲染到页面上。 10. 运行项目,在浏览器中打开页面,即可看到登录表单。 11. 输入正确的用户名和密码,点击登录按钮,触发登录方法,根据验证结果显示相应的提示信息。 通过以上步骤,可以实现一个基本的登录功能。使用Vue3、TypeScript、Pinia和Vite可以让开发过程更加高效和可靠。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值