Vue.js: المشروع النهائي: لوحة تحكم المتجر

آخر تحديث: 2026-08-26

هذا هو المشروع النهائي لدورة Vue 3 التعليمية — حيث سنطبق كل ما تعلمته في الدرس 29 على نظام خلفي حقيقي للتجارة الإلكترونية بنموذج SaaS. سنصمم تطبيقنا على غرار بنية PanJiaChen/vue-element-admin، التي حصلت على 88 ألف⭐ على GitHub، لبناء بنية خلفية للتجارة الإلكترونية تدعم 5,000 تاجر و30,000 وحدة تخزين (SKU).

يتألف المشروع بأكمله من 8 وحدات رئيسية ويتطلب ما بين 10 و12 ساعة من العمل. عند الانتهاء من هذا المشروع، ستكون قادرًا على تطوير تطبيقات Vue على مستوى المؤسسات بشكل مستقل.

1. ما ستتعلمه



2. «متطلبات الخبرة الشاملة» لمدير منتجات في شركة تجارة إلكترونية تعمل بنموذج SaaS

(1) التحدي: كيفية بناء بنية خلفية للتجارة الإلكترونية تخدم 5,000 تاجر و30,000 وحدة تخزين (SKU)

تمت ترقية أليس لتتولى قيادة مشروع لوحة التحكم الإدارية:

TEXT 📖 للعرض فقط
Business Scenarios:
  - 5,000 Small and Medium-Sized Business Owners(Per household 30-300 SKU)
  - 30,000 Items SKU
  - Daily 10,000 Order
  - 5 Role Permissions(admin / manager / editor / viewer / guest)
  - Real-time Data(Dashboard,Order,Notice)
  - Multilingual(5 Language)

كتب مدير المنتج تشارلي المواصفات كما يلي:

"أليس، تحتاج منصتنا SaaS إلى واجهة إدارة شاملة. نحتاج إلى 8 وحدات: لوحة التحكم، والمنتجات، والطلبات، والمستخدمين، والتسويق، والإعدادات، وتسجيل الدخول، والنشر. كل وحدة من هذه الوحدات ذات أهمية بالغة. قومي بتطويرها باستخدام Vue 3، في غضون 10 إلى 12 ساعة، مع الاستفادة من جميع الدروس الـ29 التي تعلمتها."

(2) مشروع شامل لـ Vue 3: بنية مكونة من 8 وحدات

TEXT 📖 للعرض فقط
src/
├-- api/                   # API Packaging
│   ├-- auth.ts
│   ├-- product.ts
│   ├-- order.ts
│   └-- user.ts
├-- assets/                # Static Resources
├-- components/            # Public Components
│   ├-- BaseButton.vue
│   ├-- BaseTable.vue       # Secondary Packaging Element Plus
│   ├-- BasePagination.vue
│   ├-- BaseDialog.vue
│   └-- charts/             # Charts
│       ├-- SalesChart.vue
│       ├-- UserChart.vue
│       └-- OrderChart.vue
├-- composables/           # Composite Functions
│   ├-- useAuth.ts
│   ├-- usePermission.ts
│   ├-- useTable.ts
│   └-- usePagination.ts
├-- layouts/                # Layout
│   ├-- DefaultLayout.vue   # After logging in
│   └-- AuthLayout.vue      # Login Page
├-- router/                # Routing
│   └-- index.ts
├-- stores/                 # Pinia
│   ├-- auth.ts
│   ├-- product.ts
│   ├-- order.ts
│   └-- app.ts              # Global(Topic / Sidebar)
├-- types/                  # TS Type
│   ├-- user.ts
│   ├-- product.ts
│   └-- api.ts
├-- utils/                  # Tools
│   ├-- request.ts          # axios Packaging
│   ├-- auth.ts
│   └-- format.ts
├-- views/                  # Page
│   ├-- dashboard/          # Dashboard
│   ├-- login/              # Log In
│   ├-- product/            # Products
│   ├-- order/              # Order
│   ├-- user/               # User
│   ├-- marketing/          # Marketing
│   └-- error/              # 403 / 404
├-- App.vue
└-- main.ts

(3) الإيرادات

بعد إنجاز هذا المشروع:



3. الوحدة 1: بدء المشروع (1.5 ساعة)

(1) استكمال ملف package.json

▶ مثال: إكمال تهيئة المشروع (مستوى الصعوبة: ⭐⭐)

إعداد مشروع كامل من الصفر باستخدام Vue 3 + Vite + Pinia + Element Plus + ECharts + TypeScript:

