在 Uniapp 项目开发中,我们经常会遇到一些需要在多个页面或组件中重复使用的函数或工具类。如果没有统一的管理方式,就会导致代码冗余,维护困难。Uniapp 如何自定义全局方法,并优雅地解决这个问题,是本文要探讨的核心。
场景重现:重复代码的困境
想象一下,你在多个页面都需要进行日期格式化、金额转换、用户登录状态校验等操作。如果每个页面都编写相同的代码,不仅效率低下,而且一旦业务逻辑发生变化,你需要修改所有涉及到的文件,简直是噩梦。使用全局方法,就能避免这种重复劳动。
底层原理:mixin、Vue.prototype 和 provide/inject
Uniapp 本质上还是 Vue.js 的一个框架,所以我们可以借助 Vue.js 的机制来实现全局方法的自定义。常用的方法有以下几种:
- Mixin: 将公共的逻辑混入到组件中。虽然可以实现代码复用,但容易产生命名冲突,不推荐作为主要方案。
- Vue.prototype: 这是最直接的方法,将方法添加到 Vue 的原型上,所有组件都可以访问。
- provide/inject: 允许祖先组件向其所有后代组件注入依赖,但使用起来相对复杂,适用于更高级的场景。
解决方案:Vue.prototype 的简单实现
这里我们选择最常用的 Vue.prototype 方式,因为它简单易懂,上手快。步骤如下:
创建全局方法文件:

在项目的
common目录下(或其他你喜欢的目录),创建一个global.js文件,用于存放全局方法。// common/global.js const globalMethods = { formatDate(date, fmt) { // 日期格式化 let o = { 'M+': date.getMonth() + 1, //月份 'd+': date.getDate(), //日 'h+': date.getHours(), //小时 'm+': date.getMinutes(), //分 's+': date.getSeconds(), //秒 'q+': Math.floor((date.getMonth() + 3) / 3), //季度 'S': date.getMilliseconds() //毫秒 }; if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); } for (let k in o) { if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))); } } return fmt; }, formatMoney(amount) { // 金额格式化 return '¥' + parseFloat(amount).toFixed(2); }, checkLoginStatus() { // 检查登录状态 // 这里可以读取本地存储的 token 或用户信息 const token = uni.getStorageSync('token'); return !!token; } }; export default globalMethods;在 main.js 中引入并挂载到 Vue.prototype:

// main.js import Vue from 'vue' import App from './App' import globalMethods from './common/global.js' Vue.config.productionTip = false Vue.prototype.$global = globalMethods; // 挂载到 Vue.prototype App.mpType = 'app' const app = new Vue({ ...App }) app.$mount()在组件中使用:
现在,你可以在任何组件中通过
this.$global.方法名()来调用全局方法了。
<template> <view> <text>当前日期:{{ formattedDate }}</text> <text>商品价格:{{ formattedMoney }}</text> <button @click="checkLogin">检查登录状态</button> </view> </template> <script> export default { data() { return { date: new Date(), price: 199.99 } }, computed: { formattedDate() { return this.$global.formatDate(this.date, 'yyyy-MM-dd hh:mm:ss'); }, formattedMoney() { return this.$global.formatMoney(this.price); } }, methods: { checkLogin() { if (this.$global.checkLoginStatus()) { uni.showToast({ title: '已登录', icon: 'success' }); } else { uni.navigateTo({ url: '/pages/login/login' }); } } } } </script>
实战避坑经验总结
- 命名冲突: 尽量给全局方法添加命名空间,例如
this.$global.xxx,避免与组件内部的方法或 Vue 自身的方法冲突。 - this 指向: 在全局方法中,
this指向的是 Vue 实例,所以可以访问 Vue 实例上的数据和方法。 - 调试: 如果全局方法不起作用,检查是否正确引入并挂载到
Vue.prototype上,并检查方法名是否拼写正确。 - 性能: 不要滥用全局方法,只将真正需要在多个地方使用的逻辑提取出来。
- 与 Vuex 的结合: 对于需要在多个组件中共享的状态,建议使用 Vuex 进行管理,而不是通过全局方法。
- 关于 Nginx 和服务器配置: 当项目部署到服务器,例如使用宝塔面板配置 Nginx 反向代理时,务必确保服务器的并发连接数足够大,否则可能会因为请求过多导致服务崩溃。同时,合理配置 Nginx 的负载均衡策略,可以提高系统的稳定性和性能。
通过以上方法,你可以轻松地在 Uniapp 项目中自定义全局方法,提高代码复用率,降低维护成本。当然,选择哪种方式取决于你的具体需求和项目规模。希望这篇文章能帮助你更好地理解和应用 Uniapp 全局方法自定义技巧。
冠军资讯
键盘上的咸鱼