vue2和vue3挂载全局的方法

在Vue中,挂载全局方法通常是为了在整个应用中的任何组件都可以使用这些方法。Vue2和Vue3在挂载全局方法上有所不同,主要因为Vue3引入了新的应用实例概念。

在Vue2中,我们通常通过修改Vue的原型(prototype)来实现全局方法的挂载。这样在每个Vue组件实例中都可以通过`this`来访问这些方法。

在Vue3中,我们不再使用`Vue.prototype`,而是通过app实例的`config.globalProperties`来添加全局方法。另外,Vue3推荐使用provide/inject来实现全局状态或方法,但对于方法,使用`globalProperties`更为直接。

Vue 2 挂载全局方法(3种方式)
1. 通过 Vue.prototype 挂载 (最常用)
// main.js
import Vue from 'vue'

// 定义全局方法
const globalMethod = {
  showToast(message) {
    console.log(`Toast: ${message}`)
    // 实际项目中这里实现toast逻辑
  },
  formatCurrency(value) {
    return `¥${parseFloat(value).toFixed(2)}`
  }
}

// 挂载到Vue原型
Vue.prototype.$utils = globalMethod

// 使用示例(在组件中)
export default {
  mounted() {
    this.$utils.showToast('操作成功!') // Toast: 操作成功!
    const price = this.$utils.formatCurrency(99.8) // ¥99.80
  }
}
2. 使用 Mixin 全局混入
// main.js
import Vue from 'vue'

Vue.mixin({
  methods: {
    $logInfo(message) {
      console.log(`[INFO] ${new Date().toISOString()}: ${message}`)
    },
    $copyText(text) {
      navigator.clipboard.writeText(text)
    }
  }
})

// 组件中使用
this.$logInfo('页面加载完成') // [INFO] 2023-08-01T10:00:00.000Z: 页面加载完成
this.$copyText('复制内容')
 3. 作为插件安装
// utilsPlugin.js
export default {
  install(Vue) {
    Vue.prototype.$api = {
      fetchData(url) {
        return fetch(url).then(res => res.json())
      },
      debounce(fn, delay = 300) {
        let timer = null
        return (...args) => {
          clearTimeout(timer)
          timer = setTimeout(() => fn.apply(this, args), delay)
        }
      }
    }
  }
}

// main.js
import Vue from 'vue'
import utilsPlugin from './plugins/utilsPlugin'

Vue.use(utilsPlugin)

// 组件中使用
this.$api.fetchData('/api/data').then(data => { /*...*/ })
const debouncedSearch = this.$api.debounce(this.handleSearch, 500)

Vue 3 挂载全局方法(Composition API)

1. 通过 app.config.globalProperties 挂载 (推荐)
// main.js
import { createApp } from 'vue'

const app = createApp(App)

// 定义全局方法
const globalMethods = {
  $showLoading() {
    // 显示加载动画
  },
  $hideLoading() {
    // 隐藏加载动画
  },
  $formatDate(date, format = 'YYYY-MM-DD') {
    return dayjs(date).format(format)
  }
}

// 挂载全局属性
app.config.globalProperties.$utils = globalMethods

app.mount('#app')

// 组件中使用(Options API)
export default {
  mounted() {
    this.$utils.$showLoading()
    const date = this.$utils.$formatDate(new Date())
  }
}

// 组合式API中使用
import { getCurrentInstance } from 'vue'

export default {
  setup() {
    const { proxy } = getCurrentInstance()
    
    const handleSubmit = () => {
      proxy.$utils.$showLoading()
      // ...
      proxy.$utils.$hideLoading()
    }
    
    return { handleSubmit }
  }
}
2. 使用 provide/inject (更适合全局工具)
// main.js
import { createApp } from 'vue'

const app = createApp(App)

// 创建工具集
const globalUtils = {
  trackEvent(eventName) {
    // 埋点统计
  },
  deepClone(obj) {
    return JSON.parse(JSON.stringify(obj))
  }
}

// 提供全局工具
app.provide('globalUtils', globalUtils)

// 组件中使用
import { inject } from 'vue'

export default {
  setup() {
    const utils = inject('globalUtils')
    
    const handleClick = () => {
      utils.trackEvent('button_click')
      const clonedObj = utils.deepClone(originalObj)
    }
    
    return { handleClick }
  }
}
3. 作为插件安装 (最佳实践)
// globalUtils.js
export default {
  install(app) {
    // 挂载全局方法
    app.config.globalProperties.$alert = (message) => {
      // 实现alert逻辑
    }
    
    // 注册全局组件
    app.component('GlobalSpinner', SpinnerComponent)
    
    // 提供响应式工具
    const utils = reactive({
      screenSize: { width: window.innerWidth, height: window.innerHeight },
      isMobile: window.innerWidth < 768
    })
    
    // 监听窗口变化
    window.addEventListener('resize', () => {
      utils.screenSize = { 
        width: window.innerWidth, 
        height: window.innerHeight 
      }
      utils.isMobile = window.innerWidth < 768
    })
    
    app.provide('responsiveUtils', utils)
  }
}

// main.js
import { createApp } from 'vue'
import globalUtils from './plugins/globalUtils'

createApp(App)
  .use(globalUtils)
  .mount('#app')

// 组件中使用
export default {
  mounted() {
    this.$alert('操作成功!') // 全局方法
  },
  
  setup() {
    const { isMobile } = inject('responsiveUtils')
    return { isMobile }
  }
}

关键区别总结

特性Vue 2Vue 3
主要挂载方式Vue.prototypeapp.config.globalProperties
插件安装Vue.use(plugin)app.use(plugin)
Composition API不支持getCurrentInstance().proxy 或 inject
类型支持有限完善的TypeScript支持
全局状态管理需配合Vuex可通过provide/inject实现
响应式工具需手动实现可集成reactive/ref响应式系统

注意:在Vue3的组合式API中,由于`setup`函数中无法直接访问`this`,因此需要通过`getCurrentInstance`来获取代理对象。但是,官方文档指出,`getCurrentInstance`主要作为内部使用,在库中谨慎使用。因此,在组合式API中,更推荐使用模块导入的方式或者使用provide/inject来传递方法。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值