Vue2.7中如何优雅访问挂载在Vue实例上的自定义对象?
Vue2.7 访问全局挂载属性的正确方案
Options API 场景
使用传统选项式写法时,和Vue2旧版本行为完全一致,直接通过组件实例this访问即可,无需额外处理:
export default { methods: { async loadData() { // 直接访问,和Vue2.6及之前版本无差异 const data = await this.$http.get('/api/list') } } }
Composition API / <script setup> 场景
使用组合式API时,setup执行阶段没有绑定组件实例this,可以通过getCurrentInstance()拿到组件代理对象后直接访问,不需要手动遍历__proto__原型链:
注意:
getCurrentInstance()仅能在setup、生命周期钩子的同步执行上下文调用,不要在异步回调、普通工具函数中调用。
import { getCurrentInstance } from 'vue' // 仅在setup同步阶段调用 const { proxy } = getCurrentInstance() // 直接访问即可,proxy会自动沿原型链查找挂载的属性 const $http = proxy.$http // 业务调用 $http.post('/api/submit', { name: 'test' })
你之前需要多层访问__proto__属于hack写法,本质是误操作拿到了未经过代理的内部实例对象。__proto__属于JS引擎的内部实现细节,Vue组件实例的原型链结构可能在小版本迭代中调整,这类写法非常容易在版本更新后失效,不要在生产环境使用。
更规范的全局属性挂载方式(兼容Vue3升级)
Vue2.7已经移植了Vue3的全局属性配置能力,不需要直接修改Vue.prototype,后续升级Vue3时这部分代码不需要改动:
// 项目入口文件 main.js import Vue from 'vue' import App from './App.vue' import http from './utils/request' // 创建根实例 const app = new Vue(App) // 挂载全局属性,替代 Vue.prototype.$http = http app.config.globalProperties.$http = http // 挂载 app.$mount('#app')
这种方式挂载的属性,在选项式、组合式场景下都可以通过前面说的方式正常访问,行为和直接修改原型完全一致。
TS类型补充(可选)
如果项目使用TypeScript,可以在全局类型声明文件中补充属性类型,获得完整的类型提示:
// src/shims-vue.d.ts import type { AxiosInstance } from 'axios' // 按你自己的http实例类型替换 declare module 'vue' { interface ComponentCustomProperties { $http: AxiosInstance } }
内容的提问来源于stack exchange,提问作者kaiwen xiao
相关产品推荐
相关产品推荐

