前端工程化 - 非feature-based- 示例

非feature-based- 示例

错误的目录结构

这是大量前端后台项目的默认写法

src/
├── api/
│   ├── user.ts
│   ├── order.ts
│   └── product.ts
│
├── views/
│   ├── UserList.vue
│   ├── UserDetail.vue
│   ├── OrderList.vue
│   └── ProductList.vue
│
├── components/
│   ├── UserTable.vue
│   ├── UserForm.vue
│   ├── OrderTable.vue
│   └── ProductCard.vue
│
├── store/
│   ├── user.ts
│   ├── order.ts
│   └── product.ts
│
├── hooks/
│   ├── useUser.ts
│   ├── useOrder.ts
│   └── useProduct.ts
│
└── router/
    └── index.ts

看起来:

  • 分层清楚
  • components / hooks / api
  • 很规范

但这是一个典型的 “坏边界” 的结构

Page代码

<template>
  <div class="order-page">
    <OrderFilter
      :filters="filters"
      @change="onFilterChange"
    />

    <OrderActions
      :selected-orders="selectedOrders"
      :permission="permission"
      @export="handleExport"
      @change-status="handleChangeStatus"
    />

    <OrderList
      :data="orderList"
      :loading="loading"
      @select="onSelect"
      @row-click="openDetail"
    />

    <OrderDetailDialog
      v-if="showDetail"
      :order-id="currentOrderId"
      @close="showDetail = false"
    />
  </div>
</template>

<script setup lang="ts">
import OrderFilter from './components/OrderFilter.vue'
import OrderActions from './components/OrderActions.vue'
import OrderList from './components/OrderList.vue'
import OrderDetailDialog from './components/OrderDetailDialog.vue'

import { useOrder } from '@/hooks/useOrder'
import { usePermission } from '@/hooks/usePermission'

const permission = usePermission()

const {
  orderList,
  filters,
  loading,
  selectedOrders,
  fetchOrders,
  onFilterChange,
  onSelect,
  handleExport,
  handleChangeStatus,
  showDetail,
  currentOrderId,
  openDetail
} = useOrder()
</script>

OrderList.vue - 核心问题

<template>
  <BaseTable
    :data="data"
    @row-click="handleRowClick"
  >
    <template #actions="{ row }">
      <button
        v-if="permission.canEdit && row.status !== 'completed'"
        @click.stop="changeStatus(row)"
      >
        修改状态
      </button>
    </template>
  </BaseTable>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import BaseTable from '@/components/Table/BaseTable.vue'
import { usePermission } from '@/hooks/usePermission'
import { changeOrderStatus } from '@/api/order'

defineProps<{
  data: any[]
}>()

const emit = defineEmits(['row-click'])

const permission = usePermission()

function handleRowClick(row: any) {
  emit('row-click', row.id)
}

function changeStatus(row: any) {
  if (permission.canEdit) {
    changeOrderStatus(row.id)
  }
}
</script>

useOrder.ts - 上帝hook

export function useOrder() {
  const orderList = ref([])
  const filters = ref({})
  const loading = ref(false)
  const selectedOrders = ref([])

  const showDetail = ref(false)
  const currentOrderId = ref<string | null>(null)

  async function fetchOrders() {
    loading.value = true
    orderList.value = await fetchOrderList(filters.value)
    loading.value = false
  }

  function handleExport() {
    // 导出逻辑
  }

  function handleChangeStatus() {
    // 状态变更
  }

  function openDetail(id: string) {
    currentOrderId.value = id
    showDetail.value = true
  }

  return {
    orderList,
    filters,
    loading,
    selectedOrders,
    fetchOrders,
    handleExport,
    handleChangeStatus,
    openDetail,
    showDetail,
    currentOrderId
  }
}
posted @ 2026-02-11 14:06  MT-Jaxon  阅读(3)  评论(0)    收藏  举报