ابتعد عن jQuery إلى Svelte ، كما كانت

تحية للجميع.

هذا استمرار لمقال " الابتعاد عن jQuery إلى Svelte ، لا ألم ."

أدناه سأتحدث عن الصعوبات التي واجهتها ، لم يكن هناك الكثير منها ، وواحد فقط كان أساسيًا جدًا حيث لم أتمكن من التأقلم بدون دعم المجتمع .

المقدمة


لقد خططت لإعادة كتابة الواجهة الأمامية على شكل قطع ، وهذا ليس شيئًا لن ينجح على الإطلاق ، ولم ينجح تمامًا - كان علي إعادة الكتابة بالقطع الكبيرة.

أولاً ، نظرًا لأن نهج jQuery أمر حتمي ، فإن نهج Svelte هو إعلاني.

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

مع Svelte ، نحصل على OOP حقيقي: لا يمكننا إجراء تغييرات بأنفسنا ، يمكننا فقط إخبار المكون عن الحاجة إلى التغييرات. كيف سيتم إجراء هذه التغييرات ، لا يعرف سوى الرمز الموجود داخل المكون.

وهذا رائع :)

لدى Svelte آليتان للتواصل مع المكونات.

متغيرات ملزمة (ربط ورسم خرائط)


نعلن متغيرًا ونعينه إلى سمة المكون:

<script>
    import DetailTaskView from './DetailTaskView.svelte';
    let task = {};
    let isModal = false;
    function renderTask(data) {
        const isSuccess = data.hasOwnProperty(0);
        if (isSuccess) {
            isModal = true;
            task = data[0];
        }
    }
    import {fade} from 'svelte/transition';
