SvelteKit هي أحدث ما أسميه أطر عمل تطبيقات الجيل التالي. إنه ، بالطبع ، يدعم تطبيقًا من أجلك ، مع التوجيه المستند إلى الملفات ، والنشر ، والتقديم من جانب الخادم الذي قام به Next إلى الأبد. لكن SvelteKit يدعم أيضًا التخطيطات المتداخلة ، وطفرات الخادم التي تقوم بمزامنة البيانات على صفحتك ، وبعض التفاصيل الأخرى التي سنتطرق إليها.
يُقصد بهذا المنشور أن يكون مقدمة رفيعة المستوى نأمل أن تثير بعض الإثارة لأي شخص لم يستخدم SvelteKit مطلقًا. ستكون جولة مريحة. إذا كنت تحب ما تراه ، فإن ملف المستندات الكاملة هنا.
من بعض النواحي ، يعد هذا المنشور صعبًا للكتابة. SvelteKit هو ملف إطار تطبيق. إنه موجود لمساعدتك في إنشاء ... حسنًا ، التطبيقات. هذا يجعل من الصعب العرض. ليس من الممكن إنشاء تطبيق كامل في منشور مدونة. لذا بدلاً من ذلك ، سوف نستخدم مخيلتنا قليلاً. سنقوم ببناء الهيكل العظمي للتطبيق ، ولدينا بعض العناصر النائبة الفارغة لواجهة المستخدم ، والبيانات الثابتة المشفرة. الهدف ليس إنشاء تطبيق فعلي ، ولكن بدلاً من ذلك لتوضيح كيفية عمل قطع SvelteKit المتحركة حتى تتمكن من إنشاء تطبيق خاص بك.
تحقيقًا لهذه الغاية ، سنقوم ببناء تطبيق To-Do الذي تم تجربته وحقيقيًا كمثال. ولكن لا داعي للقلق ، فسيكون هذا أكثر بكثير حول رؤية كيفية عمل SvelteKit بدلاً من إنشاء تطبيق To-Do آخر.
رمز كل شيء في هذا المنشور متاح في جيثب. هذا المشروع هو أيضا منتشرة في فرسيل للحصول على عرض حي.
إنشاء مشروعك
إن إدارة مشروع SvelteKit الجديد أمر بسيط بما فيه الكفاية. يركض npm create your-app-name
في المحطة والإجابة على مطالبات الأسئلة. تأكد من اختيار "Skeleton Project" ولكن حدد ما تريده لـ TypeScript و ESLint وما إلى ذلك.
بمجرد إنشاء المشروع ، قم بتشغيله npm i
و npm run dev
ويجب أن يبدأ تشغيل خادم التطوير. إشعال النار localhost:5173
في المتصفح وستحصل على صفحة العنصر النائب لتطبيق الهيكل العظمي.
التوجيه الأساسي
تلاحظ routes
مجلد تحت src
. هذا يحمل رمزًا لجميع مساراتنا. يوجد بالفعل ملف +page.svelte
ملف هناك مع محتوى للجذر /
طريق. بغض النظر عن مكان وجودك في التسلسل الهرمي للملف ، فإن الصفحة الفعلية لهذا المسار لها الاسم دائمًا +page.svelte
. مع وضع ذلك في الاعتبار ، دعنا ننشئ صفحات لـ /list
, /details
, /admin/user-settings
و admin/paid-status
، وكذلك إضافة بعض العناصر النائبة للنص لكل صفحة.
يجب أن يبدو تخطيط ملفك مشابهًا لما يلي:
يجب أن تكون قادرًا على التنقل عن طريق تغيير مسارات URL في شريط عنوان المتصفح.
تخطيطات
سنريد روابط التنقل في تطبيقنا ، لكننا بالتأكيد لا نريد نسخ الترميز لها في كل صفحة نقوم بإنشائها. لذلك ، لنقم بإنشاء ملف +layout.svelte
ملف في جذر ملف routes
المجلد ، الذي سيتعامل معه SvelteKit كقالب عام لجميع الصفحات. دعنا ونضيف بعض المحتوى إليها:
<nav> <ul> <li> <a href="/ar/">Home</a> </li> <li> <a href="/ar/list">To-Do list</a> </li> <li> <a href="/ar/admin/paid-status">Account status</a> </li> <li> <a href="/ar/admin/user-settings">User settings</a> </li> </ul>
</nav> <slot /> <style> nav { background-color: beige; } nav ul { display: flex; } li { list-style: none; margin: 15px; } a { text-decoration: none; color: black; }
</style>
بعض التنقل البدائي مع بعض الأنماط الأساسية. أهمية خاصة هو <slot />
بطاقة شعار. هذا هو ليس الفتحة التي تستخدمها مع مكونات الويب و shadow DOM، بل ميزة Svelte تشير إلى مكان وضع المحتوى الخاص بنا. عندما يتم عرض الصفحة ، سينزلق محتوى الصفحة إلى مكان الفتحة.
والآن لدينا بعض التنقل! لن نفوز بأي مسابقات تصميم ، لكننا لا نحاول ذلك.
تخطيطات متداخلة
ماذا لو أردنا أن ترث جميع صفحات المسؤول لدينا التخطيط العادي الذي أنشأناه للتو ولكننا نشارك أيضًا بعض الأشياء المشتركة في جميع صفحات المسؤول (لكن صفحات المسؤول فقط)؟ لا مشكلة ، نضيف أخرى +layout.svelte
ملف في جذرنا admin
الدليل ، والذي سيرثه كل شيء تحته. لنفعل ذلك ونضيف هذا المحتوى:
<div>This is an admin page</div> <slot /> <style> div { padding: 15px; margin: 10px 0; background-color: red; color: white; }
</style>
نضيف لافتة حمراء تشير إلى أن هذه صفحة مسؤول ثم ، كما كان من قبل ، أ <slot />
للدلالة على المكان الذي نريد أن يذهب إليه محتوى صفحتنا.
تخطيط الجذر لدينا من قبل يجعله. داخل تخطيط الجذر هو ملف <slot />
بطاقة شعار. ينتقل محتوى التخطيط المتداخل إلى تخطيط الجذر <slot />
. وأخيرًا ، يحدد التخطيط المتداخل أسلوبه الخاص <slot />
، حيث يتم عرض محتوى الصفحة.
إذا انتقلت إلى صفحات المسؤول ، يجب أن ترى الشعار الأحمر الجديد:
تحديد بياناتنا
حسنًا ، دعنا نعرض بعض البيانات الفعلية - أو على الأقل ، نرى كيف يمكننا تقديم بعض البيانات الفعلية. هناك مائة طريقة لإنشاء قاعدة بيانات والاتصال بها. هذا المنشور حول SvelteKit ، وليس إدارة DynamoDB ، لذلك سنقوم "بتحميل" بعض البيانات الثابتة بدلاً من ذلك. لكننا سنستخدم جميع الآليات نفسها لقراءتها وتحديثها التي قد تستخدمها للبيانات الحقيقية. للحصول على تطبيق ويب حقيقي ، قم بتبديل الوظائف التي تعيد البيانات الثابتة مع وظائف الاتصال والاستعلام عن أي قاعدة بيانات تستخدمها.
لنقم بإنشاء وحدة بسيطة قذرة بتنسيق lib/data/todoData.ts
يقوم بإرجاع بعض البيانات الثابتة إلى جانب التأخيرات المصطنعة لمحاكاة الاستعلامات الحقيقية. سترى هذا lib
المجلد الذي تم استيراده في مكان آخر عبر $lib
. هذه ميزة SvelteKit لهذا المجلد المعين ، ويمكنك حتى أضف الأسماء المستعارة الخاصة بك.
let todos = [ { id: 1, title: "Write SvelteKit intro blog post", assigned: "Adam", tags: [1] }, { id: 2, title: "Write SvelteKit advanced data loading blog post", assigned: "Adam", tags: [1] }, { id: 3, title: "Prepare RenderATL talk", assigned: "Adam", tags: [2] }, { id: 4, title: "Fix all SvelteKit bugs", assigned: "Rich", tags: [3] }, { id: 5, title: "Edit Adam's blog posts", assigned: "Geoff", tags: [4] },
]; let tags = [ { id: 1, name: "SvelteKit Content", color: "ded" }, { id: 2, name: "Conferences", color: "purple" }, { id: 3, name: "SvelteKit Development", color: "pink" }, { id: 4, name: "CSS-Tricks Admin", color: "blue" },
]; export const wait = async amount => new Promise(res => setTimeout(res, amount ?? 100)); export async function getTodos() { await wait(); return todos;
} export async function getTags() { await wait(); return tags.reduce((lookup, tag) => { lookup[tag.id] = tag; return lookup; }, {});
} export async function getTodo(id) { return todos.find(t => t.id == id);
}
وظيفة لإرجاع مصفوفة مسطحة لعناصر المهام الخاصة بنا ، والبحث عن علاماتنا ، ووظيفة لجلب مهمة واحدة (سنستخدم ذلك الأخير في صفحة التفاصيل الخاصة بنا).
تحميل بياناتنا
كيف نحصل على هذه البيانات في صفحات Svelte الخاصة بنا؟ هناك عدد من الطرق ، ولكن في الوقت الحالي ، لنقم بإنشاء ملف +page.server.js
ملف في موقعنا list
المجلد ، ووضع هذا المحتوى فيه:
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); const tags = getTags(); return { todos, tags, };
}
لقد حددنا أ load()
وظيفة تسحب البيانات المطلوبة للصفحة. لاحظ أننا كذلك ليس await
بين مكالماتنا getTodos
و getTags
وظائف غير متزامنة. سيؤدي القيام بذلك إلى إنشاء شلال تحميل بيانات بينما ننتظر وصول عناصر المهام الخاصة بنا قبل تحميل علاماتنا. بدلاً من ذلك ، نعيد الوعود الأولية من load
، ويقوم SvelteKit بالعمل اللازم لـ await
لهم.
إذن ، كيف يمكننا الوصول إلى هذه البيانات من مكون الصفحة الخاص بنا؟ يوفر SvelteKit ملف data
دعم لمكوننا مع البيانات عليه. سنصل إلى عناصر المهام والعلامات الخاصة بنا منه باستخدام ملف رد الفعل.
يبدو مكون صفحة القائمة لدينا الآن على هذا النحو.
<script> export let data; $: ({ todo, tags } = data);
</script> <table cellspacing="10" cellpadding="10"> <thead> <tr> <th>Task</th> <th>Tags</th> <th>Assigned</th> </tr> </thead> <tbody> {#each todos as t} <tr> <td>{t.title}</td> <td>{t.tags.map((id) => tags[id].name).join(', ')}</td> <td>{t.assigned}</td> </tr> {/each} </tbody>
</table> <style> th { text-align: left; }
</style>
وهذا يجب أن يجعل عناصر المهام الخاصة بنا!
مجموعات التخطيط
قبل أن ننتقل إلى صفحة التفاصيل وتغيير البيانات ، دعنا نلقي نظرة خاطفة على ميزة SvelteKit الأنيقة حقًا: مجموعات التخطيط. لقد رأينا بالفعل تخطيطات متداخلة لجميع صفحات المسؤول ، ولكن ماذا لو أردنا مشاركة تخطيط بين الصفحات العشوائية على نفس المستوى من نظام الملفات لدينا؟ على وجه الخصوص ، ماذا لو أردنا مشاركة تخطيط بين صفحة القائمة وصفحة التفاصيل الخاصة بنا فقط؟ لدينا بالفعل تخطيط عالمي على هذا المستوى. بدلاً من ذلك ، يمكننا إنشاء دليل جديد ، ولكن باسم موجود بين قوسين ، مثل هذا:
لدينا الآن مجموعة تخطيط تغطي صفحات القائمة والتفاصيل الخاصة بنا. سميته (todo-management)
ولكن يمكنك تسميته بأي شيء تريده. لنكون واضحين ، هذا الاسم سوف ليس تؤثر على عناوين URL للصفحات الموجودة داخل مجموعة التخطيط. ستبقى عناوين URL كما هي ؛ تسمح لك مجموعات التخطيط بإضافة تخطيطات مشتركة إلى الصفحات دون أن تشكل جميعها الدليل بأكمله routes
.
We استطاع أضف +layout.svelte
ملف وبعض سخيفة <div>
لافتة تقول ، "مرحبًا ، نحن ندير المهام". لكن دعونا نفعل شيئًا أكثر إثارة للاهتمام. يمكن أن تحدد التخطيطات load()
وظائف من أجل توفير البيانات لجميع المسارات تحتها. دعنا نستخدم هذه الوظيفة لتحميل علاماتنا - لأننا سنستخدم علاماتنا في ملف details
الصفحة - بالإضافة إلى list
صفحة لدينا بالفعل.
في الواقع ، من شبه المؤكد أن إجبار مجموعة تخطيط على تقديم قطعة واحدة من البيانات لا يستحق كل هذا العناء ؛ من الأفضل تكرار هذه البيانات في ملف load()
وظيفة لكل صفحة. ولكن بالنسبة لهذا المنشور ، سيوفر العذر الذي نحتاجه لرؤية ميزة SvelteKit الجديدة!
أولاً ، دعنا ننتقل إلى ملف list
الصفحة +page.server.js
ملف وإزالة العلامات منه.
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); return { todos, };
}
يجب أن تظهر صفحة القائمة الخاصة بنا الآن خطأ نظرًا لعدم وجود tags
موضوع. دعنا نصلح هذا عن طريق إضافة +layout.server.js
ملف في مجموعة التخطيط الخاصة بنا ، ثم حدد ملف load()
وظيفة تقوم بتحميل علاماتنا.
import { getTags } from "$lib/data/todoData"; export function load() { const tags = getTags(); return { tags, };
}
وبهذا الشكل ، يتم عرض صفحة القائمة مرة أخرى!
نقوم بتحميل البيانات من مواقع متعددة
دعنا نضع نقطة جيدة لما يحدث هنا:
- حددنا أ
load()
وظيفة لمجموعة التخطيط لدينا ، والتي وضعناها+layout.server.js
. - هذا يوفر بيانات عن من جميع للصفحات التي يقدمها التصميم - وهو ما يعني في هذه الحالة صفحات القائمة والتفاصيل الخاصة بنا.
- تحدد صفحة قائمتنا أيضًا ملف
load()
الوظيفة التي تدخل في ملف+page.server.js
ملف. - يقوم SvelteKit بالعمل الشاق المتمثل في أخذ نتائج مصادر البيانات هذه ودمجها معًا وإتاحتها في
data
.
صفحة التفاصيل الخاصة بنا
سنستخدم صفحة التفاصيل الخاصة بنا لتحرير بند مهمة. أولاً ، دعنا نضيف عمودًا إلى الجدول الموجود في صفحة القائمة الخاصة بنا والذي يرتبط بصفحة التفاصيل بمعرف عنصر المهام في سلسلة الاستعلام.
<td><a href="/ar/details?id={t.id}">Edit</a></td>
الآن دعونا نبني صفحة التفاصيل الخاصة بنا. أولاً ، سنضيف أداة تحميل للاستيلاء على عنصر المهام الذي نقوم بتحريره. إنشاء +page.server.js
in /details
، مع هذا المحتوى:
import { getTodo, updateTodo, wait } from "$lib/data/todoData"; export function load({ url }) { const id = url.searchParams.get("id"); console.log(id); const todo = getTodo(id); return { todo, };
}
محملنا يأتي مع url
الخاصية التي يمكننا من خلالها سحب قيم سلسلة الاستعلام. هذا يجعل من السهل البحث عن عنصر المهام الذي نقوم بتحريره. دعونا نعرض هذه المهمة ، جنبًا إلى جنب مع الوظائف لتعديلها.
يتمتع SvelteKit بقدرات طفرة مدمجة رائعة ، طالما أنك تستخدم النماذج. تذكر النماذج؟ ها هي صفحة التفاصيل الخاصة بنا. لقد ألغت أنماط الإيجاز.
<script> import { enhance } from "$app/forms"; export let data; $: ({ todo, tags } = data); $: currentTags = todo.tags.map(id => tags[id]);
</script> <form use:enhance method="post" action="?/editTodo"> <input name="id" type="hidden" value="{todo.id}" /> <input name="title" value="{todo.title}" /> <div> {#each currentTags as tag} <span style="{`color:" ${tag.color};`}>{tag.name}</span> {/each} </div> <button>Save</button>
</form>
نحن نحصل على العلامات كما في السابق من أداة تحميل مجموعة التخطيط الخاصة بنا وعنصر المهام المطلوب تنفيذها من أداة تحميل صفحتنا. نحن نستحوذ على الحقيقة tag
كائنات من قائمة معرفات الوسم للمهام الواجبة ثم عرض كل شيء. نقوم بإنشاء نموذج مع إدخال مخفي للمعرف ومدخلات حقيقية للعنوان. نعرض العلامات ثم نوفر زرًا لإرسال النموذج.
إذا لاحظت وجود ملف use:enhance
، هذا ببساطة يخبر SvelteKit باستخدام التحسين التدريجي و Ajax لإرسال النموذج الخاص بنا. من المحتمل أن تستخدم ذلك دائمًا.
كيف نحفظ تعديلاتنا؟
تلاحظ action="?/editTodo"
السمة في النموذج نفسه؟ يخبرنا هذا بالمكان الذي نريد إرسال بياناتنا المعدلة إليه. بالنسبة لحالتنا ، نريد الخضوع إلى ملف editTodo
"عمل."
لنقم بإنشائه بإضافة ما يلي إلى ملف +page.server.js
ملف لدينا بالفعل للحصول على التفاصيل (والذي يحتوي حاليًا على ملف load()
وظيفة ، للاستيلاء على مهامنا):
import { redirect } from "@sveltejs/kit"; // ... export const actions = { async editTodo({ request }) { const formData = await request.formData(); const id = formData.get("id"); const newTitle = formData.get("title"); await wait(250); updateTodo(id, newTitle); throw redirect(303, "/list"); },
};
تعطينا إجراءات النموذج أ request
كائن ، والذي يوفر الوصول إلى formData
، والتي لديها get
طريقة لمجالاتنا المختلفة. أضفنا هذا الإدخال المخفي لقيمة المعرف حتى نتمكن من الحصول عليه هنا للبحث عن عنصر المهام الذي نقوم بتحريره. نحن نحاكي التأخير ، ندعو جديد updateTodo()
، ثم أعد توجيه المستخدم إلى ملف /list
الصفحة. ال updateTodo()
الطريقة مجرد تحديث بياناتنا الثابتة ؛ في الحياة الواقعية ، ستجري نوعًا من التحديث في أي متجر بيانات تستخدمه.
export async function updateTodo(id, newTitle) { const todo = todos.find(t => t.id == id); Object.assign(todo, { title: newTitle });
}
لنجربها. سننتقل إلى صفحة القائمة أولاً:
لننقر الآن على الزر "تحرير" لأحد عناصر المهام لإظهار صفحة التحرير بها /details
.
سنقوم بإضافة عنوان جديد:
الآن ، انقر فوق حفظ. يجب أن يعيدنا ذلك إلى /list
الصفحة ، مع تطبيق عنوان المهام الجديد.
كيف ظهر العنوان الجديد بهذا الشكل؟ كانت تلقائية. بمجرد إعادة توجيهنا إلى /list
الصفحة ، SvelteKit يعيد تشغيل جميع أدوات التحميل الخاصة بنا تلقائيًا تمامًا كما كان سيفعل بغض النظر. هذا هو التقدم الرئيسي الذي تقدمه أطر تطبيقات الجيل التالي ، مثل SvelteKit ، ريمكسو 13 التالي يمد. بدلاً من إعطائك طريقة مناسبة لعرض الصفحات ثم أتمنى لك حظًا سعيدًا في جلب أي نقاط نهاية قد تضطر إلى تحديث البيانات ، فإنها تدمج طفرة البيانات جنبًا إلى جنب مع تحميل البيانات ، مما يسمح لكليهما بالعمل جنبًا إلى جنب.
بعض الأشياء التي قد تتساءل عنها ...
لا يبدو تحديث الطفرة هذا مثيرًا للإعجاب. ستتم إعادة تشغيل اللوادر كلما قمت بالتنقل. ماذا لو لم نقم بإضافة إعادة توجيه في إجراء النموذج الخاص بنا ، ولكننا بقينا في الصفحة الحالية؟ سيقوم SvelteKit بإجراء التحديث في نموذج الإجراء ، كما كان من قبل ، ولكنه سيفعل ذلك لا يزال أعد تشغيل جميع أدوات التحميل للصفحة الحالية ، بما في ذلك أدوات التحميل في تخطيط (تخطيطات) الصفحة.
هل يمكننا الحصول على وسائل أكثر استهدافًا لإبطال بياناتنا؟ على سبيل المثال ، لم يتم تحرير علاماتنا ، لذلك في الحياة الواقعية لا نريد إعادة الاستعلام عنها. نعم ، ما أظهرته لك هو مجرد سلوك النماذج الافتراضي في SvelteKit. يمكنك إيقاف السلوك الافتراضي عن طريق توفير رد اتصال إلى use:enhance
. ثم يوفر SvelteKit الدليل وظائف إبطال.
من المحتمل أن يكون تحميل البيانات على كل تنقل مكلفًا وغير ضروري. هل يمكنني تخزين هذه البيانات مؤقتًا مثلما أفعل باستخدام أدوات مثل react-query
؟ نعم ، فقط بشكل مختلف. يتيح لك SvelteKit تعيين (ثم احترام) رؤوس التحكم في ذاكرة التخزين المؤقت التي يوفرها الويب بالفعل. وسأغطي آليات إبطال ذاكرة التخزين المؤقت في منشور متابعة.
كل شيء قمنا به خلال هذه المقالة يستخدم بيانات ثابتة ويقوم بتعديل القيم في الذاكرة. إذا كنت بحاجة إلى التراجع عن كل شيء والبدء من جديد ، فتوقف وأعد تشغيل npm run dev
عملية العقدة.
اختتام
لقد خدشنا سطح SvelteKit بالكاد ، لكن آمل أن تكون قد رأيت ما يكفي لتتحمس حيال ذلك. لا أتذكر آخر مرة وجدت فيها أن تطوير الويب ممتع للغاية. مع أشياء مثل التجميع ، والتوجيه ، و SSR ، والنشر التي يتم التعامل معها من خارج الصندوق ، يمكنني قضاء وقت أطول في الترميز بدلاً من التكوين.
إليك بعض الموارد الإضافية التي يمكنك استخدامها كخطوات تالية لتعلم SvelteKit:
- محتوى مدعوم من تحسين محركات البحث وتوزيع العلاقات العامة. تضخيم اليوم.
- بلاتوبلوكشين. Web3 Metaverse Intelligence. تضخيم المعرفة. الوصول هنا.
- المصدر https://css-tricks.com/getting-started-with-sveltekit/
- 1
- 10
- 100
- 11
- 7
- 9
- 98
- a
- ماهرون
- من نحن
- حوله
- الوصول
- حسابي
- اكشن
- الإجراءات
- ادم
- وأضاف
- إضافة
- العنوان
- مشرف
- متقدم
- تؤثر
- الكل
- السماح
- جنبا إلى جنب
- سابقا
- دائما
- كمية
- و
- آخر
- إجابة
- أي شخص
- التطبيق
- تطبيق
- التطبيقات
- تطبيقي
- حول
- مجموعة
- البند
- مصطنع
- تعيين
- أوتوماتيك
- تلقائيا
- متاح
- ترقب
- الى الخلف
- خلفية
- لوحة الاعلان
- شريط
- الأساسية
- قبل
- أفضل
- أفضل
- ما بين
- قطعة
- اسود
- المدونة
- المقالات والأخبار
- الأزرق
- صندوق
- جلب
- المتصفح
- البق
- نساعدك في بناء
- بنيت
- مدمج
- زر
- مخبأ
- دعوة
- دعوات
- قدرات
- حقيبة
- بالتأكيد
- تحدي
- متغير
- واضح
- الكود
- البرمجة
- اللون
- عمود
- تأتي
- مشترك
- المسابقات
- عنصر
- مكونات
- المؤتمرات
- التواصل
- الرابط
- كنسولات
- محتوى
- مناسب
- استطاع
- الدورة
- تغطية
- يغطي
- خلق
- خلق
- خلق
- حالياًّ
- حاليا
- البيانات
- قاعدة البيانات
- الترتيب
- يعرف
- تأخير
- التأخير
- نشر
- تصميم
- تفاصيل
- ديف
- التطوير التجاري
- فعل
- العرض
- لا
- فعل
- لا
- كل
- في مكان آخر
- كاف
- كامل
- كلية
- خطأ
- إلخ
- حتى
- كل
- كل شىء
- مثال
- متحمس
- إثارة
- موجود
- ذو تكلفة باهظة
- تصدير
- قابليه
- الميزات
- قليل
- مجال
- قم بتقديم
- ملفات
- أخيرا
- نهاية
- نار
- الاسم الأول
- حل
- مسطحة
- متابعيك
- إلى الأبد
- النموذج المرفق
- شكل
- أشكال
- وجدت
- الأطر
- تبدأ من
- بالإضافة إلى
- مرح
- وظيفة
- وظيفة
- وظائف
- دولار فقط واحصل على خصم XNUMX% على جميع
- الحصول على
- منح
- إعطاء
- العالمية
- Go
- هدف
- يذهب
- الذهاب
- انتزاع
- تجمع
- مجموعات
- يحدث
- الثابت
- رؤوس
- مساعدة
- هنا
- مخفي
- تسلسل
- رفيع المستوى
- يحمل
- نأمل
- أفقي
- كيفية
- HTML
- HTTPS
- سوف
- خيال
- استيراد
- أهمية
- مثير للإعجاب
- in
- بما فيه
- في البداية
- إدخال
- بدلًا من ذلك
- دمج
- وكتابة مواضيع مثيرة للاهتمام
- المُقدّمة
- IT
- العناصر
- نفسها
- جافا سكريبت
- القفل
- اسم العائلة
- آخر
- تصميم
- تعلم
- يتيح
- مستوى
- Li
- الحياة
- ضوء
- على الأرجح
- وصلات
- قائمة
- حي
- تحميل
- محمل
- جار التحميل
- الأحمال
- طويل
- بحث
- تبدو
- بحث
- حظ
- آلية
- جعل
- يصنع
- القيام ب
- إدارة
- كتيب
- هامش
- أمر
- يعني
- مكبر الصوت : يدعم، مع دعم ميكروفون مدمج لمنع الضوضاء
- مجرد
- دمج
- طريقة
- ربما
- مانع
- وحدة
- الأكثر من ذلك
- خطوة
- يتحرك
- متعدد
- الاسم
- عين
- NAV
- التنقل
- قائمة الإختيارات
- ضروري
- حاجة
- جديد
- التالي
- العقدة
- عادي
- عدد
- موضوع
- الأجسام
- ONE
- طلب
- أخرى
- وإلا
- الخاصة
- خاص
- مسار
- نفذ
- اختيار
- قطعة
- قطعة
- النائب
- أفلاطون
- الذكاء افلاطون البيانات
- أفلاطون داتا
- البوينت
- منشور
- المنشورات
- يحتمل
- إعداد
- المشكلة
- عملية المعالجة
- إنتاج
- تقدمية
- تنفيذ المشاريع
- وعود
- الملكية
- محمي
- تزود
- ويوفر
- تسحب
- وضع
- سؤال
- الخام
- عرض
- حقيقي
- الحياه الحقيقيه
- واقع
- أحمر
- إعادة توجيه
- بغض النظر
- لا تزال
- تذكر
- إزالة
- أداء
- يجعل
- طلب
- الموارد
- النتائج
- عائد أعلى
- عودة
- عائدات
- العودة
- النوادي الثرية
- جذر
- طريق
- طرق
- يجري
- تشغيل
- نفسه
- حفظ
- رؤية
- يخدم
- طقم
- شادو
- مشاركة
- شاركت
- ينبغي
- إظهار
- الاشارات
- ببساطة
- منذ
- عزباء
- slide
- So
- بعض
- شيء
- مصادر
- أنفق
- بداية
- بدأت
- بقي
- خطوات
- قلة النوم
- تقدم
- الدعم
- المساحة
- نظام
- جدول
- TAG
- أخذ
- مع الأخذ
- حديث
- ترادفيا
- المستهدفة
- يروي
- قالب
- محطة
- •
- الأشياء
- طوال
- الوقت
- عنوان
- إلى
- سويا
- جدا
- أدوات
- رحلات سياحية
- علاج
- صحيح
- منعطف أو دور
- نسخة مطبوعة على الآلة الكاتبة
- ui
- مع
- تحديث
- آخر التحديثات
- URL
- us
- تستخدم
- مستخدم
- قيمنا
- القيم
- مختلف
- بواسطة
- المزيد
- انتظر
- مطلوب
- طرق
- الويب
- مكونات الويب
- تطوير شبكة الويب
- ابحث عن
- التي
- أبيض
- سوف
- كسب
- بدون
- رائع
- للعمل
- أعمال
- قيمة
- سوف
- اكتب
- أنت
- حل متجر العقارات الشامل الخاص بك في جورجيا
- زفيرنت