在vuejs 中使用axios不能获取属性data的解决方法

本文探讨了在Vue应用中使用Axios发送HTTP请求时遇到的问题,特别是关于如何正确处理回调函数内的this上下文,以避免常见的错误。提供了两种解决方案:使用变量self保存this引用或采用ES6箭头函数。

axios请求数据:

 // mounted 方法为钩子,在Vue实例化后自动调用
    mounted() {
       axios.post('/api/question/follower', {
           'question':this.question,
           'user':this.user
       }).then(function(response){
           // console.log(response.data);
           this.followed = response.data.followed;
       })
    },

出错问题:
then 这个里边的赋值方法this.followed = response.data.followed会出现报错,什么原因呢?在Google上查了下,原来是在 then的内部不能使用Vue的实例化的this, 因为在内部 this 没有被绑定。
可以看下 Stackoverflow 的解释:

In option functions like data and created, vue binds this to the view-model instance for us,
so we can use this.followed, but in the function inside then, this is not bound.

解决方法:

 created() {
       var self = this;
       axios.post('/api/question/follower', {
           'question':this.question,
           'user':this.user
       }).then(function(response){
           // console.log(response.data);
           self.followed = response.data.followed;
       })
    },

或者我们可以使用 ES6 的 箭头函数arrow function,箭头方法可以和父方法共享变量 :


   
 created() {
       axios.post('/api/question/follower', {
           'question':this.question,
           'user':this.user
       }).then((response) => {
           this.followed = response.data.followed;
       })
    },

完整代码:

<script>
export default {
    // 为父组件传递到子组件的属性值,子组件使用props方法接收
    props:['question', 'user'],
    // mounted 方法为钩子,在Vue实例化后自动调用
    mounted() {
       
       axios.post('/api/question/follower', {
           'question':this.question,
           'user':this.user
       }).then(function(response){
           // console.log(response.data);
           this.followed = response.data.followed;
       })
    },
    data(){
        return {
            followed : false,
        }
    },
    computed:{
        text(){
           return this.followed ? '已关注' : '关注该问题';
        }
    },
    methods:{
        // 关注动作
        follow(){
            axios.post('/api/question/follow', {
                'question':this.question,
                'user':this.user
            }).then(function(response){
                this.followed = response.data.followed;
            })
        }
    }
}
</script>

参考文章:
Stackoverflow:Axios can't set data

 

