当前位置: 首页 > news >正文

<script setup> 实战模式:大型组件怎么拆?

用 Vue3 <script setup> 写小组件很爽,但遇到大型页面时,逻辑堆在一起就像面条。今天我们从“订单详情页”这个复杂组件入手,讲清楚 <script setup> 的最佳实践:逻辑分层、组合式函数拆分、Prop/Emit 类型定义、与普通 <script> 共存,让你写大组件也井井有条。

🎯 订单详情页需求

  • 渲染订单基础信息、商品列表、物流时间线。
  • 支持操作:修改状态、退款、打印。
  • 需要权限控制 + 国际化。

🧱 目录规划

OrderDetail.vue
composables/useOrderInfo.tsuseOrderActions.tsuseOrderPermission.ts
  • 把逻辑拆到同文件夹下的组合式函数。
  • 组件负责布局 + 调用组合函数。

✍️ OrderDetail.vue 结构

<script setup lang="ts">
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import OrderBase from './components/OrderBase.vue';
import OrderItems from './components/OrderItems.vue';
import OrderTimeline from './components/OrderTimeline.vue';
import { useOrderInfo } from './composables/useOrderInfo';
import { useOrderActions } from './composables/useOrderActions';
import { useOrderPermission } from './composables/useOrderPermission';const { t } = useI18n();
const route = useRoute();
const orderId = computed(() => route.params.id as string);const { loading, order, reload } = useOrderInfo(orderId);
const { canEdit, canRefund } = useOrderPermission(order);
const { updateStatus, refund, print } = useOrderActions(order, reload);
</script>
  • <script setup> 直接写逻辑,无需 defineComponent
  • 组合式函数返回的数据直接解构。
  • 所有业务逻辑都在 composable 中实现。

🧩 组合式函数示例

// useOrderInfo.ts
import { computed, ref, watch } from 'vue';
import { getOrderDetail } from '@/api/order';export function useOrderInfo(orderId: Ref<string>) {const loading = ref(false);const order = ref<Order | null>(null);const fetchOrder = async () => {if (!orderId.value) return;loading.value = true;try {order.value = await getOrderDetail(orderId.value);} finally {loading.value = false;}};watch(orderId, fetchOrder, { immediate: true });const totalAmount = computed(() =>order.value?.items.reduce((sum, item) => sum + item.price * item.qty, 0) || 0);return { loading, order, totalAmount, reload: fetchOrder };
}
  • 组合式函数以 use 开头。
  • 暴露响应式数据 + 方法。
  • 方便在其他组件复用。

🧠 Props、Emits 类型定义

<script setup lang="ts">
interface Props {orderId: string;
}const props = defineProps<Props>();
const emit = defineEmits<{(e: 'refresh'): void;
}>();const handleSuccess = () => emit('refresh');
</script>
  • definePropsdefineEmits<script setup> 中直接调用。
  • TypeScript 自动推断模板里的类型。

🔁 与普通 <script> 共存

<script lang="ts">
export default {inheritAttrs: false,
};
</script><script setup lang="ts">
// ...这里写 setup 逻辑
</script>
  • 当需要 inheritAttrscomponentsdirective 等选项时,可以保留普通 <script>
  • <script setup> 会在选项式 API 之后执行。

🧯 调试技巧

  • defineExpose:暴露内部方法给父组件。
    defineExpose({ reload });
    
  • onMounted, onUnmounted 与原生生命周期一致。
  • 使用 ESLint 插件 eslint-plugin-vue 保持编码规范。

⚠️ 常见坑

现象解决
<script setup> 中使用 thisundefined不存在 this,使用组合式变量
逻辑堆积混乱文件过大拆到 composables 子目录
defineProps 重复执行在顶层直接使用只能在 <script setup> 顶层调用
类型推断失败未开启 Volar + TS 支持确保 vue-tsc 生效

🏁 小练习

  1. 把你项目中 200 行以上的组件拆分成 <script setup> + composables。
  2. 尝试写一个 useTable 组合式函数,封装分页、排序逻辑。
http://www.dtcms.com/a/618235.html

相关文章:

  • 关键词解释:迁移学习(Transfer Learning)
  • 网站建设方案书简单wordpress主页加音乐
  • 这样做网站标志设计公司有哪些
  • 【MacBook】自动隐藏和显示菜单栏
  • 在Mysql环境下对数据进行增删改查
  • C#类修饰符功能与范围详解
  • 一个网站怎么留住用户做的比较好的国外网站一级页面布局分析
  • 可信网站是否必须做南阳网站备案
  • 【Linux驱动开发】Linux 设备驱动中的阻塞与非阻塞 I/O:机制、源码与示例
  • HarmonyOS新闻卡片组件开发实战:自定义组件与List渲染深度解析
  • 解决:jenkins Exception java.lang.NoSuchFieldError: SNAKE_CASE
  • 如何实现Redis安装与使用的详细教程
  • tensorflow+yolo图片训练和图片识别系统
  • 唯品会 一家专门做特卖的网站现在前端开发用什么技术
  • 图神经网络分享系列-GraphSage(Inductive Representation Learning on Large Graphs) (一)
  • leetcode对称二叉树
  • 网站开发设计心得及体会河南建设工程造价管理协会网站
  • 深度学习实战:(2)用 TensorFlow 1.x 构建手语识别模型
  • 人工智能、机器学习、深度学习:技术革命的深度解析
  • 东营seo网站建设费用广告设计专业自我介绍
  • 【Linux】进程状态、进程优先级、进程切换和调度
  • 【Android】View 的工作原理
  • 行人跌倒智能检测系统:YOLOv8/V5/V6/V7 多模型 + PySide6 界面 深度学习 多场景适配 大数据 (建议收藏)✅
  • 山东网络推广图片福州seo网站管理
  • C#中Task的详细用法
  • 自己怎么做企业网站建设免费代理服务器ip地址
  • 前端 css selector 的层叠 优先级与继承
  • 基于python二手房数据分析系统 可视化 Scrapy 爬虫 链家二手房数据 Django框架 基于用户的协同过滤推荐 二手房推荐系统 (源码)✅
  • Rust 内部可变性的访问器模式
  • ThinkPHP8学习篇(十二):模型关联(二)