JSON
{
  "name": "mercury-admin",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build",
    "preview": "vite preview",
    "test": "vitest",
    "test:e2e": "playwright test",
    "lint": "eslint . --ext .vue,.ts,.tsx"
  },
  "dependencies": {
    "vue": "^3.4.0",
    "vue-router": "^4.3.0",
    "pinia": "^2.1.0",
    "element-plus": "^2.5.0",
    "@element-plus/icons-vue": "^2.3.0",
    "echarts": "^5.4.0",
    "vue-echarts": "^7.0.0",
    "axios": "^1.6.0",
    "dayjs": "^1.11.0",
    "vueuse": "^10.7.0"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.0.0",
    "vite": "^5.0.0",
    "vue-tsc": "^1.8.0",
    "typescript": "^5.3.0",
    "unplugin-vue-components": "^0.26.0",
    "unplugin-auto-import": "^0.17.0",
    "unplugin-icons": "^0.17.0",
    "@iconify-json/carbon": "^1.1.0",
    "sass": "^1.69.0",
    "vitest": "^1.0.0",
    "@vue/test-utils": "^2.4.0",
    "@playwright/test": "^1.40.0"
  }
}

(2) vite.config.ts

TS
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import'
import Components from 'unplugin-vue-components'
import Icons from 'unplugin-icons/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import path from 'path'

export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      imports: ['vue', 'vue-router', 'pinia', 'vueuse'],
      resolvers: [ElementPlusResolver()],
      dts: 'src/auto-imports.d.ts'
    }),
    Components({
      resolvers: [ElementPlusResolver()],
      dts: 'src/components.d.ts'
    }),
    Icons({ autoInstall: true })
  ],
  resolve: {
    alias: { '@': path.resolve(__dirname, 'src') }
  },
  server: {
    port: 5173,
    proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true } }
  },
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'vue-vendor': ['vue', 'vue-router', 'pinia'],
          'echarts-vendor': ['echarts', 'vue-echarts']
        }
      }
    }
  }
})


4. الوحدة 2: تسجيل الدخول + المصادقة باستخدام JWT + التوجيه القائم على الأذونات (2 ساعة)

(1) متجر Pinia الأصلي

▶ مثال: تسجيل الدخول باستخدام JWT + مخزن أذونات مكون من 5 أدوار (مستوى الصعوبة: ⭐⭐)

استخدم متجر إعدادات Pinia لإدارة الرموز / المستخدمين / الأدوار / الأذونات:

TS
// stores/auth.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { loginApi, getUserInfoApi } from '@/api/auth'

export const useAuthStore = defineStore('auth', () => {
  const token = ref<string>(localStorage.getItem('token') || '')
  const user = ref<User | nulo>(nulo)
  const roles = ref<string[]>([])
  const permissions = ref<string[]>([])
  
  const isLoggedIn = computed(() => !!token.value)
  const isAdmin = computed(() => roles.value.includes('admin'))
  
  async function login(credentials: { username: string; password: string }) {
    const { data } = await loginApi(credentials)
    token.value = data.token
    user.value = data.user
    roles.value = data.roles
    permissions.value = data.permissions
    localStorage.setItem('token', data.token)
  }
  
  async function fetchUserInfo() {
    const { data } = await getUserInfoApi()
    user.value = data.user
    roles.value = data.roles
    permissions.value = data.permissions
  }
  
  function logout() {
    token.value = ''
    user.value = nulo
    roles.value = []
    permissions.value = []
    localStorage.removeItem('token')
  }
  
  return { token, user, roles, permissions, isLoggedIn, isAdmin, login, fetchUserInfo, logout }
}, {
  persist: {
    key: 'mercury-auth',
    paths: ['token', 'user', 'roles', 'permissions']
  }
})
▶ جرّب الكود

(2) حارس الطريق

TS
// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import { useAuthStore } from '@/stores/auth'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/login', component: () => import('@/views/login/LoginPage.vue') },
    {
      path: '/',
      component: () => import('@/layouts/DefaultLayout.vue'),
      meta: { requiresAuth: true },
      children: [
        { path: '', redirect: '/dashboard' },
        { path: 'dashboard', component: () => import('@/views/dashboard/DashboardPage.vue') },
        { path: 'products', component: () => import('@/views/product/ProductListPage.vue') }
      ]
    }
  ]
})

router.beforeEach((to, from, next) => {
  const auth = useAuthStore()
  
  if (to.meta.requiresAuth && !auth.isLoggedIn) {
    return next({ name: 'login', query: { redirect: to.fullPath } })
  }
  
  next()
})

export default router

(3) توجيهات الأذونات المخصصة

TS
// directives/permission.ts
import { useAuthStore } from '@/stores/auth'

export const permission = {
  mounted(el: HTMLElement, binding: { value: string }) {
    const auth = useAuthStore()
    if (!auth.permissions.includes(binding.value)) {
      el.parentNode?.removeChild(el)
    }
  }
}
VUE
<button v-permission="'product.create'">Create Product</button>


5. الوحدة 3: لوحة التحكم (ساعتان)

(1) 5 رسوم بيانية من ECharts

▶ مثال: لوحة معلومات تحتوي على 5 مخططات من ECharts (مستوى الصعوبة: ⭐⭐)

الكود الأساسي للوحة التحكم: 5 مخططات + 4 مؤشرات أداء رئيسية + تخطيط شبكي باستخدام Element Plus:

VUE 📖 للعرض فقط
<!-- views/dashboard/DashboardPage.vue -->
<template>
  <div class="dashboard">
    <!-- 1. KPI Card -->
    <div class="kpi-grid">
      <KpiCard title="Today's Sales" :value="stats.todaySales" :change="+12%" />
      <KpiCard title="Orders" :value="stats.todayOrders" :change="+5%" />
      <KpiCard title="Active Users" :value="stats.activeUsers" :change="+8%" />
      <KpiCard title="Conversion" :value="stats.conversion" :change="-2%" />
    </div>
    
    <!-- 2. 5 View Chart -->
    <el-row :gutter="20">
      <el-col :span="12">
        <SalesChart :data="salesData" />
      </el-col>
      <el-col :span="12">
        <UserChart :data="userData" />
      </el-col>
      <el-col :span="24">
        <OrderChart :data="orderData" />
      </el-col>
      <el-col :span="12">
        <CategoryChart :data="categoryData" />
      </el-col>
      <el-col :span="12">
        <TopProductsTable :data="topProducts" />
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { getDashboardStatsApi } from '@/api/dashboard'

const stats = ref({})
const salesData = ref([])
const userData = ref([])
const orderData = ref([])
const categoryData = ref([])
const topProducts = ref([])

onMounted(async () => {
  const { data } = await getDashboardStatsApi()
  Object.assign(stats.value, data.stats)
  salesData.value = data.sales
  userData.value = data.users
  orderData.value = data.orders
  categoryData.value = data.categories
  topProducts.value = data.topProducts
})
</script>
46 سطر من الكود المنطقي (تجاوز الحد 40, للعرض فقط)

(2) تغليف مكونات ECharts

VUE
<!-- components/charts/SalesChart.vue -->
<template>
  <el-card title="Sales Trend">
    <v-chart :option="chartOption" autoresize style="height: 300px" />
  </el-card>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart } from 'echarts/charts'
import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'

use([CanvasRenderer, LineChart, GridComponent, TooltipComponent, LegendComponent])

const props = defineProps<{
  data: Array<{ date: string; sales: number }>
}>()

const chartOption = computed(() => ({
  tooltip: { trigger: 'axis' },
  xAxis: { type: 'category', data: props.data.map(d => d.date) },
  yAxis: { type: 'value' },
  series: [{
    name: 'Sales',
    type: 'line',
    data: props.data.map(d => d.sales),
    smooth: true
  }]
}))
</script>


6. الوحدة 4: إدارة المنتجات (1.5 ساعة)

(1) قائمة المنتجات + CRUD

▶ مثال: عمليات CRUD للمنتج + التحكم في الوصول (مستوى الصعوبة: ⭐⭐)

جوهر إدارة المنتج: إعادة تغليف BaseTable + عرض 6 أعمدة + توجيهات الأذونات + تأكيد الحذف:

VUE 📖 للعرض فقط
<!-- views/product/ProductListPage.vue -->
<template>
  <BaseTable
    :data="products"
    :columns="columns"
    :total="total"
    :loading="loading"
    @search="onSearch"
    @page="onPage"
  >
    <template #toolbar>
      <el-button type="primary" v-permission="'product.create'" @click="onCreate">
        Create Product
      </el-button>
    </template>
    
    <template #column-status="{ row }">
      <el-tag :type="statusType(row.status)">{{ row.status }}</el-tag>
    </template>
    
    <template #column-actions="{ row }">
      <el-button v-permission="'product.edit'" @click="onEdit(row)">Edit</el-button>
      <el-button v-permission="'product.delete'" type="danger" @click="onDelete(row)">Delete</el-button>
    </template>
  </BaseTable>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { getProductsApi, deleteProductApi } from '@/api/product'

