使用Axios Get方法向Pinia存储变量存数据时this未定义问题
问题:Pinia中使用Axios获取数据并存入store时出现
this未定义错误 使用的依赖版本
- "pinia": "^2.1.3"
- "vue": "^3.2.25"
- "vue-router": "^4.0.16"
- "axios": "^1.4.0"
- "vite": "^2.9.5"
原代码
TheItems.vue
<template> <div> Items: {{storeItems.items}} </div> </template> <script setup> import { useItemsStore } from '../stores/itemsStore'; const storeItems = useItemsStore(); storeItems.getItemsList_API(); </script>
ItemsStore.js
import { defineStore } from 'pinia' import axios from 'axios'; export const useItemsStore = defineStore('itemsStore', { state: () => ({ items: [], }), actions: { async getItemsList_API() { await axios.get('http://127.0.0.1:5000/api/items') .then(function (response) { response.data.items.forEach(element => { this.items.push(element); }); console.log(response.data.items); }); }, }, });
错误原因
你在Axios的then回调里用了普通函数,普通函数的this指向的是Axios回调的上下文,而非Pinia的store实例,所以会出现this未定义的错误。另外你已经用async标记了函数,没必要混用async/await和.then(),这种写法既不规范也容易引发上下文问题。
修正方案
方案1:用箭头函数绑定上下文
箭头函数不会改变this指向,它会继承外层函数的this(也就是Pinia store实例):
import { defineStore } from 'pinia' import axios from 'axios'; export const useItemsStore = defineStore('itemsStore', { state: () => ({ items: [], }), actions: { async getItemsList_API() { await axios.get('http://127.0.0.1:5000/api/items') .then((response) => { // 改成箭头函数 response.data.items.forEach(element => { this.items.push(element); }); console.log(response.data.items); }); }, }, });
方案2:纯async/await写法(推荐)
既然已经用了async,直接用await接收响应,代码更清晰,也不会有this指向问题:
import { defineStore } from 'pinia' import axios from 'axios'; export const useItemsStore = defineStore('itemsStore', { state: () => ({ items: [], }), actions: { async getItemsList_API() { try { const response = await axios.get('http://127.0.0.1:5000/api/items'); // 直接替换数组比逐个push更高效,需要追加就用this.items.push(...response.data.items) this.items = [...response.data.items]; console.log(response.data.items); } catch (error) { // 别忘了捕获请求错误 console.error('获取数据失败:', error); } }, }, });
额外优化:组件中规范调用时机
建议在onMounted钩子中调用接口,而非直接在<script setup>顶层执行,避免组件初始化时不必要的请求触发:
<template> <div> Items: {{storeItems.items}} </div> </template> <script setup> import { useItemsStore } from '../stores/itemsStore'; import { onMounted } from 'vue'; const storeItems = useItemsStore(); onMounted(() => { storeItems.getItemsList_API(); }); </script>
内容的提问来源于stack exchange,提问作者dkgcb
相关产品推荐
相关产品推荐