</script>
{#if isModal}
    <div transition:fade>
        <DetailTaskView bind:isModal="{isModal}" {...task}/>
    </div>
{/if}

ماذا فعلنا؟


أعلنا عن متغيرين محليين "مهمة" و "isModal" ، و "مهمة" هي المعلومات التي سيتم عرضها في المكون ، ولا يتم عرض البيانات إلا ، ولن يتم تغييرها ، "isModal" هي علامة رؤية المكون ، إذا نقر المستخدم على الصليب في المكون ، فيجب أن يختفي المكون ، ينتمي الصليب إلى المكون ، لذلك لا نعرف أي شيء عن النقرة ، ولكننا نعلم أن قيمة المتغير "isModal" قد تغيرت وبفضل التفاعل ، سنعمل على تحديد هذه القيمة الجديدة.

إذا كنا بحاجة إلى ربط ثنائي الاتجاه ، فعندئذ نكتب "bind:" ، وسيتم إبلاغ المكون "الأصل" عن تغيير في القيمة داخل المكون.

يمكننا استخدام نموذج مختصر إذا أردنا فقط إخبار المكون بالقيم ، وإذا كان اسم سمة المكون يطابق اسم المتغير ، يمكننا كتابة "{مهمة}" أو استخدام المدمر "{... مهمة}".

ملائم.

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

فقاعات الحدث


قد أكون مخطئا في المصطلحات ، لا ركلة الكثير.

يمكن للمكون الأصل التعامل مع أحداث المكون الفرعي ، ولكن فقط الأحداث التي يبلغ عنها المكون الفرعي.

<!-- App.svelte   -->
<script>
    import SearchForm from './SearchForm.svelte';
    async function applySample(event) {
        const sample = event.detail.sample;
        if(sample){
            search(sample);
        }
        if(!sample){
            renderPage();
        }
    }
</script>
<div class="container">
    <h1>  </h1>
    <SearchForm on:search={applySample}/>
</div>

<!-- SearchForm.svelte    -->
<script>
	import { createEventDispatcher } from 'svelte';
	const dispatch = createEventDispatcher();
	let sample = '';
    function search(event) {
        event.preventDefault();
        dispatch('search', {
            sample: sample
        });
    }
</script>
<form class="form-horizontal" id="search"
on:submit={search}>
    <div class="form-group">
        <label class="control-label col-sm-2" for="sample">
        
        </label>
        <div class="col-sm-10">
            <input id="sample" class="form-control" type="search"
             placeholder="  "
             autocomplete="on" bind:value={sample}
             />
        </div>
    </div>
</form>

ماذا يجري هنا ؟


في المكون الرئيسي ، يتم تنفيذ الوظيفة "applicationSample" بواسطة الحدث "on: search" للمكون الفرعي "SearchForm" ، وتتلقى هذه الوظيفة المعلمات (event.detail) من كائن الحدث وتعالجها.

ماذا يحدث في مكون؟


يتم تعيين سمة "القيمة" لعنصر الإدخال إلى متغير "العينة" ، عن طريق الحدث "on: Submit" (لعنصر "النموذج") ، ويتم تنفيذ وظيفة "البحث" ، والتي ترفع حدث "البحث" وتكتب {sample: sample object إلى خاصية "التفاصيل" } - أي قيمة سلسلة البحث.

وبالتالي ، يتم تمرير قيمة سلسلة البحث إلى المكون الأصلي وهو الذي يقرر ماذا يفعل بهذه القيمة.

المكون مسؤول فقط عن عرض نموذج الإدخال وإرسال القيمة المدخلة ، ولا يقوم المكون بتنفيذ البحث وعرض النتائج ، لذلك نتشارك المسؤولية.

الجمال!

الانتقال من إلزامي إلى إلزامي


هنا ، لسوء الحظ ، لا يعمل لإظهار الفرق بنفس الوضوح. في الكلمات ، يبدو الأمر كما يلي: إذا ، عند استخدام jQuery ، أنشأت ترميز html ثم أدرجته في المكان الصحيح ، ثم باستخدام Svelte أقوم بإنشاء مصفوفة بسمات المكونات ثم في الحلقة أقوم بإضافة المكونات بسمات محسوبة مسبقًا:

<!-- Paging.svelte        -->
<script>
    import {createEventDispatcher} from 'svelte';
    import OrdinalPlace from './OrdinalPlace.svelte';
    let pagingPlaces;
    //         pagingPlaces
    function addPlace(
        paging = [], index = Number.NEGATIVE_INFINITY,
        text = "", css = "") {
        paging.push({index:index,text:text,css:css});

        return paging;
    }
    const dispatch = createEventDispatcher();
    function browsePage(event) {
        const pageIndex = event.detail.index;
        dispatch('move', {
            index: pageIndex
        });
    }
</script>

{#if pagingPlaces.length}
    <table class = "table table-hover-cells table-bordered">
        <tbody>
            <tr>
            {#each pagingPlaces as place (place.index)}
                <OrdinalPlace on:move="{browsePage}"
                {...place}>
                </OrdinalPlace>
            {/each}
            </tr>
        </tbody>
    </table>
{/if}

<!-- OrdinalPlace.svelte     ""      -->
<script>
    export let index = -1;
    export let text = "";
    export let css = "";

    let number = index +1;
    function skip() {
        return !(text === "");
    }

    let letSkip = skip();
    let noSkip = !letSkip;

    import { createEventDispatcher } from "svelte";
    const dispatch = createEventDispatcher();
    function moveTo() {
        if(noSkip){
            dispatch("move", {index:index});
        }
    }
</script>
<td class="{css}" on:click="{moveTo}">
    {#if letSkip}
        {text}
    {/if}
    {#if noSkip}
        {number}
    {/if}
</td>

كيف تعمل ؟


عند إنشاء مكون الترحيل ، نقوم بتشكيل مجموعة من "العناصر" للانتقال إلى صفحات معينة - "pagingPlaces" ، ثم التنقل بين جميع العناصر وإدراج مكون لعرض موضع ترحيل واحد - "OrdinalPlace".

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

هنا نرى حالة مربكة لحدث الصعود. للانتقال إلى صفحة نتائج البحث ، ينقر المستخدم على مكون "OrdinalPlace" ، ولا يمكن لهذا المكون تحميل الصفحة ، وبالتالي يقوم بإنشاء حدث "نقل" بمعلمة فهرس الصفحة ، ويختار هذا الحدث المكون الرئيسي - "الترحيل" ، والذي لا يمكنه أيضًا تحميل الصفحة وبالتالي فإنه يثير الحدث "نقل" ، والمكون الأصل التالي يلتقطها بالفعل ويعالجها بطريقة أو بأخرى.

يدفعنا Svelte ومنهج المكون إلى مشاركة المسؤولية واتباع SOLID.

أكبر كمين


يوضح المثال أعلاه حلاً لمشكلة أساسية لن أتمكن من معالجتها بدون تلميح. يقوم Svelte بتخزين جميع المكونات مؤقتًا وتحتاج إلى مساعدته على تتبع التغييرات في هذه المكونات.

إليك الرمز المعني:

            {#each pagingPlaces as place (place.index)}
                <OrdinalPlace on:move="{browsePage}"
                {...place}>
                </OrdinalPlace>
            {/each}

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

عند العمل مع المصفوفات ، ضع في اعتبارك أن أي تمريرة عبر الصفيف يجب أن تستخدم فهرسًا ، مرة أخرى:

            {#each pagingPlaces as place (place.index)}

"PagingPlaces كمكان (place.index)" - تأكد من استخدامه.

بالطبع ، إذا كنت قد عملت سابقًا مع React / Vue ، فربما تكون على دراية بهذه الميزة بالفعل.

تأثيرات بصرية


استخدم تطبيقي نوافذ مشروطة. يقوم jQuery لهذا بتعيين متطلبات الترميز ، بدونها ، لن تعمل طريقة jQuery.modal ().

Svelte يجعل هذا أسهل:

{#if isModal}
    <div transition:fade>
        <DetailTaskView bind:isModal="{isModal}" {...task}/>
    </div>
{/if}

على وجه التحديد ، "الانتقال: تلاشي" مسؤول عن اختفاء / ظهور العناصر على الصفحة.
لا أحد يملي علينا الترميز الذي يجب أن نحصل عليه.

إنه جيد.

بالإضافة إلى هذه الرسوم المتحركة ، يحتوي Svelte على زوجين آخرين: fly and tweened ، أمثلة من الروابط في البرنامج التعليمي.

آخر


أسماء متغيرة


مشكلة تسمية المتغيرات / المعلمات / السمات ، يجب عليك استخدام كلمة واحدة للاتصال بكل من خاصية الكائن والمتغير الذي تكتبه هناك ، وقاعدة الهاتف عندما تحتاج إلى التحدث عن الرمز على الهاتف ، حتى لا تخلط بين هذه الغاية وتفهم كل شيء ، مثل الأسماء المتكررة تنتهك.

أياكس


لا ينطبق هذا على Svelte ، ولكن يتعلق برفض استخدام jQuery ، يمكن استبدال jQuery.ajax بـ fetch () ، لقد قمت بهذا الاستبدال ، يمكنك رؤيته في المستودع.

استنتاج


سيتطلب الانتقال من استخدام jQuery إلى استخدام Svelte إعادة كتابة المنطق لإنشاء الترميز ، ولكنه ليس صعبًا وطالما قد يبدو ، خاصة إذا لم تخطأ التعليمات البرمجية بهذا.

يبسط Svelte ترميزك ويقصر كود JS ، باستخدام Svelte يجعل الشفرة الخاصة بك أكثر قابلية لإعادة الاستخدام ومقاومة للأخطاء العشوائية.

استخدم Svelte ، سيكون جيدًا لك ولعملائك!

المراجع


الموقع الرسمي لـ Svelte
Repository مع الانتقال من استخدام jQuery إلى استخدام
قناة Svelte من المجتمع الناطق باللغة الروسية Svelte في Telegram

شكرًا لك على القراءة.

ملاحظة: لا أعرف لماذا يستثني هبر القولون من رابط القناة المجتمعية ، فخط الارتباط الصحيح هو: tg: // Resolution؟ Domain = sveltejs

All Articles