<think> 我们正在解决在Vue中使用`Vue.prototype.$axios`访问不到的问题。根据引用[2]和[4],在Vue3中,由于架构变化,不再使用`Vue.prototype`,而是使用`app.config.globalProperties`。此外,引用[5]提到,在Vue2中,需要正确安装并挂载axios。 因此,我们需要根据Vue的版本(Vue2或Vue3)采取不同的解决方案。 ### 解决方案 #### 1. **Vue2中的解决方案** 在Vue2中,使用`Vue.prototype`是标准的全局属性挂载方式。 **步骤:** 1. 确保已安装axios: ```bash npm install axios --save ``` 2. 在入口文件(通常是`main.js`)中导入并挂载axios: ```javascript import Vue from 'vue'; import axios from 'axios'; // 设置axios的baseURL(可选) axios.defaults.baseURL = process.env.VUE_APP_API_URL; // 挂载到Vue原型 Vue.prototype.$axios = axios; ``` 3. 在组件中使用: ```javascript export default { methods: { fetchData() { this.$axios.get('/some-endpoint') .then(response => { // 处理响应 }) .catch(error => { // 处理错误 }); } } }; ``` **注意:** - 如果在组件中遇到`this.$axios is not a function`错误(如引用[1]所述),请检查是否在`main.js`中正确挂载了`Vue.prototype.$axios`。 - 引用[5]提到,也可以使用`Vue.use`配合`vue-axios`插件,但上述方式更常见。 #### 2. **Vue3中的解决方案** 在Vue3中,由于使用了新的应用实例API,不再有`Vue.prototype`,而是通过`app.config.globalProperties`挂载全局属性(引用[4])。 **步骤:** 1. 确保已安装axios: ```bash npm install axios --save ``` 2. 在入口文件(通常是`main.js`或`main.ts`)中: ```javascript import { createApp } from 'vue'; import App from './App.vue'; import axios from 'axios'; const app = createApp(App); // 设置axios的baseURL(可选) axios.defaults.baseURL = import.meta.env.VITE_APP_API_URL; // 注意:Vue3项目环境变量可能使用Vite,前缀为VITE_ // 挂载axios到全局属性 app.config.globalProperties.$axios = axios; app.mount('#app'); ``` 3. 在组件中使用(注意:在setup语法中不能直接使用this): - **选项式API**:可以在方法中通过`this.$axios`访问。 ```javascript export default { methods: { async fetchData() { try { const response = await this.$axios.get('/some-endpoint'); // 处理响应 } catch (error) { // 处理错误 } } } }; ``` - **组合式API**:在`setup`函数中无法访问`this`,因此不能直接使用`this.$axios`。有以下两种替代方案: - **方案1**:直接导入axios实例(推荐)。 ```javascript import axios from 'axios'; // 直接导入 export default { setup() { const fetchData = async () => { try { const response = await axios.get('/some-endpoint'); // 处理响应 } catch (error) { // 处理错误 } }; return { fetchData }; } }; ``` - **方案2**:通过`getCurrentInstance`获取全局属性(不推荐,因为官方文档指出内部实例是内部组件,不建议直接使用)。 ```javascript import { getCurrentInstance } from 'vue'; export default { setup() { const internalInstance = getCurrentInstance(); const axios = internalInstance?.appContext.config.globalProperties.$axios; const fetchData = async () => { try { const response = await axios.get('/some-endpoint'); // 处理响应 } catch (error) { // 处理错误 } }; return { fetchData }; } }; ``` ### 常见问题排查 1. **未正确挂载**:确保挂载代码在Vue实例创建(`app.mount()`)之前执行。 2. **环境变量问题**:如果使用`process.env.VUE_APP_API_URL`(Vue2)或`import.meta.env.VITE_APP_API_URL`(Vue3+Vite),确保在对应的环境文件(如`.env.development`)中已设置。 3. **版本不匹配**:Vue3项目中使用`Vue.prototype`会导致引用[2]和[4]中的错误,请改用`app.config.globalProperties`。 ### 总结 - **Vue2**:使用`Vue.prototype.$axios = axios`在入口文件中挂载。 - **Vue3**:使用`app.config.globalProperties.$axios = axios`挂载,但在组合式API中建议直接导入axios实例。 以上步骤应能解决访问不到`$axios`的问题。 [^6]: [Vue3添加全局属性](https://v3.vuejs.org/guide/migration/global-api.html#vue-prototype-replaced-by-config-globalproperties) §§相关问题§§ 1. 在Vue3的组合式API中,除了直接导入axios,还有哪些方式可以在组件中发起HTTP请求? 2. 如何在Vue项目中统一管理axios的请求拦截器和响应拦截器? 3. 如何在Vue项目中对axios进行封装,以便于API的统一管理? </think> ### Vue中使用`Vue.prototype.$axios`访问不到的解决方案 #### 1. **检查Vue版本** - **Vue2**:支持`Vue.prototype`方式 在入口文件(如`main.js`)添加: ```javascript import Vue from 'vue' import axios from 'axios' // 正确挂载方式 axios.defaults.baseURL = process.env.VUE_APP_API_URL; Vue.prototype.$axios = axios; // 关键步骤 ``` - **Vue3**:不再支持`Vue.prototype`(引用[4]) 改为: ```javascript import { createApp } from 'vue' import axios from 'axios' const app = createApp(App) app.config.globalProperties.$axios = axios; // Vue3专用方式 ``` #### 2. **安装和引入检查** - 确保已安装axios: ```bash npm install axios --save # 或 yarn add axios ``` - 检查入口文件是否漏掉关键步骤: ```javascript // 必须同时包含以下两行(Vue2示例) import axios from 'axios'; // 引入库 Vue.prototype.$axios = axios; // 挂载到原型 ``` #### 3. **组件内使用方法** - **选项式API**(直接使用`this`): ```javascript methods: { async fetchData() { try { const res = await this.$axios.get('/api/data'); // 通过this访问 console.log(res.data); } catch (err) { console.error(err); } } } ``` - **组合式API**(需通过`getCurrentInstance`): ```javascript import { getCurrentInstance } from 'vue'; export default { setup() { const { proxy } = getCurrentInstance(); // 获取实例代理 const fetchData = async () => { const res = await proxy.$axios.get('/api/data'); // 通过proxy访问 }; return { fetchData }; } } ``` #### 4. **常见错误排查** | 错误现象 | 原因 | 解决方案 | |---------|------|---------| | `this.$axios is not a function` | 未正确挂载到原型 | 检查`main.js`挂载代码(引用[1][3]) | | `Cannot set properties of undefined` | Vue3中使用Vue2语法 | 改用`app.config.globalProperties`(引用[2][4]) | | 跨域问题(CORS) | 后端未配置CORS | 配置后端或使用代理(详见下方说明) | #### 5. **替代方案(推荐)** 避免原型污染,创建axios实例: ```javascript // utils/http.js import axios from 'axios'; const instance = axios.create({ baseURL: process.env.VUE_APP_API_URL }); export default instance; // 组件中使用 import http from '@/utils/http'; http.get('/api/data'); ``` #### 6. **环境变量配置** 确保`.env`文件已设置: ```bash # .env.development VUE_APP_API_URL = http://localhost:3000/api ``` > 关键要点: > - Vue2用`Vue.prototype.$axios`,Vue3用`app.config.globalProperties.$axios` > - 组合式API需通过`getCurrentInstance().proxy`访问 > - 优先推荐独立axios实例(避免原型链污染) [^1]: [原型挂载缺失导致未定义函数](引用1) [^2]: [Vue3中不能设置undefined属性](引用2) [^4]: [Vue3改用globalProperties](引用4) [^5]: [完整安装和挂载步骤](引用5) --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值