-
المساهمات
971 -
تاريخ الانضمام
-
تاريخ آخر زيارة
-
عدد الأيام التي تصدر بها
1
نوع المحتوى
ريادة الأعمال
البرمجة
التصميم
DevOps
التسويق والمبيعات
العمل الحر
البرامج والتطبيقات
آخر التحديثات
قصص نجاح
أسئلة وأجوبة
كتب
دورات
كل منشورات العضو Mustafa Mahmoud7
-
هذا الخطأ سببه أن كل ما يوضع داخل <Routes> لابد أن يكون <Route> فقط أو <React.Fragment> يحتوي فقط على <Route> لكن لاحظ أنك وضعت داخله <Background /> ، <Hero /> بشكل مباشر وهذا غير مسموح. لهذا قم بنقل <Background /> خارج <Routes> لأنه ليس مسار (Routes) بل مكون أعتقد تريد أن يظهر دائما في كل الصفحات ولاحظ عند استخدام المكون Hero لابد من إرسال الخواص التي يريدها heroData ، heroCount، playStatus، setHeroCount ، setPlayStatus فهي ضرورية لكي يظهر المكون Hero بصورة صحيحة. ليصبح الكود بعد التعديل كالتالي <> <div> <BrowserRouter> <Navbar /> <Routes> <Route path="/Hero" element={ <Hero heroData={heroData[heroCount]} heroCount={heroCount} playStatus={playStatus} setHeroCount={setHeroCount} setPlayStatus={setPlayStatus} /> } /> </Routes> {/* هذا العنصر يجب أن يكون خارج <Routes> */} <Background playStatus={playStatus} heroCount={heroCount} /> </BrowserRouter> </div> </>
-
يمكنك عمل مكون خاص AppRouter بهذه العملية ليكون مستقل بذاته لهذا الأمر كالتالي import { BrowserRouter, Routes, Route } from "react-router"; import Home from "./pages/Home"; import About from "./pages/About"; import Contact from "./pages/Contact"; export default function AppRouter() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> </BrowserRouter> ); } ثم استخدامه بداخل App.js كالتالي import { Link } from "react-router"; import AppRouter from "./router"; export default function App() { return ( <> <nav> <Link to="/">Home</Link> <Link to="/about">About</Link> <Link to="/contact">Contact</Link> </nav> <AppRouter /> </> ); } أو يوجد طريقة أخرى متاحة يمكنك استخدامه أيضا ليكون المكون AppRouter كالتالي mport { createBrowserRouter, RouterProvider } from "react-router"; import Home from "./pages"; import About from "./pages/about"; import Contact from "./pages/Contact"; const router = createBrowserRouter([ { path: "/", element: <Home />, }, { path: "/about", element: <About />, }, { path: "/contact", element: <Contact />, }, ]); export default function AppRouter() { return <RouterProvider router={router} />; } واستخدام المكون AppRouter بداخل App.js كالتالي import { Link } from "react-router"; import AppRouter from "./router"; export default function App() { return ( <> <nav> <Link to="/">Home</Link> <Link to="/about">About</Link> <Link to="/contact">Contact</Link> </nav> <AppRouter /> </> ); } الطريقتان متاحتان يمكنك اختيار أي منهم.
-
لعمل صفحات أخرى وتحويل التطبيق إلى SPA سنقوم باستخدام مكتبة react-router وهي المسؤولة عن إدارة التوجيه بداخل التطبيق. تثبيت المكتبة عن طريق الأمر npm i react-router وفي المكون App لديك نقوم باستخدام المكتبة كالتالي import { BrowserRouter, Routes, Route,Link } from "react-router"; import Home from "./pages/Home"; import About from "./pages/About"; import Contact from "./pages/Contact"; function App() { return ( <BrowserRouter> <nav> <Link to="/">Home</Link> <Link to="/about">About</Link> <Link to="/contact">Contact</Link> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> </BrowserRouter> ); } سيتطلب الأمر منك بالطبع إنشاء المكونات التي هي عبارة عن صفحة وهي Home ،ِ About , Contact. صفحة Home.jsx export default function Home() { return <h1>Home Page</h1>; } صفحة About.jsx export default function About() { return <h1>About Page</h1>; } صفحة Contact.jsx export default function Contact() { return <h1>Contact Page</h1>; } سيظهر لديك في الصفحة navbar وبه الروابط للصفحات واستخدام المكون Link هذا بديل محسن من anchor tag (<a>) مع استخدام to بدلا من href للإنتقال للصفحة بدون عمل إعادة تحميل للصفحة فقط الإنتقال للصفحة. لابد أن يكون المسار الذي تريد الذهاب له "to="/about يجب أن يكون مطابق حرفيا لـ "path="/about في <Route> حتى يتم تحميل الصفحة about بنجاح. يمكن قراءة المزيد حول react-router
-
أولا بما أنك تعمل على مشروع عبارة عن صفحة واحدة هل هناك هدف لتغيير العنوان حيث تذكر بعد ذلك أنه لديك أكثر من صفحة. أفترض انك لديك مشروع رياكت عبارة عن SPA وقمت بتثبيت مكتبة react-router من خلالها تستطيع التنقل بين الصفحات. في تطبيقات React التي هي عبارة عن صفحة واحدة (Single Page Application) فعلا بيكون عندك ملف index.html واحد فقط وذلك معناه إن عنوان الصفحة (<title>) لا يتغير تلقائي عندما تنتقل بين الصفحات (Routes) لأنه لا يوجد reload بيحصل للصفحة. لذلك الحل هو إنك تغير العنوان يدويا من داخل React. تستطيع كل صفحة تغير عنوانها بنفسها كالتالي import { useEffect } from "react"; function Page1() { useEffect(() => { document.title = "Page 1"; }, []); return ( <div> <h1>Page 1</h1> {/* باقي المكونات */} </div> ) } وهكذا في باقي الصفحات كل واحدة منهم تقوم بكتابة العنوان الخاص بها في useEffect. تستطيع أيضا تحديد العنوان تلقائيا حسب الرابط (URL) لو الروابط عندك واضحة مثل (about أو contact/) يمكن عمل مكون صغير مسؤول عن تحديث العنوان تلقائي حسب الصفحة كالتالي 1. ملف فيه العناوين: // pageTitles.js const pageTitles = { "/": "الصفحة الرئيسية", "/about": "من نحن", "/contact": "اتصل بنا", }; export default pageTitles; 2. مكون PageTitleUpdater: import { useEffect } from "react"; import { useLocation } from "react-router-dom"; import pageTitles from "./pageTitles"; function PageTitleUpdater() { const location = useLocation(); useEffect(() => { const title = pageTitles[location.pathname] || "تطبيقي"; document.title = title; }, [location.pathname]); return null; } useLocation هو hook من React Router يعطي لك المعلومات عن الرابط الحالي في المتصفح. 2. تستخدم المكون PageTitleUpdater في ملف App: import { BrowserRouter, Routes, Route } from "react-router-dom"; import Home from "./pages/Home"; import About from "./pages/About"; import Contact from "./pages/Contact"; import PageTitleUpdater from "./PageTitleUpdater"; function App() { return ( <BrowserRouter> <PageTitleUpdater /> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> </BrowserRouter> ); } بالإضافة لذلك طبعا يمكنك استخدام مكتبة react-helmet كما ذكر لك محمد في التعليق السابق لهذا الأمر.
-
هذا الخطأ يخبرك أنك تقوم بمحاول الوصول للثابت todos في سطر 15 وهذا الثابت قبل ما يتم تعريفه أو تهيئته (initialization). لذلك يرجى نقل عملية استخدام الـ todos ومحاولة الوصول لقيمته أسفل عملية التعريف له. فمثلا في هذا الكود const handelButtonClick = () => { const text = inpRef.current.value; const newTodos = {complelted: false ,text} setTodos([...todos, newTodos]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ inpRef.current.value = ''; } const [todos , setTodos] = useState([]); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ هذا الكود ليس بالظبط في أكوادك التي أرسلتها سابقا فقط لبيان كيف يمكن أن يحدث هذا الخطأ سيظهر معك هذا الخطأ Cannot access 'todos' before initialization لأنك بتحاول تستخدم حاجة لسه ما اتعرفتش. وتصحيح هذا الكود يكون كالأتي const [todos , setTodos] = useState([]); const handelButtonClick = () => { const text = inpRef.current.value; const newTodos = {complelted: false ,text} setTodos([...todos, newTodos]) inpRef.current.value = ''; } لذلك قم بالبحث عن السطر الذي قم فيه بتعريف todos وانقله قبل السطر رقم 15 والتجربة مرة أخرى.
-
خطأ غريب حيث قمت باختبار الكود عدة مرات سواء بإعادة التحميل للتطبيق أو الإضافة أو الحذف ولا يظهر هذا الخطأ لدي. أرجو أيضا تفريغ الـ localStorage من البيانات الموجودة به ربما هناك بيانات قديمة مخزنة به تحت المفتاح todos أيضا. من الممكن أن يكون هناك إضافة لديك في المتصفح تؤدي إلى ذلك الخطأ لذا يرجى تشغيل التطبيق في المتصفح الخفي وإعادة المحاولة. وأرجو أيضا استبدال هذا السطر return <div className="item"><li className={complelted ? "done" : ""} onClick={() => handelItemClick(i)}>{text}</li><span onClick={() => handelDeleteItem(i)}>❌</span></div> بالتالي return ( <div className="item" key={i}> <li className={complelted ? "done" : ""} onClick={() => handelItemClick(i)} > {text} </li> <span onClick={() => handelDeleteItem(i)}>❌</span> </div> ); قمنا بإضافة الـ key للـ div وهو مهم عند العمل مع map في react. من المفترض ألا تظهر معك أي أخطاء في الـ console أو تحذيرات ويعمل معك التطبيق بدون مشكلة.
-
إذا كان هذا التطبيق خاص بأحد دروس الدورة ستجد أسفل فيديو الدرس في نهاية الصفحة صندوق تعليقات كما هنا، أرجو طرح الأسئلة أسفل الدرس وليس هنا في قسم أسئلة البرمجة حيث نطرح الأسئلة العامة الغير متعلقة بمحتوى الدورة أو الدرس، وذلك لمساعدتك بشكل أفضل. لكي يتم حفظ البيانات في التخزين المحلي (localStorage) وتستمر بعد ما يتم إعادة تحميل الصفحة، لابد أن نستخدم localStorage مع useEffect فالمطلوب كالأتي عند تشغيل التطبيق لأول مرة: نقرأ المهام من localStorage. عند تغيير المهام (todos): نقوم بتحديث localStorage ونضيف المهام المحدثة به. لهذا الأمر عليك بإضافة التالي إلى الكود الخاص بك // قراءة البيانات من التخزين المحلي عند تحميل الصفحة أول مرة useEffect(() => { const storedTodos = localStorage.getItem("todos"); if (storedTodos) { setTodos(JSON.parse(storedTodos)); } }, []); // حفظ المهام في التخزين المحلي عند كل تغيير في القائمة useEffect(() => { localStorage.setItem("todos", JSON.stringify(todos)); }, [todos]); في الـ useEffect الأولي يتم التالي هذا الكود بداخل useEffect يعمل مرة واحدة فقط عند تحميل المكون APP بسبب [] في النهاية. يقوم بالبحث في localStorage عن شيء محفوظ باسم المفتاح todos. إذا وجده نحوله من نص إلى مصفوفة باستخدام ()JSON.parse ثم نخزنها داخل todos باستخدام ()setTodos. في الـ useEffect الثانية يتم التالي هذا الكود بداخل useEffect يعمل في كل مرة تتغير فيها المهام todos بسبب [todos]. يقوم بتحويل المهام إلى نص باستخدام ()JSON.stringify ثم يقوم بحفظ هذا النص داخل localStorage باسم المفتاح todos.
-
نعم لا يزال استخدام الـ Dom أساسيا في تطوير تطبيقات الويب حتى وإن لم يتعامل المطور معه بشكل مباشر في أطر العمل الحديثة مثل React أو Angular أو Vue فإن هذه الأطر تعتمد عليه داخليا للتفاعل مع الصفحة وعرض المحتوى. فهم كيفية عمل الـ DOM يظل مهما لأي مطور لأنه يمثل الأساس الذي تبنى عليه واجهات المستخدم في الويب. في المشاريع البسيطة ذات صفحة واحدة (Single Page) أو التي لا تتطلب تفاعلات كثيرة يمكن استخدام DOM مباشر بدون الحاجة إلى إطار عمل ثقيل لتقليل حجم الملفات وتحسين الأداء. أما في المشاريع الكبيرة والتي تحتوي على العديد من الصفحات وتحتاج إلى تفاعل ديناميكي كبير مع الواجهة وإدارة حالة معقدة يصبح من العملي استخدام أطر العمل الحديثة التي تسهل التحكم في DOM بطريقة منظمة وسريعة. لذلك استخدام DOM ليس قديما بل هو جزء لا يتجزأ من كل تطبيق ويب ولكن طريقة التعامل معه تطورت فمعرفتك لكيفية التعامل مع الـ Dom وما يتم داخليا يسهل عليك الكثير وتفهم ما يدور داخليا في أطر العمل.
-
من الأفضل لك في الوقت الحالي التركيز على ريأكت و JSX وكيفية إدارة الحالة بها ومعرفة دورة حياة المكون في رياكت وعمل تطبيق بسيط ثم محاولة تعلم MUI حتى لا يصيبك التشتت والكثير من المعلومات التركيز الأكبر على إطار العمل React واستخدام CSS معه كافي جدا للتطبيق على مفاهيم رياكت.
- 5 اجابة
-
- 1
-
-
MUI هي مكتبة واجهات مستخدم (UI) مبنية باستخدام React وتستند إلى تصميم Material Design من Google. توفر مجموعة من المكونات الجاهزة مثل الأزرار، حقول الإدخال، الجداول، النوافذ المنبثقة وغيرها. استخدام MUI يوفر الكثير من الوقت والجهد بدلًا من بناء كل المكونات من الصفر، كما أنه يساعدك على تصميم واجهات أنيقة ومتناسقة بسرعة. كما أن هذه المكونات قابلة للتخصيص حسب الحاجة وتوفر دعما قويا للتصميم المتجاوب (Responsive Design) وإمكانيات التخصيص عبر الـ Themes. MUI ليست مجرد تنسيق CSS فقط بل هي مكتبة كاملة للمكونات التفاعلية أي ليست مكونات تم تنسيقها عن طريق CSS ولكن بها بها تنسيق ومنطق برمجي، فهي توفر لك كل ما تحتاجه لبناء واجهات احترافية بسرعة في مشاريع React وتشمل تصميم، منطق تفاعل، تخصيص.
-
ستجد أسفل فيديو الدرس صندوق للتعليقات كما هنا يرجى طرح سؤالك أسفل الدرس وليس هنا حيث هنا قسم الأسئلة العامة ولا نقوم بإجابة الأسئلة الخاصة بمحتوى الدورة أو الدرس، وذلك لمعرفة الدرس الذي توجد به مشكلتك و لمساعدتك بشكل أفضل. عند تثبيت بايثون على نظام ويندوز يتم تثبيت برنامج IDLE وهو يشمل بداخله ما يُعرف بـ Python Shell. Python Shell هو نفسه النافذة التفاعلية التي تظهر عند فتح IDLE وتبدأ بالسطر: Python 3.x.x (...) on win32 Type "help", "copyright", ... >>> إذا ظهرت لك هذه النافذة عند فتح IDLE فاعلم أن Python Shell مثبت ويعمل بشكل صحيح. يمكنك تجربة كتابة أمر بسيط مثل: print("Hello, Python!") ثم Enter وستظهر لك النتيجة فورا وهذا دليل على أن كل شيء يعمل بدون مشكلة. إذا واجهتك مشكلة معينة فيرجى توضيحها أكثر تحت الفيديو الذي تقصده لمساعدتك بشكل أفضل.
-
سبب ظهور هذا الأمر يرجع إلى أن الـ navbar المساحة له في الشاشات الصغيرة لم تعد كافية للمحتوى لذلك في هذه الشاشات نقوم بجعل قائمة الروابط أسفل شعار الموقع لذلك في ملف components\GymNav.vue نقوم بتعديل ترتيب العناصر لتصبح عمودية لجعل قائمة الروابط أسفل شعار الموقع لتصبح الأكواد الخاص بالشاشة الصغيرة التي أقل من 768px كالتالي @media(max-width: 778px){ .logo{ display: none; } .links{ margin-left: 30px; } .navbar{ flex-direction:column; } } أضفنا ;flex-direction:column للعنصر الذي لديه الصنف navabar. لجعل إتجاه العناصر عموديا أي تحت بعضهم البعض حيث السلوك الافتراضي لـ ;display:flex هو جعل اتجاه ترتيب العناصر أفقيا أي بجانب بعضهم البعض لذلك قمنا بتعديله.
-
الدورات لا يتم تحديثها بالكامل دفعة واحدة، بل يتم تحديثها بشكل تدريجي من خلال: إضافة مسارات جديدة لمواكبة سوق العمل وما به من متطلبات جديدة. استبدال مسارات قديمة بمسارات أحدث حسب الحاجة. لذلك يمكنك البدء بمشاهدة المحتوى الحالي مباشرة فهو يمثل آخر تحديث متاح للدورة حتى الآن. بخصوص التحديثات القادمة على الدورة دورة تطوير واجهات المستخدم يتم تحديثها بشكل دوري وفقا لمتطلبات سوق العمل وتطور التقنيات الحديثة لكن لا يوجد موعد محدد للتحديثات. يمكنك دائما متابعة التحديثات الجديدة لجميع الدورات من خلال صفحة آخر التحديثات على الرابط التالي: https://academy.hsoub.com/release-notes
- 1 جواب
-
- 1
-
-
لتنسيق المشروع في الشاشات الصغيرة من المهم جدا استخدام الـ media queries لكي تستطيع تطبيق بعض الخصائص والتسيقات في أحجام شاشة معينة لذلك يرجى الإطلاع على هذه المقالة تبين لك كيفية تنفيذ ذلك بعد ذلك لجعل التطبيق الخاص بك متجاوب في الشاشات التي أقل من 768px أولا علينا إضافة تغليف للجدول في ملف index.html فهو ما يخرب الصفحة فبدلا من <table> <tr> <th>id</th> <th>title</th> <th>price</th> <th>taxes</th> <th>ads</th> <th>discount</th> <th>total</th> <th>category</th> <th>update</th> <th>delete</th> </tr> <tbody id="tbody"> </tbody> </table> نضيف التغليف ليصبح <div class="table-responsive"> <table> <tr> <th>id</th> <th>title</th> <th>price</th> <th>taxes</th> <th>ads</th> <th>discount</th> <th>total</th> <th>category</th> <th>update</th> <th>delete</th> </tr> <tbody id="tbody"> </tbody> </table> </div> بعد ذلك في ملف style.css سطر 78 .searchBlock { width: 90%; margin-left: 60px; ^^^^^^^^^^^^^^^^^^^^^^^^ } نعدل هذا العنصر ليتوسط أفقيا بالعرض %90 كالتالي .searchBlock { width: 90%; margin:0 auto; } وفي نفس الملف أيضا نضيف هذه التنسيقات /* 1. غلف الجدول بحاوية متجاوبة */ .table-responsive { overflow-x: auto; /* اجعل الحاوية قابلة للتمرير أفقيًا عند ضيق الشاشة */ margin: 10px 0; /* مسافة رأسية بسيطة فوق وتحت الجدول */ } /* 2. اجعل عرض الجدول يملأ الحاوية */ .table-responsive table { width: 100%; /* الجدول يملأ عرض الحاوية بالكامل */ min-width: 600px; /* الحد الأدنى لعرض الجدول حتى لا ينهار */ } /* 3. تخصيص عناصر البحث والشكل العام تحت 768px */ @media (max-width: 768px) { .price { text-align: center; /* يوسّط النصوص والعناصر داخل حاوية السعر أفقياً */ } .price input { width: 48%; /* مدخلات السعر تظهر اثنين في كل صف */ } #total { margin: 6px 0; /* يضيف مسافة رأسية بسيطة فوق وتحت عرض الإجمالي */ display: inline-block; /* يجعل صندوق الإجمالي يتصرف كعنصر سطري مع الحفاظ على خصائص الكتلة */ } .btnSearch { flex-direction: column; /* ترتيب أزرار البحث بشكل عمودي */ } .btnSearch button { width: 100%; /* الأزرار تملأ العرض بالكامل */ margin-bottom: 6px; /* مسافة تحت كل زر */ } /* تصغير الحشو وحجم الخط في الجدول */ table th, table td { padding: 4px; /* تقليل الحشو لجعل الجدول أكثر اختصارًا */ font-size: 0.9em; /* تصغير حجم الخط قليلًا */ } } ودور هذه الأكواد هو table-responsive. يضيف حاوية قابلة للتمرير الأفقي مع مسافات علوية وسفلية وكود table-responsive table. يجعل الجدول يملأ عرض الحاوية بالكامل ويمنع انضغاطه لأقل من 600px، وأخيراً في @media (max-width: 768px) تجد تعديلات على مدخلات السعر لتظهر اثنين في الصف، وترتيب أزرار البحث عموديا مع ملء العرض لكل زر وإضافة مسافة رأسية بسيطة فوق وتحت عرض الإجمالي وترتيب الحشو وحجم الخط في خلايا الجدول وكل سطر مكتوب أمامه تعليق يفسر وظيفته. وهذه هي الملفات بعد التعديل index.html style.css
-
Electron.js هو إطار عمل برمجي يُستخدم في تطوير تطبيقات سطح المكتب التي تعمل على مختلف أنظمة التشغيل وتبدو وكأنها تطبيقات أصلية (native-feeling) لكنها في الأساس تعتمد على تقنيات الويب المعروفة مثل HTML وCSS وJavaScript. الإطار يستفيد من متصفح Chromium المفتوح المصدر لعرض واجهات المستخدم بحيث تظهر وكأنها صفحة ويب داخل نافذة التطبيق وفي نفس الوقت يستخدم Node.js للتعامل مع نظام الملفات المحلي والنظام بشكل عام. وبفضل هذا الدمج يمكن تشغيل التطبيقات بسلاسة على جميع أنظمة التشغيل مثل ويندوز، لينكس، وماك. ومن أشهر الأمثلة على تطبيقات سطح المكتب التي تم تطويرها باستخدام Electron: تطبيق Slack للتواصل بين فرق العمل. تطبيق Figma لتصميم واجهات المستخدم. أما مدى احتياجك لـ Electron.js من عدمه يعتمد هل في المستقبل سوف تحتاج إلى تطوير تطبيقات سطح مكتب أم لا وبالنسبة للشركات تعلمك له بالطبع يعتبر مهارة إضافية تعزز من فرصك للقبول في الوظائف التي تحتاج استخدامه أو بتشتغل على تطبيقات سطح مكتب مبنية بتقنيات الويب. في النهاية هو إطار مبني يستخدم HTML وCSS وJavaScript فلو أنت بالفعل متقن لهذه الأساسيات ستجد تعلمه بسيط وسهل عليك بإذن الله.
-
لرفع المشروع على netify في البداية عليك بالقيام بعملية البناء للمشروع عن طريق فتح الـ terminal ووضع الأمر npm run build ثم enter ستلاحظ إنشاء مجلد جديد باسم dist هذا المجلد يحتوي على نسخة المشروع الجاهزة للنشر. بعد ذلك نريد رفع إلى netlify الخطوات: افتح موقع https://app.netlify.com سجل دخول بحسابك أو أنشئ حساب جديد. من لوحة التحكم، اضغط على زر Add new site → ثم Deploy manually. اسحب مجلد dist من جهازك وافلته داخل المربع. انتظر لحظات وسيتم رفع المجلد ونشر المشروع. بعد النشر Netlify تستطيع فتح الموقع من خلال الضغط على الزر Open production deploy ستلاحظ فتح الموقع في تبويب جديد. ويوجد مقالة أيضا تتحدث عن رفع مشاريع vue ولكن عن طريق ربط المستودع للمشروع على github بموقع netlify تستطيع الإطلاع عليها
-
في ملف MyMain.vue يجب تضمين جميع التنسيقات الخاصة بالشاشات الصغيرة داخل البلوك الخاص بـ media@ لاحظ أنك قمت بإغلاق القوس { للبلوك media@ مبكرا في سطر 322 @media(max-width: 778px){ .my-main{ display: flex; flex-direction: column; text-align: center; justify-content: center; } } ^^^^^^^^ .cards{ display: flex; flex-wrap: wrap; .card{ width: 100%; } } لذلك باقي التنسيقات (cards, .skills, .prog.) لا تحتسب ضمن الشاشات الصغيرة وتم تطبيقها على جميع الشاشات بدلا من الشاشات الصغيرة فقط. لذلك يجب حذف هذا القوس { ووضعه في نهاية التنسيقات ليصبح الكود ب الخاص بـ media@ بعد التعديل كالتالي @media(max-width: 778px){ .my-main { display: flex; flex-direction: column; text-align: center; justify-content: center; } .cards { display: flex; flex-wrap: wrap; .card { width: 100%; } } .skills { display: flex; flex-direction: column; text-align: center; .icons { display: flex; flex-wrap: wrap; margin-top: 10px; gap: 10px; } div { width: 100%; } } .prog { display: flex; flex-wrap: wrap; text-align: center; img { width: 500px; } } }
-
وظيفة هذا الكود هو إعادة ناتج جمع كل العناصر اللي موجودة في المصفوفة myArr ولنفترض لدينا المصفوفة [1, 2, 3, 4] عند استخدام الدالة reduce كالتالي this.myArr.reduce((num1, num2) => num1 + num2) فكرة reduce إنها بتمر على كل عنصر في المصفوفة،وتنفذ عليه عملية (زي الجمع أو الضرب أو أي حاجة) مع ناتج العملية السابقة، وبتفضل تكرر كده لحد ما تختصر المصفوفة لقيمة واحدة بس. في هذا الكود أنت تريد الجمع لو myArr = [1, 2, 3, 4] فـ reduce هتشتغل كالتالي: أول خطوة: 1 + 2 = 3 ثاني خطوة: 3 + 3 = 6 ثالث خطوة: 6 + 4 = 10 وفي الأخر بيرجع 10. يعني السطر ده كله return this.myArr.reduce((num1,num2) => num1 + num2) وظيفته يحسب مجموع كل الأرقام اللي موجودة جوّا المصفوفة myArr ويرجع الناتج. تُستخدم أيضا الدالة ()reduce مع النصوص وأنواع البيانات الأخرى وتكون القيمة المرجعة منها إما رقم أو نص أو أي نوع بيانات أخر. تستطيع المعرفة أكثر عن هذه الدالة في موسوعة حسوب https://wiki.hsoub.com/JavaScript/Array/reduce
-
هذا عبارة عن كائن اسمه methods وتكون بداخله كل الدوال الخاصة بالمكون في Vue.js فلدينا الآن دالة تدعى getProducts وهي دالة غير متزامنة -أي أنها يمكن أن تنتظر أوامر تأخذ وقتا في التنفيذ، مثل جلب البيانات من الإنترنت - وقمنا بجعلها غير متزامنة عن طريقة إضافة async أمام تعريفها لنستطيع بعد ذلك بداخل هذه الدالة استخدام await مع fetch تقوم الدالة fetch بإرسال طلب إلى https://dummyjson.com/products بعد ذلك نقوم باستخدام then لمعرفة الرد الذي حصلنا عليه وبداخل then نقوم بتحويل الرد إلى صيغة نستطيع التعامل معاها بواسطة الدالة ()json لتحويل الرد إلى صيغة JSON (وهي صيغة يمكننا التعامل معها في JavaScript) ثم قمنا باستخدام then مرة أخري واستخدام البيانات العائدة من الطلب واسنادها إلى الخاصية this.products ليتم عرضها بالمكون.
-
وعليكم السلام، استخدام النماذج الذكاء الاصطناعي يعتبر مهم في الوقت الحالي لمعظم المطورين ولكن في مرحلة التعلم وبناء أساس قوي لك في أي لغة أو اطار عمل يفضل الابتعاد عن هذه النماذج، على الأقل لابد من حلك للتاسكات بنفسك ثم إعادة تحسينها بذلك قد تكون استفدت من عملية التعلم وتطوير فهمك ومنطقك البرمجي، وستجد القدرة على حل المشكلات بعد ذلك تتطور مع كثرة حلك لهذه للمشكلات بنفسك. تستطيع بعدها سؤال نماذج الذكاء الاصطناعي على حلول أفضل لنفس المشكلة أو تقييم الحل الخاص بك أو تحسيينه. ولكن إذا قمت بالاعتماد على هذه النماذج في الحل مع الوقت ستجد نفسك غارق في أكواد كثيرة لا تفهمها وما هي نتائجاها على تطبيقاتك قد تؤدي لمشاكل أمنية أو مشاكل في الأداء في تطبيقك وسيكون عليك من الصعب إدارة العديد والعديد من الملفات والأكواد وأنت لا تفهمها بشكل جيد وفي بعض الأوقات هذه النماذج تعطي حلول معقدة والمشكلة لا تحتاج لهذا التعقيد للحل. لذلك عليك التركيز على عملية التعلم وحل التاسكات بنفسك ويمكنك الاستعانة بهذه النماذج لشرح موضوع جديد عليك لا تفهمه من التوثيق الرسمي أو تبسيط للمعلومة وليس حل المشكلات لك. بهذه الطريقة ستستفيد بشكل جيد من هذه النماذج وستكون فاهم بنسبة كبيرة الأكواد التي يقدمها لك وتستطيع تقييم الجيد منها والغير جيد وتأثيره في حل المشكلة أو التطبيق وليس استخدامها بدون فهم جيد لها.
- 3 اجابة
-
- 1
-
-
وعليكم السلام، الدورة ليس لها وقت انتهاء فكل الدورات المقدمة من قبل الأكاديمية ليس لها وقت للإنتهاء وليس عليك إعادة الاشتراك أو التجديد بل الدورة متاحة لك مدى الحياة تستطيع مشاهدتها وطرح الأسئلة التي تريدها في التعليقات، بالإضافة لذلك ستستطيع الوصول لك التحديثات القادمة على الدورة التي قمت بالاشتراك بها حيث الأكاديمية تقوم بتحديث الدورات بشكل دوري وإضافة مسارات جديدة بالدورة أو تحديث المسارات الموجودة لمواكبة أخر التطورات في سوق العمل، هذه التحديثات لا تتطلب منك أي اشتراك جديد أو رسوم إضافية بل هذه التحديثات مجانية بشكل كامل. يمكنك الإطلاع على الميزات التي تقدمها الأكاديمية في الدورات من هنا.
-
الصورة تم رفعها بنجاح على الواجهة الخلفية (الخادم) وهذا يعني أن المشكلة ليست في عملية الرفع بل في طريقة عرض الصورة في الواجهة الأمامية (Frontend). عندما نحصل على اسم الصورة مثل: url-1744329877173-986064634.png فهذا مجرد اسم الملف، وليس رابطا كاملا يمكن من خلاله عرض الصورة. لذلك في ملف مكون BookCards نحتاج إلى تكوين الرابط الكامل للصورة وذلك بإضافة رابط الخادم الذي يحتوي على الصور ثم دمج اسم الصورة معه. مثلاً: const API_URL_IMAGES = 'http://localhost:4000/images'; ثم ندمج هذا الرابط مع اسم الصورة بهذا الشكل: <img src={`${API_URL_IMAGES}/${data.url}`} /> ليكون الرابط النهائي للصورة المطلوب من الخادم هو http://localhost:4000/images/url-1744329877173-986064634.png وبذلك سيتم عرض الصورة بشكل صحيح على الواجهة الامامية. وهذا هو ملف المكون BookCards بالكامل بعد التعديل import React from 'react'; import { Link } from 'react-router-dom'; const API_URL_IMAGES = 'http://localhost:4000/images'; const BookCards = ({ data }) => { console.log(data); return ( <> <Link> <div className="bg-zinc-800 rounded p-4"> <div className="bg-zinc-900"> <img src={`${API_URL_IMAGES}/${data.url}`} className="h-[25vh]" /> </div> <h1>{data.title}</h1> </div> </Link> </> ); }; export default BookCards; ستلاحظ بعد هذا التعديل أن الصورة تظهر بنجاح في الواجهة الأمامية.
- 1 جواب
-
- 1
-
-
الخطأ يخبرك بأن لا يستطيع العثور على الصورة logo.png في هذا المكان لذلك يرجى كتابة مسار الصورة بشكل صحيح أو التأكد من وجود الصورة في src/img/logo.png حيث من المفترض أن تتواجد الصورة. إذا كان هذا السؤال متعلق بأحد الدورات ستجد أسفل فيديو الدرس في نهاية الصفحة صندوق تعليقاتكما هنا، أرجو طرح الأسئلة أسفل الدرس وليس هنا في قسم أسئلة البرمجة حيث نطرح الأسئلة العامة الغير متعلقة بمحتوى الدورة أو الدرس، وذلك لمساعدتك بشكل أفضل.
- 2 اجابة
-
- 1
-