הבלוג של ינון פרק

טיפים קצרים וחדשות למתכנתים

דוגמת קוד: בדיקת טופס עם yup ב vue

22/12/2024
vue

הדרך הכי קלה היום לעבוד עם טפסים היא לדלג עליהם בספריית ה SPA שלנו, ולהשתמש במאפייני ה HTML ו ValidityState של רכיבי הקלט כדי להציג הודעות למשתמשים. ועדיין לפעמים אנחנו צריכים בדיקות יותר מסובכות או שרוצים להריץ תהליך יותר מסודר סביב הנושא של בדיקות קלט בצד לקוח. במצבים כאלה נוכל להשתמש בספריה כמו yup כדי לתאר את הטופס ובקוד לעדכן את הודעות השגיאה בתוך אפליקציית vue או ריאקט. בואו נראה איך זה עובד.

המשך קריאה

שתי דרכים להרגיע את TypeScript כשמשתמשים ב inject ב vue

05/12/2024
vue

הקוד הזה עובד, אבל גורם לטייפסקריפט לכעוס:

<script setup lang="ts">
import { inject } from 'vue';
import { translations } from './InjectionKeys';

const texts = inject(translations);
</script>

<template>
  <button>{{ texts['click-here'] }}</button>
</template>

הקומפוננטה לוקחת מהקונטקסט את הערך הכי קרוב של המשתנה translations ואז מושכת ממנו את התרגום של הטקסט click-here. אין שגיאות בקונסול ועל המסך הכל נראה תקין. יותר מזה, אם בטעות מישהו שכח לעשות provide ל texts מיד נראה את השגיאה בקונסול כי ננסה לקרוא מפתח מתוך null. אני בסדר עם ההתנהגות הזאת כי אין לי מה לעשות עם המערכת אם אפילו הטקסטים לא נטענו. הבעיה שטייפסקריפט לא יודע את כל מה שאני יודע ומסמן את שורת הכפתור ב template באדום. מה עושים? שתי הצעות-

דרך אחת היא להוסיף בדיקה בקוד הסקריפט אחרי inject:

<script setup lang="ts">
import { inject, ref } from 'vue';
import { translations } from './InjectionKeys';

const texts = inject(translations);
if (!texts) {
  throw new Error("Missing texts in parent component");
}
</script>

<template>
  <button>{{ texts['click-here'] }}</button>
</template>

קיבלנו הודעת שגיאה קצת יותר טובה וטייפסקריפט רגוע. דרך שניה היא להעביר פרמטר שני ל inject שהוא ערך ברירת המחדל:

<script setup lang="ts">
import { inject, ref } from 'vue';
import { translations } from './InjectionKeys';

const texts = inject(translations, ref<Record<string, string>>({}));
</script>

<template>
  <button>{{ texts['click-here'] }}</button>
</template>

פה הקוד יותר קצר שזה נחמד, אבל החיסרון הוא שעכשיו אם מישהו שוכח להעביר את texts מקומפוננטה עליונה יותר לא נראה שגיאה בקונסול אלא רק טקסטים ריקים. כנראה שגם זה לא נורא כי זאת שגיאה שמאוד קל לזהות.

איזה משתי הגישות אתם מעדיפים? או שאולי יש לכם טכניקה אחרת? מוזמנים לספר בתגובות או בטלגרם.

שליטה על Input ב React לעומת Vue

28/11/2024
vue

הקוד הבא ב Vue יכול להטעות:

<script setup lang="ts">
import {ref} from 'vue';

const data = ref('a');

function handleInput(e: any) {
  if (Math.random() * 10 < 2) {
    data.value = e.target.value;
  }
}
</script>


<template>
    <input type="text" @input="handleInput" :value="data" />
</template>

במיוחד אם משווים אותו לקוד מקביל בריאקט:

function App() {
    const [data, setData] = useState('a');
    function handleInput(e) {
        if (Math.random() * 10 < 2) {
            setData(e.target.value);
        }
    }

    return <input type="text" value={data} onChange={handleInput} />
}

גירסת הריאקט תעדכן את הטקסט בתיבה רק ב 20% מהמקרים. בשאר המקרים גם המשתנה data וגם תיבת הטקסט שמופיעה על המסך יישארו מסונכרנים ויציגו את הטקסט הישן. ריאקט יתעלם מהלחיצות.

בגירסת ה vue ההתנהגות שונה: אנחנו עדיין נכנסים לפונקציה ועדיין רק ב 20% מהמקרים נכנסים לבלוק לביצוע של התנאי, אבל הטקסט בתיבה תמיד ישתנה - בלי קשר למצב של המשתנה data. נשים לב ששינוי של data ממקום אחר עדיין יגרום לעדכון של תיבת הטקסט, כלומר בגירסת ה vue אני יכול להוסיף כפתור:

<input type="text" @input="handleInput" :value="data" />
<button @click="data = ''">Reset</button>

ואז לחיצות על הכפתור יאפסו את המשתנה וגם את הטקסט בתיבה. המנגנון הריאקטיבי של Vue אומר שכשיש שינוי במשתנה גם תיבת הטקסט על המסך תעודכן, אבל כשאין שינוי במשתנה לתיבה לא יקרה כלום.

גם הגדרת v-model עם אפשרות לכתיבה תישאר עם אותה התנהגות מבלבלת:

<script setup lang="ts">
import {computed, ref} from 'vue';
const data = ref('a');
const dataModel = computed({
  get() {
    return data.value;
  },
  set(newValue) {
    if (Math.random() * 10 < 2) {
      data.value = newValue;
    }
  }
})

</script>

<template>
  <Todos />
  <input type="text" v-model="dataModel" />
  <button @click="data = ''"></button>
</template>

גם במצב זה ב 20% מהמקרים תהיה כתיבה למשתנה אבל בשאר 80% לא תהיה כתיבה למשתנה והטקסט בתיבת הטקסט יצא מסינכרון, התיבה תציג את הטקסט שנכתב אבל המשתנה לא יכיל אותו.

מה בכל זאת אפשר לעשות? אם אתם רוצים את ההתנהגות של ריאקט תצטרכו לכתוב אותה בעצמכם:

function handleInput(e) {
  if (Math.random() * 10 < 2) {
    data.value = e.target.value;
  } else {
    e.target.value = data.value;
  }
}

ניסוי Vue - משיכת מידע מקומפוננטה אסינכרונית

22/10/2024
vue

בדומה לריאקט גם ויו כבר תומך בקומפוננטות אסינכרוניות ואצלם כרגיל התחביר יותר פשוט ממה שאנחנו מכירים מריאקט. במקום להוסיף פונקציה סודית שמקבלת Promise, הם פשוט מאפשרים לכתוב את setup בצורה אסינכרונית. עשיתי ניסוי עם קומפוננטה פשוטה כדי לראות איך זה עובד. התוצאה בלינק:

https://asyncvue-nr26xan9r48q.deno.dev/

המשך קריאה