🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

دليل Vue 3 الكامل 2026: واجهة برمجة تطبيقات التركيب وPinia وNuxt.js

⏱️3 min read  ·  654 words

Vue 3 مع واجهة برمجة تطبيقات Composition، وإدارة حالة Pinia، وNuxt.js للمكدس الكامل – Vue هو ثاني أكثر إطارات عمل JavaScript شيوعًا في عام 2026 مع تجربة مطور ممتازة. يغطي هذا الدليل الكامل واجهة برمجة تطبيقات التركيب الخاصة بـ Vue 3 ونظام التفاعل وأنماط الإنتاج.

يثبت

# Create new project
npm create vue@latest my-app

# Choose: TypeScript, Vue Router, Pinia, ESLint, Prettier
cd my-app && npm install && npm run dev

واجهة برمجة التطبيقات للتكوين

<!-- Counter.vue — script setup syntax (preferred) -->
<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue';

// ref — reactive primitive
const count = ref(0);
const name = ref('World');

// computed — derived state (cached)
const doubled = computed(() => count.value * 2);
const greeting = computed(() => `Hello, ${name.value}! Count: ${count.value}`);

// watch — side effects
watch(count, (newVal, oldVal) => {
  console.log(`Count changed: ${oldVal} → ${newVal}`);
  document.title = `Count: ${newVal}`;
});

// watchEffect — auto-tracks dependencies
watchEffect(() => {
  localStorage.setItem('count', count.value.toString());
});

// Lifecycle hooks
onMounted(() => {
  console.log('Component mounted!');
  count.value = parseInt(localStorage.getItem('count') || '0');
});

function increment() {
  count.value++;
}

function reset() {
  count.value = 0;
}
</script>

<template>
  <div class="counter">
    <h2>{{ greeting }}</h2>
    <p>Doubled: {{ doubled }}</p>
    <!-- v-model works with refs automatically -->
    <input v-model="name" placeholder="Your name" />
    <div>
      <button @click="increment">+1</button>
      <button @click="reset">Reset</button>
    </div>
  </div>
</template>

الكائنات التفاعلية مع رد الفعل ()

<script setup lang="ts">
import { reactive, toRefs } from 'vue';

// reactive — for objects (no .value needed)
const state = reactive({
  count: 0,
  name: 'Alice',
  todos: [] as string[],
});

// Destructure with toRefs (maintains reactivity)
const { count, name } = toRefs(state);

// Mutate directly
function addTodo(text: string) {
  state.todos.push(text);
}
</script>

المكونات والدعائم

<!-- UserCard.vue -->
<script setup lang="ts">
interface Props {
  user: {
    id: number;
    name: string;
    email: string;
    avatarUrl?: string;
  };
  isSelected?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  isSelected: false,
});

const emit = defineEmits<{
  select: [userId: number];
  delete: [userId: number];
}>();

function handleSelect() {
  emit('select', props.user.id);
}
</script>

<template>
  <div
    class="user-card"
    :class="{ 'user-card--selected': isSelected }"
    @click="handleSelect"
  >
    <img
      v-if="user.avatarUrl"
      :src="user.avatarUrl"
      :alt="user.name"
    />
    <div>
      <h3>{{ user.name }}</h3>
      <p>{{ user.email }}</p>
    </div>
    <button @click.stop="emit('delete', user.id)">Delete</button>
  </div>
</template>

المواد المركبة – خطافات مخصصة

// composables/useUsers.ts
import { ref, computed } from 'vue';

interface User { id: number; name: string; email: string; }

export function useUsers() {
  const users = ref<User[]>([]);
  const loading = ref(false);
  const error = ref<string | null>(null);
  const searchQuery = ref('');

  const filteredUsers = computed(() =>
    users.value.filter(u =>
      u.name.toLowerCase().includes(searchQuery.value.toLowerCase())
    )
  );

  async function fetchUsers() {
    loading.value = true;
    error.value = null;
    try {
      const response = await fetch('/api/users');
      users.value = await response.json();
    } catch (e) {
      error.value = 'Failed to load users';
    } finally {
      loading.value = false;
    }
  }

  async function createUser(data: Omit<User, 'id'>) {
    const response = await fetch('/api/users', {
      method: 'POST',
      body: JSON.stringify(data),
      headers: { 'Content-Type': 'application/json' },
    });
    const newUser = await response.json();
    users.value = [...users.value, newUser];
  }

  return { users, loading, error, searchQuery, filteredUsers, fetchUsers, createUser };
}

// Usage in component
const { users, loading, error, searchQuery, filteredUsers, fetchUsers } = useUsers();
onMounted(fetchUsers);

إدارة ولاية بينيا

// stores/userStore.ts
import { defineStore } from 'pinia';

export const useUserStore = defineStore('users', {
  state: () => ({
    users: [] as User[],
    currentUser: null as User | null,
    loading: false,
  }),

  getters: {
    activeUsers: (state) => state.users.filter(u => u.active),
    userCount: (state) => state.users.length,
  },

  actions: {
    async fetchUsers() {
      this.loading = true;
      try {
        this.users = await api.getUsers();
      } finally {
        this.loading = false;
      }
    },

    async createUser(data: CreateUserInput) {
      const user = await api.createUser(data);
      this.users.push(user);
      return user;
    },

    logout() {
      this.currentUser = null;
    }
  }
});

// In component
import { useUserStore } from '@/stores/userStore';
const store = useUserStore();
await store.fetchUsers();
console.log(store.userCount);
store.logout();

Vue vs React: متى تختار Vue

  • اختر Vue متى: هناك حاجة إلى منحنى تعليمي أبسط، ويفضل اتباع نهج القالب الأول، وفريق أصغر، والانتقال التدريجي من jQuery/Vanilla JS
  • اختر الرد متى: فريق كبير، مطلوب إدارة حالة معقدة، نظام Next.js البيئي، React Native للجوال
  • كلاهما ممتازبالنسبة لمعظم تطبيقات الويب، غالبًا ما يعود الاختيار إلى معرفة الفريق

يعد Vue 3 في عام 2026 مع إعداد البرنامج النصي وComposition API وPinia إطار عمل ناضجًا وصديقًا للمطورين. يعد بناء جملة القالب أكثر سهولة من JSX بالنسبة للعديد من المطورين، وتوفر واجهة برمجة التطبيقات Composition API القوة الكاملة للمكونات المعقدة. للحصول على حزمة كاملة، قم بالاقتران مع Nuxt.js للحصول على نفس مكاسب الإنتاجية مثل Next.js لـ React.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা