Pinia使用state、getters、actions

1.1 安装
npm install pinia

1.2 main.js引入
import { createPinia } from ‘pinia’
app.use(createPinia())

1.3 根目录新建store/index.js中写入

import { defineStore } from 'pinia'
export const useStore = defineStore('storeId', {
  state: () => {
    return {
      counter: 0,
    }
  },
  getters:{},
  actions:{}
})

1.4 组件使用
import { useStore } from ‘…/store’
const store = useStore();

二、State

2.1 Pinia定义state数据

import { defineStore } from 'pinia'
export const useStore = defineStore('storeId', {
  state: () => {
    return {
      counter: 0,
      name: 'Eduardo',
      isAdmin: true,
    }
  },
  getters:{},
  actions:{}
})

2.2 组件使用pinia的state数据
<template>
	<div>
		<h1>A组件</h1>
		{{ name }}
	</div>
</template>

<script setup>
import { useStore } from '../store'
const store = useStore();
let { name } = store;
</script>
2.3 组件修改pinia的state数据
本身pinia可以直接修改state数据,无需像vuex一样通过mutations才可以修改,但是上面写的let { name } = store;这种解构是不可以的,所以要换解构的方式。
<template>
	<div>
		<h1>A组件</h1>
		{{ name }}
		<button @click='btn'>按钮</button>
	</div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import { useStore } from '../store'
const store = useStore();
let { name }  = storeToRefs(store);
const btn = ()=>{
	name.value = '123';
}
</script>
2.4 如果state数据需要批量更新
store/index.js
import { defineStore } from 'pinia'
export const useStore = defineStore('storeId', {
  state: () => {
    return {
      counter: 0,
      name: 'Eduardo',
      arr:['a','b','c']
    }
  },
  getters:{},
  actions:{}
})

组件代码
<template>
	<div>
		<h1>A组件</h1>
		{{ name }}
		{{ counter }}
		{{ arr }}
		<button @click='btn'>按钮</button>
	</div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import { useStore } from '../store'
const store = useStore();
let { name,counter,arr }  = storeToRefs(store);
const btn = ()=>{
	//批量更新
	store.$patch(state=>{
		state.counter++;
		state.arr.push(4);
		state.name = '456';
	})
}
</script>

三、actions

import { defineStore } from 'pinia'

export const useStore = defineStore('storeId', {
  state: () => {
    return {
      counter: 0
    }
  },
  getters:{},
  actions:{
  	changeCounter( val ){
  		this.counter += val;
  	}
  }
})
<template>
	<div>
		<h1>A组件</h1>
		{{ counter }}
		<button @click='add'>10</button>
	</div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import { useStore } from '../store'
const store = useStore();
let { counter }  = storeToRefs(store);
const add = ()=>{
	store.changeCounter(10);
}
</script>

四、getters

import { defineStore } from 'pinia'

export const useStore = defineStore('storeId', {
  state: () => {
    return {
      counter: 0,
    }
  },
  getters:{
  	counterPar(  ){
  		console.log(111);
  		return this.counter + 100;
  	}
  },
  actions:{}
})
<template>
	<div>
		{{ counterPar }}
		{{ counterPar }}
		{{ counterPar }}
		<h1>A组件</h1>
		{{ counter }}
	</div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import { useStore } from '../store'
const store = useStore();
let { counter, counterPar }  = storeToRefs(store);
</script>
<think>我们正在使用Pinia状态管理库。在Pinia中,store的actions部分是用来封装业务逻辑的地方。根据引用[2]和引用[5]的内容,我们可以知道在actions中如何访问state。 在Pinia中,定义store时,我们可以在actions函数内部通过`this`来访问整个store实例,进而访问state中定义的状态。 引用[2]中提供了一个例子: ```javascript import { defineStore } from 'pinia' import { Names } from './store-naspace' export const useTestStore = defineStore(Names.TEST, { state:()=>{ return { current:1, age:30 } }, actions:{ setCurrent () { this.current++ // 这里通过this访问state中的current } } }) ``` 在这个例子中,`setCurrent`这个action通过`this.current`访问到了state中的`current`属性,并对其进行了自增操作。 同样,引用[5]也提到,虽然可以直接修改state(如`store.baseUrl = ...`),但推荐将状态修改放在actions中统一管理。 因此,在Piniaactions中访问state,只需要使用`this.stateProperty`即可,其中`stateProperty`是你在state中定义的属性名。 ### 步骤总结: 1. 在store的state中定义状态。 2. 在actions中,通过`this`关键字来访问和修改这些状态。 ### 示例代码: ```javascript // 定义store import { defineStore } from 'pinia'; export const useCounterStore = defineStore('counter', { state: () => ({ count: 0, // 状态count message: 'Hello' }), actions: { increment() { // 通过this访问state中的count this.count++; }, updateMessage(newMessage) { // 访问并修改message this.message = newMessage; }, // 也可以同时访问多个状态 reset() { this.count = 0; this.message = 'Reset done'; } } }); ``` ### 在组件中使用: ```vue <script setup> import { useCounterStore } from './stores/counter'; const counterStore = useCounterStore(); // 调用actions const increment = () => { counterStore.increment(); }; </script> ``` ### 注意事项: - 在actions中,可以使用异步操作(如调用API),在异步操作中同样可以通过`this`来访问和修改state。 - 由于Pinia的store是响应式的,所以在actions中修改state后,依赖这些状态的组件会自动更新。 ### 引用说明: - 引用[2]展示了在actions中通过`this`访问state的示例。 - 引用[5]强调了虽然可以直接修改state,但推荐在actions中统一修改。 因此,在Piniaactions中访问state,直接使用`this`指向当前store实例,然后访问对应的状态属性即可。 §§相关问题§§ 1. 在Piniaactions中如何执行异步操作? 2. 如何在Piniaactions中调用另一个store的actions? 3. Piniagettersactions有什么区别? 4. 在组件中如何调用Pinia store的actions? 5. 如何测试Pinia store的actions?</think>在 Piniaactions 中访问 state非常简单直接,只需使用 `this` 关键字即可。以下是详细说明和示例: ### 访问 state 的两种方法 1. **直接通过 `this` 访问** 在 actions 内部,`this` 指向当前 store 实例,可以直接访问所有 state 属性: ```javascript actions: { increment() { // 直接通过 this 访问 state this.count++; console.log('当前:', this.count); } } ``` 2. **通过解构访问** 如果需要访问多个 state 属性,可以使用解构语法: ```javascript actions: { updateUser() { // 解构常用属性 const { username, email } = this; console.log(`更新用户: ${username} <${email}>`); } } ``` ### 完整示例 ```javascript import { defineStore } from 'pinia'; export const useUserStore = defineStore('user', { state: () => ({ id: 1, name: '张三', email: 'zhangsan@example.com', isAdmin: false }), actions: { // 1. 直接修改state promoteToAdmin() { this.isAdmin = true; console.log(`${this.name} 现在是管理员`); }, // 2. 使用state进行计算 getUserInfo() { return `${this.name} (ID: ${this.id}) - ${this.email}`; }, // 3. 异步操作中使用state async fetchUserDetails() { const userId = this.id; // 访问state const response = await fetch(`/api/users/${userId}`); const data = await response.json(); // 更新state this.name = data.name; this.email = data.email; }, // 4. 访问多个state属性 updateProfile(newName, newEmail) { const oldName = this.name; // 保存旧 this.name = newName; this.email = newEmail; console.log(`用户 ${oldName} 更新为 ${newName}`); } } }); ``` ### 在组件中使用 ```vue <script setup> import { useUserStore } from './stores/user'; const userStore = useUserStore(); // 调用action const updateUser = () => { userStore.updateProfile('李四', 'lisi@example.com'); }; </script> ``` ### 关键注意事项 1. **不要使用箭头函数** 箭头函数会改变 `this` 的指向,导致无法访问 state: ```javascript // ❌ 错误写法 (箭头函数) actions: { badAction: () => { console.log(this.name); // undefined! } } ``` 2. **修改数组/对象** 直接修改数组/对象元素会保持响应性: ```javascript actions: { addItem(item) { this.items.push(item); // 直接修改 ✅ } } ``` 3. **TypeScript 支持** 使用 TypeScript 时,可以定义 state 接口获得类型提示: ```typescript interface UserState { id: number; name: string; email: string; } export const useUserStore = defineStore('user', { state: (): UserState => ({ id: 1, name: '', email: '' }), actions: { // 获得完整的类型提示 setName(name: string) { this.name = name; } } }); ``` Pinia 的设计让在 actions 中访问 state 变得非常直观,通过 `this` 即可直接读写所有状态属性,同时保持响应式更新[^2][^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值