const products = ref<Product[]>([])
const total = ref(0)
const loading = ref(false)
const search = ref({ name: '', category: '', status: '' })
const page = ref(1)
const size = ref(20)

const columns = [
  { key: 'id', label: 'ID', width: 80 },
  { key: 'name', label: 'Name' },
  { key: 'category', label: 'Category' },
  { key: 'price', label: 'Price', formatter: (row) => `$${row.price}` },
  { key: 'stock', label: 'Stock' },
  { key: 'status', label: 'Status' }
]

async function fetchData() {
  loading.value = true
  const { data } = await getProductsApi({ ...search.value, page: page.value, size: size.value })
  products.value = data.items
  total.value = data.total
  loading.value = false
}

function onSearch() { page.value = 1; fetchData() }
function onPage(p) { page.value = p; fetchData() }

async function onDelete(row) {
  await ElMessageBox.confirm(`Delete ${row.name}?`, 'Confirm')
  await deleteProductApi(row.id)
  ElMessage.success('Deleted')
  fetchData()
}

onMounted(fetchData)
</script>
57 سطر من الكود المنطقي (تجاوز الحد 40, للعرض فقط)

(2) مربع حوار تعديل المنتج

VUE
<!-- views/product/ProductEditDialog.vue -->
<template>
  <el-dialog v-model="visible" :title="isEdit ? 'Edit Product' : 'Create Product'" width="700px">
    <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
      <el-form-item label="Name" prop="name">
        <el-input v-model="form.name" />
      </el-form-item>
      <el-form-item label="Category" prop="category">
        <el-select v-model="form.category">
          <el-option v-for="c in categories" :key="c" :value="c" :label="c" />
        </el-select>
      </el-form-item>
      <el-form-item label="Price" prop="price">
        <el-input-number v-model="form.price" :min="0" />
      </el-form-item>
      <el-form-item label="Stock" prop="stock">
        <el-input-number v-model="form.stock" :min="0" />
      </el-form-item>
      <el-form-item label="Image">
        <el-upload action="/api/upload" :show-file-list="false">
          <img v-if="form.image" :src="form.image" class="preview" />
          <el-button v-else>Upload</el-button>
        </el-upload>
      </el-form-item>
    </el-form>
    
    <template #footer>
      <el-button @click="visible = false">Cancel</el-button>
      <el-button type="primary" @click="onSave">Save</el-button>
    </template>
  </el-dialog>
</template>


7. الوحدة 5: إدارة الطلبات (ساعة واحدة)

(1) قائمة الطلبات + التفاصيل

▶ مثال: قائمة الطلبات + مربع حوار التفاصيل (مستوى الصعوبة: ⭐)

جوهر الترتيب: قائمة «BaseTable» + درج التفاصيل + انتقالات الstatus:

VUE
<template>
  <BaseTable :data="orders" :columns="columns" :total="total">
    <template #column-status="{ row }">
      <el-tag :type="statusType(row.status)">{{ row.status }}</el-tag>
    </template>
    <template #column-actions="{ row }">
      <el-button @click="viewDetail(row)">View</el-button>
      <el-button v-if="row.status === 'pending'" @click="confirmOrder(row)">Confirm</el-button>
    </template>
  </BaseTable>
  
  <el-dialog v-model="detailVisible" title="Order Detail" width="800px">
    <h3>Order #{{ currentOrder?.id }}</h3>
    <p>User: {{ currentOrder?.user }}</p>
    <p>Total: ${{ currentOrder?.total }}</p>
    <h4>Items:</h4>
    <ul>
      <li v-for="item in currentOrder?.items" :key="item.id">
        {{ item.name }} × {{ item.quantity }} = ${{ item.price * item.quantity }}
      </li>
    </ul>
  </el-dialog>
</template>
▶ جرّب الكود

8. الوحدة 6: إدارة المستخدمين (ساعة واحدة)

(1) قائمة المستخدمين + إدارة الأدوار

▶ مثال: إدارة أدوار المستخدمين + تعديل نموذج RBAC (مستوى الصعوبة: ⭐)

أساسيات إدارة المستخدمين: الأدوار المتعلقة بالقوائم والعلامات ومجموعات خانات الاختيار:

