vue3 pinia 写法和 pinia 中数据 proxy 对象如何获取使用

main.ts


import pinia from '@/stores'
app.use(pinia); 引入store/index.ts中的pinia
store/index.ts
import { createPinia } from 'pinia'
import piniaPersist from 'pinia-plugin-persist'

const pinia = createPinia()
// 永久持久化插件
pinia.use(piniaPersist);
export default pinia

store/user.ts
// 使用持久化存储

import {defineStore} from 'pinia'
import { getMenusApi } from '@/api/user'
import { toRaw } from '@vue/reactivity'
export const useUserStore=defineStore('storeUser',{
    state:()=>{
        return{
            fistName:"",
            lastName:"",
            accessToken:"",
            meunList:<any>[]
        }
    },
    getters:{
      getMeunList:(state)=>{
        return state.meunList
      }
    },
    actions:{
        setToken(value:string){
            this.accessToken=value
        },
        // 获取菜单
        getMenus() {
          let that=this;
            return new Promise((resolve, reject) => {
              getMenusApi().then((response:any) => {
                that.meunList= [{name:""}];
                // that.meunList= JSON.parse(response) ;
                console.log("数据00000000000",toRaw(that.meunList))
                localStorage.setItem('MerMenuList', JSON.stringify(response))
                resolve(response)
              }).catch(error => {
                reject(error)
              })
            })
          },
    },
    persist:{
        enabled:true //启用插件
    }
})

在页面中使用

import  {useUserStore}  from '@/stores/user'
import { toRaw } from '@vue/reactivity'
//使用vue3.0时,因为底层是使用proxy进行代理的,所以当我们打印一些值的时候,是proxy代理之后的是Proxy对象,Proxy对象里边的[[Target]]才是真实的对象。
let store=useUserStore();
store.getMenus() //调用actions方法
let meunList=toRaw(store.meunList)
//通过vue中的响应式对象可使用toRaw()方法获取原始对象 这样这个数据就可以直接使用了
console.log( meunList,"路由----")

我们发现起始store中的值已经改变了,但是子组件没有响应式,该问题的原因是我们子组件采用了解构的方式调用,而该种方式是不能达到响应式的目的的,但是pinia给我们提供了解决办法。
我们修改一下上面的调用方式-2,调用pinia提供的storeToRefs方法。

<template>
<p>---child---</p>
<p>name:{{name}}</p>
<p>age:{{age}}</p>
<p>sex:{{sex}}</p>
</template>

<script setup lang="ts">
import { useUsersStore } from "../store/user";
import {storeToRefs} from 'pinia'

const store = useUsersStore();
const { name, age, sex } = storeToRefs(store);
</script>

此时可以看见,子组件也是响应式了。完美解决。而两种调用方式(推荐第二种)

5)同时修改多个state里的值

  • 面我们修改state的数据是都是一条一条修改的,比如store.name="张三"等等,如果我们一次性需要修改很多条数据的话,有更加简便的方法,使用store的$patch方法,修改app.vue代码,添加一个批量更改数据的方法。
App.vue

<button @click="patchStore2">批量修改数据</button>

// 法一
const patchStore = () => {
  store.$patch({
    name: "张三",
    age: 100
  });
};
// 法二(推荐)
const patchStore2 = () => {
  store.$patch((state) => {
    state.name='张三'
    state.age = 99
  })
};

3)getters方法中带参数
有时我们需要手动传递参数到方法执行,我们可以如此

user.ts

getters: {
    getAddParamsAge: (state) => {
      return (params:number)=>state.age + 100 + params;
    },
  },


App.vue

<p>getters+Params:{{store.getAddParamsAge(500)}}</p>

基本使用之actions

前面我们提到的state和getters属性都主要是数据层面的,并没有具体的业务逻辑代码,它们两个就和我们组件代码中的data数据和computed计算属性一样。
那么,如果我们有业务代码的话,最好就是写在actions属性里面,该属性就和我们组件代码中的methods相似,用来放置一些处理业务逻辑的方法。
actions属性值同样是一个对象,该对象里面也是存储的各种各样的方法,包括同步方法和异步方法。
*1)添加actions(此时的useUsersStore即是最基本的一个架构了)

user.ts

import { defineStore } from 'pinia'
export const useUsersStore = defineStore('users', {
  // 其它配置
  state: () => {
    return {
      name: "李华",
      age: 25,
      sex: "男",
    }
  },
  getters: {
    getAddAge: (state) => {
      return state.age + 100;
    },
    getAddParamsAge: (state) => {
      return (params:number)=>state.age + 100 + params;
    },
    getNameAndAge(): string {
      return this.name + this.getAddAge;
    },
  },
  actions: {
    saveName(name: string) {
      // 修改state中的name
      this.name = name;
    },
  },
})

  • 调用
App.vue

<button @click="store.saveName('李成功')">action</button>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初遇你时动了情

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值