Vue2与Vue3中导入通用工具函数的使用方法对比
前言
在Vue项目开发中,合理使用工具函数是提高代码复用性和可维护性的重要手段。Vue2和Vue3在工具函数的使用方式上存在一些差异,本文将详细介绍两种版本中导入和使用通用工具函数的方法,并进行对比分析。
一、Vue2中工具函数的使用方法
1. 直接导入使用(推荐方式)
对于纯工具函数(不依赖Vue实例),最简单的使用方式就是直接导入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| export function formatDate(date) { return new Date(date).toLocaleDateString('zh-CN'); }
export function formatDateTime(date) { return new Date(date).toLocaleString('zh-CN'); }
export function capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); }
export function truncate(str, length = 50) { return str.length > length ? str.substring(0, length) + '...' : str; }
|
在Vue组件中使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <script> import { formatDate, capitalize } from '@/utils/date'; import { truncate } from '@/utils/string';
export default { data() { return { article: { title: 'vue2工具函数使用指南', content: '这是一篇关于Vue2中工具函数使用的详细指南...', createdAt: '2025-11-07T10:00:00' } }; }, computed: { formattedDate() { return formatDate(this.article.createdAt); }, formattedTitle() { return capitalize(this.article.title); }, truncatedContent() { return truncate(this.article.content, 30); } } }; </script>
<template> <div> <h2>{{ formattedTitle }}</h2> <p>发布时间:{{ formattedDate }}</p> <p>{{ truncatedContent }}</p> </div> </template>
|
2. 挂载到Vue原型上
对于频繁使用的工具函数,可以挂载到Vue原型上,使其在所有组件中可用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import Vue from 'vue'; import App from './App.vue'; import { formatDate, formatDateTime } from '@/utils/date'; import { capitalize, truncate } from '@/utils/string';
Vue.prototype.$formatDate = formatDate; Vue.prototype.$formatDateTime = formatDateTime; Vue.prototype.$capitalize = capitalize; Vue.prototype.$truncate = truncate;
new Vue({ render: h => h(App) }).$mount('#app');
|
在组件中使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| export default { data() { return { article: { title: 'vue2原型方法', createdAt: '2025-11-07T10:00:00' } }; }, computed: { formattedDate() { return this.$formatDate(this.article.createdAt); }, formattedTitle() { return this.$capitalize(this.article.title); } } };
|
3. 使用Vue插件
对于复杂的工具函数集合,可以封装成Vue插件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import { formatDate, formatDateTime } from '@/utils/date'; import { capitalize, truncate } from '@/utils/string'; import { debounce, throttle } from '@/utils/performance';
const UtilsPlugin = { install(Vue) { Vue.prototype.$utils = { formatDate, formatDateTime, capitalize, truncate, debounce, throttle }; Vue.prototype.$formatDate = formatDate; Vue.prototype.$debounce = debounce; } };
export default UtilsPlugin;
import Vue from 'vue'; import UtilsPlugin from '@/plugins/utils';
Vue.use(UtilsPlugin);
|
在组件中使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| export default { data() { return { searchText: '' }; }, methods: { handleSearch: this.$utils.debounce(function() { console.log('搜索:', this.searchText); }, 300), formatData() { const date = this.$utils.formatDate(new Date()); const title = this.$utils.capitalize('hello world'); return { date, title }; } } };
|
4. 使用Mixin
对于需要在多个组件中复用的工具函数逻辑,可以使用Mixin:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| export default { methods: { $formatCurrency(amount) { return '¥' + amount.toFixed(2); }, $validateEmail(email) { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return regex.test(email); }, $deepClone(obj) { return JSON.parse(JSON.stringify(obj)); } } };
import utilsMixin from '@/mixins/utils';
export default { mixins: [utilsMixin], methods: { processOrder(order) { const clonedOrder = this.$deepClone(order); clonedOrder.total = this.$formatCurrency(clonedOrder.amount); return clonedOrder; } } };
|
二、Vue3中工具函数的使用方法
1. Composition API方式(推荐)
Vue3的Composition API提供了更灵活的工具函数使用方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| import { ref, computed } from 'vue'; import { formatDate, formatDateTime } from '@/utils/date'; import { capitalize, truncate } from '@/utils/string';
export function useUtils() { const formatDate = (date) => { return new Date(date).toLocaleDateString('zh-CN'); }; const capitalize = (str) => { return str.charAt(0).toUpperCase() + str.slice(1); }; const truncate = (str, length = 50) => { return str.length > length ? str.substring(0, length) + '...' : str; }; return { formatDate, capitalize, truncate }; }
<script setup> import { ref } from 'vue'; import { useUtils } from '@/composables/useUtils';
const { formatDate, capitalize, truncate } = useUtils();
const article = ref({ title: 'vue3工具函数使用指南', content: '这是一篇关于Vue3中工具函数使用的详细指南...', createdAt: '2025-11-07T10:00:00' });
const formattedDate = computed(() => formatDate(article.value.createdAt)); const formattedTitle = computed(() => capitalize(article.value.title)); const truncatedContent = computed(() => truncate(article.value.content, 30)); </script>
<template> <div> <h2>{{ formattedTitle }}</h2> <p>发布时间:{{ formattedDate }}</p> <p>{{ truncatedContent }}</p> </div> </template>
|
2. 直接导入使用
与Vue2类似,可以直接导入工具函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| export function formatDate(date) { return new Date(date).toLocaleDateString('zh-CN'); }
<script setup> import { ref, computed } from 'vue'; import { formatDate } from '@/utils/date';
const article = ref({ createdAt: '2025-11-07T10:00:00' });
const formattedDate = computed(() => formatDate(article.value.createdAt)); </script>
|
3. 使用Provide/Inject
对于需要在多个组件间共享的工具函数,可以使用Provide/Inject:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <script setup> import { provide } from 'vue'; import { formatDate, formatDateTime } from '@/utils/date'; import { capitalize, truncate } from '@/utils/string';
provide('utils', { formatDate, formatDateTime, capitalize, truncate }); </script>
<script setup> import { inject, computed } from 'vue';
const utils = inject('utils'); const article = ref({ title: 'vue3 provide/inject', createdAt: '2025-11-07T10:00:00' });
const formattedDate = computed(() => utils.formatDate(article.value.createdAt)); </script>
|
4. 使用全局属性
Vue3中也可以配置全局属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import { createApp } from 'vue'; import App from './App.vue'; import { formatDate, capitalize } from '@/utils/date';
const app = createApp(App);
app.config.globalProperties.$formatDate = formatDate; app.config.globalProperties.$capitalize = capitalize;
app.mount('#app');
export default { computed: { formattedDate() { return this.$formatDate(this.article.createdAt); } } };
import { getCurrentInstance } from 'vue';
const instance = getCurrentInstance(); const formattedDate = instance.proxy.$formatDate(article.createdAt);
|
三、Vue2与Vue3对比分析
1. 导入方式对比
| 特性 |
Vue2 |
Vue3 |
| 直接导入 |
✅ 支持 |
✅ 支持 |
| 原型挂载 |
✅ Vue.prototype |
⚠️ app.config.globalProperties |
| 插件系统 |
✅ Vue.use() |
✅ app.use() |
| Mixin |
✅ 支持 |
⚠️ 兼容但推荐Composition API |
| Composition API |
❌ 不支持 |
✅ 推荐方式 |
| Provide/Inject |
✅ 支持 |
✅ 增强支持 |
2. 类型支持对比
Vue2类型支持有限:
1 2 3 4 5 6 7 8 9
| import Vue from 'vue';
declare module 'vue/types/vue' { interface Vue { $formatDate: (date: string) => string; $capitalize: (str: string) => string; } }
|
Vue3类型支持完善:
1 2 3 4 5 6 7 8 9 10 11 12
| import type { App } from 'vue';
declare module '@vue/runtime-core' { interface ComponentCustomProperties { $formatDate: (date: string) => string; } }
export function setupUtils(app: App) { app.config.globalProperties.$formatDate = formatDate; }
|
3. 性能与Tree Shaking
Vue2:
- 原型挂载的函数会被打包到所有组件中
- 无法进行有效的Tree Shaking
- 所有挂载的函数都会增加包体积
Vue3:
- Composition API支持更好的Tree Shaking
- 按需导入,未使用的函数会被摇树优化掉
- 更好的包体积控制
4. 代码组织对比
Vue2代码组织:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| export default { data() { return { }; }, computed: { formattedDate() { return this.$formatDate(this.date); } }, methods: { processData() { const formatted = this.$formatDate(this.date); } } };
|
Vue3代码组织:
1 2 3 4 5 6 7 8 9 10
| <script setup> import { useUtils } from '@/composables/useUtils'; import { useBusinessLogic } from '@/composables/useBusinessLogic';
const { formatDate, capitalize } = useUtils();
const { processData } = useBusinessLogic({ formatDate, capitalize }); </script>
|
四、最佳实践建议
1. Vue2最佳实践
- 简单工具函数:直接导入使用
- 频繁使用的函数:挂载到Vue原型
- 复杂工具集合:封装成Vue插件
- 类型安全:使用TypeScript声明类型
- 避免过度使用Mixin:可能导致命名冲突和难以维护
2. Vue3最佳实践
- 优先使用Composition API:更好的代码组织和Tree Shaking
- 创建自定义Composable:封装相关工具函数
- 按需导入:避免不必要的包体积增加
- 使用Provide/Inject:组件间共享工具函数
- 利用TypeScript:获得完整的类型支持
3. 迁移建议
从Vue2迁移到Vue3时:
- 逐步迁移:先迁移工具函数的使用方式
- 创建Composable:将Vue2中的工具逻辑重构为Composable
- 保持兼容:在迁移期间可以同时支持两种方式
- 性能优化:利用Vue3的Tree Shaking特性优化包体积
五、实际应用示例
1. 表单验证工具函数
Vue2实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| export function validateEmail(email) { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return regex.test(email); }
export function validatePhone(phone) { const regex = /^1[3-9]\d{9}$/; return regex.test(phone); }
Vue.prototype.$validate = { email: validateEmail, phone: validatePhone };
export default { methods: { submitForm() { if (!this.$validate.email(this.form.email)) { this.$message.error('邮箱格式错误'); return; } } } };
|
Vue3实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import { ref } from 'vue';
export function useValidation() { const validateEmail = (email) => { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return regex.test(email); }; const validatePhone = (phone) => { const regex = /^1[3-9]\d{9}$/; return regex.test(phone); }; return { validateEmail, validatePhone }; }
<script setup> import { useValidation } from '@/composables/useValidation';
const { validateEmail, validatePhone } = useValidation();
const submitForm = () => { if (!validateEmail(form.value.email)) { message.error('邮箱格式错误'); return; } }; </script>
|
六、总结
Vue2和Vue3在工具函数的使用上各有特点:
- Vue2 通过原型挂载和Mixin提供了便捷的全局访问方式,但类型支持和Tree Shaking有限
- Vue3 通过Composition API提供了更灵活、类型安全的工具函数使用方式,支持更好的性能优化
在实际开发中,应根据项目需求和技术栈选择合适的工具函数使用方式。对于新项目,推荐使用Vue3和Composition API;对于现有Vue2项目,可以根据实际情况逐步迁移或保持现有架构。