VUE
<template>
  <BaseTable :data="users" :columns="columns">
    <template #column-roles="{ row }">
      <el-tag v-for="role in row.roles" :key="role" :type="roleType(role)">
        {{ role }}
      </el-tag>
    </template>
    <template #column-actions="{ row }">
      <el-button @click="editRoles(row)">Edit Roles</el-button>
    </template>
  </BaseTable>
  
  <el-dialog v-model="rolesDialog" title="Edit Roles">
    <el-checkbox-group v-model="selectedRoles">
      <el-checkbox v-for="r in allRoles" :key="r" :value="r">{{ r }}</el-checkbox>
    </el-checkbox-group>
    <template #footer>
      <el-button @click="saveRoles">Save</el-button>
    </template>
  </el-dialog>
</template>
▶ جرّب الكود

(2) أذونات الأدوار الخمسة

TS
// utils/roles.ts
export const ROLES = {
  admin: {
    label: 'Admin',
    permissions: ['*']  // Full Access
  },
  manager: {
    label: 'Manager',
    permissions: ['product.*', 'order.*', 'user.read']
  },
  editor: {
    label: 'Editor',
    permissions: ['product.read', 'product.edit', 'order.read']
  },
  viewer: {
    label: 'Viewer',
    permissions: ['*.read']
  },
  guest: {
    label: 'Guest',
    permissions: ['product.read']
  }
}


9. الوحدة 7: الحملات التسويقية (ساعة واحدة)

(1) إدارة القسائم

▶ مثال: قائمة القسائم + النطاق الزمني (مستوى الصعوبة ⭐)

المكونات الأساسية لوحدة التسويق: el-table + status الtag + تنسيق الوقت:

VUE
<template>
  <el-table :data="coupons" stripe>
    <el-table-column prop="code" label="Code" />
    <el-table-column prop="type" label="Type" :formatter="formatType" />
    <el-table-column prop="discount" label="Discount" />
    <el-table-column label="Status">
      <template #default="{ row }">
        <el-tag :type="statusType(row.status)">{{ row.status }}</el-tag>
      </template>
    </el-table-column>
    <el-table-column label="Valid Period">
      <template #default="{ row }">
        {{ formatDate(row.startAt) }} ~ {{ formatDate(row.endAt) }}
      </template>
    </el-table-column>
  </el-table>
</template>
▶ جرّب الكود

10. الوحدة 8: النشر (ساعة واحدة)

(1) تحسين البنية

▶ مثال: تحسين تقسيم المقاطع يدويًّا في Vite (مستوى الصعوبة: ⭐⭐)

نشر الوحدة الأساسية: تقسيم manualChunks (vue / echarts / ui / utils):

TS
// vite.config.ts(Production Environment Optimization)
build: {
  outDir: 'dist',
  sourcemap: true,  // Used for Sentry
  minify: 'esbuild',
  cssMinify: 'lightningcss',
  rollupOptions: {
    output: {
      manualChunks: {
        'vue-vendor': ['vue', 'vue-router', 'pinia'],
        'echarts-vendor': ['echarts', 'vue-echarts'],
        'ui-vendor': ['element-plus'],
        'utils': ['axios', 'dayjs']
      }
    }
  }
}
▶ جرّب الكود

(2) النشر على Vercel

BASH
npm install -g vercel
vercel --prod
JSON
// vercel.json
{
  "build": { "command": "npm run build" },
  "outputDirectory": "dist",
  "framework": "vite",
  "rewrites": [
    { "source": "/(.*)", "destination": "/index.html" }
  ]
}

(3) مراقبة الأداء

TS
// main.ts
import * as Sentry from '@sentry/vue'

Sentry.init({
  app,
  dsn: 'https://your-dsn@sentry.io/123',
  tracesSampleRate: 0.1
})


11. إحصائيات حجم الكود لجميع الوحدات الثماني

الوحدة عدد أسطر البرمجة الميزات الرئيسية
1 تهيئة المشروع 300 Vite + Pinia + Router + Element Plus + ECharts
2 المصادقة 400 JWT + Route Guard + توجيه الأذونات + 5 أدوار
3 لوحات معلومات 500 5 مخططات ECharts + 4 مؤشرات أداء رئيسية + بيانات في الوقت الفعلي
4 إدارة المنتجات 600 CRUD + عرض القائمة + التعديل + تحميل الصور + الأذونات
5 إدارة الطلبات 400 القائمة + التفاصيل + تغييرات الstatus + التصدير
6 إدارة المستخدمين 300 إدارة القوائم + إدارة الأدوار + تعديل الأذونات
7 حملات تسويقية 300 قسائم + نطاق زمني + آلة الحالات
8 النشر والتشغيل 200 تحسين البناء باستخدام Vite + Vercel + Sentry
الإجمالي 3,000 نظام خلفي SaaS كامل مكون من 8 وحدات


