vue3.0之Pinia(状态管理工具)

vue3.0之Pinia(状态管理工具)

  • 官网:pinia
  • 下载
    • yarn add pinia -S
  • 引入 main.ts
import { createApp } from 'vue'
import App from './App.vue'

// 引入重置样式
import "./assets/css/reset.css"
// 引入全局组件
import Card from './components/card/Card.vue'
// 引入拖拽指令
import DragDirective from "./directive/drag.ts"
const app = createApp(App)

// 引入状态 管理工具
import { createPinia } from "pinia"
const store= createPinia()
app.use(store)

app.use(DragDirective).component('Card',Card).mount('#app')

创建一个pinia状态管理仓库

  • src / store / index.ts
  • src / store / store-namespce.ts

index.ts


import { defineStore } from 'pinia'
import { Names } from './store-namespce'
 
// defineStore() 参数1:唯一值;参数2:一个对象,里面有着3个模块 state状态数据、
export const useTestStore = defineStore(Names.Test, {
  state:()=>{
    return {
        current:1,
        name:"xzl"
      }
  },
  //类似于computed 可以帮我们去修饰我们的值
  getters:{
 
  },
  //可以操作异步 和 同步提交state
  actions:{

  }

})

store-namespce.ts

// store 唯一值 (类似 vuex的命名空间 )
export const enum Names {
  Test = 'TEST'
}

访问 pinia之中的 state数据

<template>
  <div>
    我是app
    <div>{{ Test.current }} -- {{ Test.name }}</div>
  </div>
</template>

<script setup lang="ts">
import { useTestStore } from './store/index'
const Test = useTestStore()
  • 效果
    在这里插入图片描述

修改pinia之中的 state 总共有5种方式

  • 推荐使用的是
    • 方式5:触发 actions
    • 方式3:工程函数的形式 修改 里面包含 逻辑 -> 推荐之
    • 方式1:直接修改 pinia 里面的 state 数据

store-namespce.ts

// store 唯一值 (类似 vuex的命名空间 )
export const enum Names {
  Test = 'TEST'
}

store / indes.ts


import { defineStore } from 'pinia'
import { Names } from './store-namespce'
 
// defineStore() 参数1:唯一值;参数2:一个对象,里面有着3个模块 state状态数据、
export const useTestStore = defineStore(Names.Test, {
  state:()=>{
    return {
        current:1,
        name:"xzl"
      }
  },
  //类似于computed 可以帮我们去修饰我们的值
  getters:{
 
  },
  //可以操作异步 和 同步提交state
  actions:{
    // 方式5 之 不传递 参数
    // setCurrent () {
    //   this.current = 1000
    // }
    // 方式5 之 传递 参数
    setCurrent (num:Number) {
      this.current = num
    }
  }
})

App.vue

<template>
  <!-- <Layout></Layout> -->
  <div>
    我是app
    <div>{{ Test.current }} -- {{ Test.name }}</div>
    <button @click="changeNum">修改</button>
  </div>
</template>

<script setup lang="ts">
// import Layout from './layout/Layout.vue'
import { useTestStore } from './store/index'
const Test = useTestStore()

const changeNum = () => {
  // Test.current++ // 方式1 直接修改 pinia中 state的 数据
  // 方式2 批量 修改 pinia中 state的 数据
  // Test.$patch({
  //
  //   current: 22,
  //   name: '小渣亮',
  // })
  // 方式3:工程函数的形式 修改 里面包含 逻辑 -> 推荐之
  // Test.$patch((state) => {
  //   if (state.current === 1) {
  //     state.current = 100
  //   }
  //   state.name = '小菜鸡'
  // })
  // 方式4:必须修改整个 state对象 也就是当前 state对象有多少属性,都得修改
  // Test.$state = {
  //   current: 100,
  //   name: '222',
  // }
  // 方式5:调用 actions之中的方法去修改 pinia中 的state数据
  // Test.setCurrent()
  Test.setCurrent(999)
}
</script>
<style lang="scss">
html,
body,
#app {
  height: 100%;
  width: 100%;
  overflow: hidden;
}
</style>

解构store 函数 使得解构的数据具有响应式

store / index.ts


import { defineStore } from 'pinia'
import { Names } from './store-namespce'
 
// defineStore() 参数1:唯一值;参数2:一个对象,里面有着3个模块 state状态数据、
export const useTestStore = defineStore(Names.Test, {
  state:()=>{
    return {
        current:1,
        name:"xzl"
      }
  },
  //类似于computed 可以帮我们去修饰我们的值
  getters:{
 
  },
  //可以操作异步 和 同步提交state
  actions:{
  }
})

app.vue

<template>
  <div>
    我是app
    <div>{{ current }} -- {{ Test.name }}</div>
    <button @click="changeNum">修改</button>
  </div>
</template>

<script setup lang="ts">
import { useTestStore } from './store/index'
const Test = useTestStore()
// 解构 pinia 出来的数据 是不具备响应式属性的 需要属于 storeToRefs 去转化
import { storeToRefs } from 'pinia'
let { current, name } = storeToRefs(Test)

