Vue模板不承载逻辑,需将内联表达式等抽离为Composition API组合函数,确保可复用、可测试、强类型;典型场景包括格式化、权限判断、状态派生和副作用管理。

Vue 组件模板本身不直接承载逻辑,所谓“模板中的逻辑提取与复用”,实际是指将原本写在模板内联表达式、v-if/v-for 条件、计算属性或事件处理中耦合的业务逻辑,抽离到 Composition API 的组合式函数(Composable)中,再通过 setup 或 `<script setup>` 引入使用。核心不是动模板,而是让模板更干净、更声明式。</script>
为什么不能在模板里“复用逻辑”
Vue 模板语法(如 {{ formatPrice(price) }} 或 v-if="user.role === 'admin' && !isExpired()")本质是视图层表达式,不具备封装能力:
- 无法被其他组件调用
- 无法单独测试
- 多处重复时修改成本高
- TypeScript 类型推导弱,易出错
所以真正可复用的逻辑必须离开模板,进入 JavaScript 层。
提取逻辑的典型场景与做法
常见需提取的逻辑包括格式化、权限判断、状态派生、副作用管理等:
-
格式化类逻辑:如日期、金额、单位转换——定义无状态组合函数
useDateFormat()或useCurrency(),接收原始值返回处理后字符串 -
权限与状态判断:如
canEdit(item)或isDraftVisible()——封装成带业务规则的函数,避免模板中散落 if 判断 -
响应式状态派生:如“筛选后待办数量”“未读消息高亮”——用
computed+ref在组合函数中统一管理,模板只读取最终响应式变量 -
带副作用的交互逻辑:如鼠标跟踪、滚动监听、防抖搜索——按规范用
onMounted/onUnmounted注册清理,返回{ x, y, isActive }等明确字段供模板绑定
如何保证提取后的逻辑真正可复用
关键不在“能用”,而在“好用、安全、易维护”:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- 函数名以
use开头(如useTodoFilter),符合 Vue 社区约定,便于识别和 IDE 支持 - 只返回响应式引用(
ref/computed)或纯函数,不直接操作 DOM 或全局状态 - 输入参数明确、最小化,避免隐式依赖 props 或上下文;必要时通过参数传入依赖项
- 内部生命周期钩子(如
onMounted)自动绑定当前组件作用域,卸载时自动清理,防止内存泄漏 - 配合 TypeScript 定义清晰的输入输出类型,比如
usePagination<t>(list: Ref<t>)</t></t>
模板里怎么配合使用
提取后,模板反而更简洁直观:
立即学习“前端免费学习笔记(深入)”;
✅ 好的做法:
<template>
<p>当前时间:{{ formattedTime }}</p>
<button :disabled="!canSubmit" @click="handleSubmit">提交</button>
</template>
<script setup>
import { useTimeFormat, useSubmitGuard } from '@/composables'
const { formattedTime } = useTimeFormat()
const { canSubmit, handleSubmit } = useSubmitGuard()
</script>
❌ 避免回退:
<p>{{ new Date().toLocaleString() }}</p>
<button :disabled="!form.valid || isSubmitting">提交</button>(逻辑又回到了模板)

