12. مرجع سريع: 5 أخطاء شائعة

الخطأ الأعراض الحل
شاشة فارغة عند التحميل الأول خطأ في ترتيب تحميل Router / Pinia في ملف main.ts، استدعِ app.use(router) قبل app.use(pinia)
انتهت صلاحية الأذونات لم يتم تحديث الدور أذونات المشاهدة
10,000 status تقطع ضعف أداء الجدول التمرير الافتراضي el-table-v2
لا يتم عرض ECharts ارتفاع الحاوية 0 تعيين style="height: 300px"
خطأ 404 بعد النشر مشكلات في توجيه SPA Vercel تعيد كتابة التكوين


❓ أسئلة شائعة

س كم من الوقت يستغرق إكمال الوحدة 8؟
ج 10–12 ساعة (وفقًا لوتيرة الدورة). 4–6 ساعات للمطورين ذوي الخبرة.
س كيف يمكنني محاكاة واجهة برمجة تطبيقات (API) للخلفية؟
ج استخدم MSW (Mock Service Worker) أو Express + json-server. يستخدم هذا الدليل التعليمي الخيار الأول.
س هل يدعم Element Plus لغة TypeScript بشكل كامل؟
ج نعم. تمت إعادة كتابة Element Plus 2.x بالكامل بلغة TypeScript، وهو يوفر استدلالًا كاملاً للأنواع.
س كيف يمكنني تحسين أداء نموذج يحتوي على 10,000 حقل؟
ج استخدم el-table-v2 (الإصدار الرسمي من Element Plus مع التمرير الافتراضي) أو vue-virtual-scroller. زيادة في الأداء بمقدار 100 ضعف.
س كيف يمكنني النشر على بيئة الإنتاج؟
ج Vercel (موصى به، مجاني) + نطاق مخصص. vercel --prod بأمر واحد.
س ما الذي يجب أن أتعلمه بعد إتمام الدورة المكونة من 30 درسًا؟
ج (1) Nuxt 3 (SSR)؛ (2) React (تحليل مقارن)؛ (3) الواجهات الأمامية المصغرة (qiankun)؛ (4) تطوير تطبيقات الأجهزة المحمولة (uni-app).
س هل يمكنني استخدام قالب المشروع هذا كما هو؟
ج نعم. الكود مفتوح المصدر بالكامل ويمكن استخدامه مباشرة كنقطة انطلاق لمشاريع المؤسسات.

📖 ملخص



13. 🎉 انتهيت من الدرس 30!

تهانينا على إتمام دورة Vue 3 الكاملة المكونة من 30 درسًا! بدءًا من الأساسيات وصولاً إلى المشاريع على مستوى المؤسسات، فقد أتقنت الآن ما يلي:

توصيات بشأن الخطوات التالية:


📝 تمارين

  1. أسئلة أساسية (مستوى الصعوبة: ⭐)

    أكمل الوحدة 1 (بدء المشروع) + الوحدة 2 (تسجيل الدخول والمصادقة):

    1. Vite + Vue 3 + Pinia + Element Plus
    2. صفحة تسجيل الدخول + لوحة التحكم (عنصر مؤقت) 3.5 أساسيات أذونات الأدوار
  2. مسائل متقدمة (مستوى الصعوبة: ⭐⭐)

    أكمل الوحدات الأربع الرئيسية: التهيئة / تسجيل الدخول / لوحة التحكم / المنتجات:

    1. إكمال تهيئة Vite + TypeScript
    2. 5 رسوم بيانية من ECharts
    3. عمليات CRUD للمنتج (10 حقول)
  3. مسائل التحدي (مستوى الصعوبة: ⭐⭐⭐)

    إكمال جميع الوحدات الثماني + النشر:

    1. جميع الوحدات الثماني (10–12 ساعة)
    2. التعيين القوي للأنواع في TypeScript
    3. تحسين الأداء (التمرير الافتراضي / المقاطع اليدوية)
    4. تغطية الاختبار (5 مكونات + 3 اختبارات من طرف إلى طرف)
    5. النشر على Vercel + التكامل مع Sentry
    6. أكملت دورة Vue التعليمية المكونة من 30 درسًا — تخرجت! 🎉
Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%