const changeNum = () => {
  current.value++
  Test.$patch(() => {
    if (current.value % 2 === 0) {
      name.value = '偶数-小小狗'
    } else {
      name.value = '基数-小小狗'
    }
  })
}
</script>
<style lang="scss">
html,
body,
#app {
  height: 100%;
  width: 100%;
  overflow: hidden;
}
</style>

  • 效果
    在这里插入图片描述

pinia实现一个 简单的异步 修改 state数据 (与同步)

store / index.ts


import { defineStore } from 'pinia'
import { Names } from './store-namespce'

type UserInfo = {
  name:String
  age:Number
}
// 同步写法
let user:UserInfo = {
  name:"xxx",
  age:11
}

// 模拟异步
const Login = ():Promise<UserInfo> =>{
  return new Promise((resolve)=>{
    setTimeout(()=>{
      resolve({
        name:"xzl",
        age:20
      })
    },2000)
  })
}

// defineStore() 参数1:唯一值;参数2:一个对象,里面有着3个模块 state状态数据、
export const useTestStore = defineStore(Names.Test, {
  state:()=>{
    return {
        user:<UserInfo>{},
        userInfo:<UserInfo>{},
      }
  },
  //类似于computed 可以帮我们去修饰我们的值
  getters:{
 
  },
  //可以操作异步 和 同步提交state
  actions:{
    // 修改 用户信息
    setUser (){
      this.user = user
    },
    // 异步的写法
    async setUserAsync () {
     const res =  await Login()
     this.userInfo = res;
     console.log("res", res);
    }
  }
})

app.vue

<template>
  <!-- <Layout></Layout> -->
  <div>
    我是app

    <div>user - {{ Test.user }}</div>
    <button @click="changeUser">修改用户</button>
    <div>userInfo - {{ Test.userInfo }}</div>
    <button @click="setUserAsync">修改用户async</button>
  </div>
</template>

<script setup lang="ts">
// import Layout from './layout/Layout.vue'
import { useTestStore } from './store/index'
const Test = useTestStore()
// 解构 pinia 出来的数据 是不具备响应式属性的 需要属于 storeToRefs 去转化
// import { storeToRefs } from 'pinia'
// import { userInfo } = storeToRefs(Test)

const changeUser = () => {
  Test.setUser() // 同步的写法 调用
}
const setUserAsync = () => {
  Test.setUserAsync() // 异步 写法调用
}
</script>
<style lang="scss">
html,
body,
#app {
  height: 100%;
  width: 100%;
  overflow: hidden;
}
</style>

  • 效果
    在这里插入图片描述

多个 actions之间 调用

store / index.ts


import { defineStore } from 'pinia'
import { Names } from './store-namespce'

type UserInfo = {
  name:String
  age:Number
}

// 模拟异步
const Login = ():Promise<UserInfo> =>{
  return new Promise((resolve)=>{
    setTimeout(()=>{
      resolve({
        name:"xzl",
        age:20
      })
    },2000)
  })
}

// defineStore() 参数1:唯一值;参数2:一个对象,里面有着3个模块 state状态数据、
export const useTestStore = defineStore(Names.Test, {
  state:()=>{
    return {
        user:<UserInfo>{},
        userInfo:<UserInfo>{},
      }
  },
  //类似于computed 可以帮我们去修饰我们的值
  getters:{
 
  },
  //可以操作异步 和 同步提交state
  actions:{
    // 异步的写法
    async setUserAsync () {
     const res =  await Login()
     this.userInfo = res;
    this.setName()
    },
    setName (){
      this.userInfo.name = "采狗"
    }
  }
})

pinia 之中的 getters 写法

store / index.ts


import { defineStore } from 'pinia'
import { Names } from './store-namespce'

// defineStore() 参数1:唯一值;参数2:一个对象,里面有着3个模块 state状态数据、
export const useTestStore = defineStore(Names.Test, {
  state:()=>{
    return {
        name:"小菜鸡"
      }
  },
  //类似于computed 可以帮我们去修饰我们的值
  getters:{
    getNewName():string {
      return `${this.name}`
    }
  },
  //可以操作异步 和 同步提交state
  actions:{
    changeName(name:string){
      this.name = name
    }
  }
})

app.vue

<template>
  <!-- <Layout></Layout> -->
  <div>
    我是app
    <div>getNewName - {{ Test.getNewName }}</div>
    <button @click="changeName">修改name</button>
  </div>
</template>

<script setup lang="ts">
import { useTestStore } from './store/index'
const Test = useTestStore()
// 解构 pinia 出来的数据 是不具备响应式属性的 需要属于 storeToRefs 去转化
// import { storeToRefs } from 'pinia'
// import { userInfo } = storeToRefs(Test)

const changeName = () => {
  Test.changeName('大菜鸡')
}
</script>
  • 效果
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值