• בלוג
  • מדריך Vue למתחילים - פרק 1 - קומפוננטה ראשונה ב Vue

מדריך Vue למתחילים - פרק 1 - קומפוננטה ראשונה ב Vue

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

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

1. מהו תכנות מבוסס קומפוננטות ולמה זה כדאי

דפי אינטרנט באופן רגיל מורכבים משלוש טכנולוגיות משלימות: HTML, CSS ו JavaScript, וכל טכנולוגיה אחראית על היבט אחר בפונקציונאליות של העמוד. ב HTML אנחנו כותבים את תוכן הדף, ב CSS מעצבים את התוכן הזה וב JavaScript מקודדים את האינטרקציות של הדף עם המשתמש.

מבנה זה מכריח אותנו (או לפחות מאוד מעודד אותנו) להסתכל על העמוד כמכלול - בכתיבת ה CSS להשתמש במה שאנחנו יודעים על ה HTML; בכתיבת ה JavaScript להשתמש במה שאנחנו יודעים על ה HTML וה CSS וכך הלאה. באתרים קטנים זה מאוד נוח כי אפשר להשאיר בראש את מה שקורה בכל מקום באתר ולראות את הקוד כתמונה אחת מרכזית.

ברגע שהאתר גדל העסק מסתבך. באתרים גדולים קוד JavaScript של חלק אחד באתר עלול להפריע לקוד JavaScript של חלק אחר. קוד CSS של רכיב מסוים באתר כתוב בערבוביה עם קוד CSS של כל החלקים האחרים, ואז אם למשל מחקתי מה HTML את גלריית התמונות לא בטוח שאני אזכור למחוק את כללי העיצוב המתאימים לה מה CSS (והרבה פעמים אני פוחד למחוק משם, כי אולי הכללים משפיעים על חלקים אחרים בעמוד).

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

ככל שקוד צד-לקוח הפך גדול ומסובך יותר כך מפתחים וארכיטקטים החלו לחשוב על רעיונות איך להפוך את ההתמודדות עם הקוד לקלה יותר באמצעות הפיכתו למודולרי. אחד הרעיונות הראשונים בתחום זה נקרא MVC והוא דיבר על זה שחלק מהקוד יהיה אחראי על התצוגה וחלק אחר יהיה אחראי על הלוגיקה. אבל MVC ברוב המקרים רק הפך את הקוד ליותר מסובך ולא הצליח להתמודד עם האופי המודולארי של פיתוח ממשק משתמש וספציפית של השילוב בין שלוש הטכנולוגיות השונות. רוב ה MVC Frameworks התמקדו רק ב JavaScript וניסו לבטל לחלוטין את ה HTML וה CSS.

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

קומפוננטה היא חלק בעמוד שמכיל גם את ה HTML, גם את ה CSS וגם את ה JavaScript ואפשר להעביר אותו בין פרויקטים או בין דפים. אפשר לחשוב על גלריית תמונות בדף בתור קומפוננטה, תפריט עליון יכול להיות קומפוננטה, תפריט צד יהיה קומפוננטה אחרת ותיבת חיפוש קומפוננטה נוספת. לקומפוננטה יש קשר לקומפוננטות אחרות, למשל קומפוננטה של גלריית תמונות יכולה להיות מורכבת מקומפוננטה כללית יותר של "קרוסלה", אבל הדבר המרכזי לקחת פה הוא שקומפוננטה היא עצמאית: יש לה ממשק מוגדר עם העולם שסביבה, יש לה את התוכן שלה, את הקוד שלה, את העיצוב שלה ואפילו את הבדיקות שלה, ולכן קוד שמורכב מקומפוננטות הוא קוד קל יותר לתחזוקה.

מתכנתי Front End שרגילים לחשוב על HTML/CSS/JavaScript וצריכים לעבור לחשוב על קומפוננטות יצטרכו לשנות גישה. במקום להסתכל על כל העמוד ולחשוב איזה HTML לכתוב עבורו, אנחנו נתחיל בסקירה ממבט על של העמוד, נזהה איזה קומפוננטות מופיעות בו ונתחיל לבנות את הקומפוננטות האלה אחת אחרי השניה. בסוף נרכיב את כל הקומפוננטות יחד כדי לקבל את העמוד המלא.

2. איך נראית קומפוננטה ב Vue

תכף נגיע לכתוב אפליקציית Vue מלאה אבל בואו נתחיל קודם מהעניין המרכזי - הוא הקומפוננטה. קומפוננטה ב Vue נשמרת בקובץ עם סיומת vue ומורכבת משלושה חלקים, שהם שלושת טכנולוגיות הווב שאנחנו מכירים: התבנית (HTML), העיצוב (CSS) והקוד (JavaScript). הנה קומפוננטה ראשונה שמכילה את שלושת החלקים:

<template>
  <input type="text" v-model="text" />
  <p>You typed: {{ text }}</p>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      text: "Type something...",
    };
  },
};
</script>

<style scoped>
  p {
    font-size: 18px;
  }
</style>

את התוצאה של הקוד אפשר לראות לייב בתיבה כאן:

או בקישור: https://codesandbox.io/s/festive-bell-qeij1?file=/src/components/HelloWorld.vue.

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

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

<template>
  <HelloWorld />
</template>

<script>
import HelloWorldVue from "./components/HelloWorld.vue";
export default {
  name: "App",
  components: {
    HelloWorld: HelloWorldVue,
  },
};
</script>

<style>
</style>

וזה מדהים כי גם קובץ זה הוא קומפוננטה. נסו אתם בכניסה לקישור או בתיבה כאן בפוסט לשנות את הקובץ ולהוסיף עוד כמה עותקים של הקומפוננטה - כלומר בתוך ה template לכתוב מספר פעמים את האלמנט HelloWorld:

<template>
  <HelloWorld />
  <HelloWorld />
  <HelloWorld />
  <HelloWorld />
</template>

תוך רגע יופיעו עוד תיבות טקסט ועוד פיסקאות, וכל תיבה תהיה מתואמת עם הפיסקה שלה.

3. מה עוד היה בקומפוננטה

נחזור לקומפוננטה שכתבנו וננסה להבין מה היה שם? איך זה עבד? נחזור לקומפוננטה שכתבנו ונתבונן שוב בקטע ה script שלה:

export default {
  name: "HelloWorld",
  data() {
    return {
      text: "Type something...",
    };
  },
};

דבר ראשון שיראה מוזר פה לחלק מכם הוא התחלת הסקריפט בביטוי export default. זהו כתיב המודולים של ES6 וחשוב להכיר אותו (ובאופן כללי את הרעיונות המרכזיים של ES6 והתקנים החדשים יותר) לפני שאפשר להשתמש בפריימוורקים כמו Vue, React ו Angular. בגדול כתיב זה אומר שהאוביקט שאנחנו כותבים עכשיו יהיה הדבר המרכזי מתוך הסקריפט, והוא בעצם יהיה הדבר שקבצים אחרים "יקבלו" כשהם יטענו את הסקריפט שלי.

האוביקט הזה מורכב משני שדות: השדה name שקובע את שם הקומפוננטה, והשדה data שמכיל את המידע שהקומפוננטה מכירה. אגב, שדה name רלוונטי רק להדפסות ו Debugging והקומפוננטה תעבוד ממש בסדר גם בלעדיו. השדה המעניין הוא data.

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

<template>
  <input type="text" v-model="text" />
  <p>You typed: {{ text }}</p>
</template>

אפשר לראות שאני משתמש במידע בשני מקומות בתבנית:

  1. בתוך תוכן אלמנט p אני משתמש בכתיב {{ text }}. כתיב זה אומר ל Vue שאני רוצה לשתול את הערך של שדה המידע text במקום הביטוי עם הסוגריים המסולסלים.

  2. בתור הערך של ה Attribute שנקרא v-model אני משתמש במילה text. המאפיין v-model הוא מאפיין מיוחד, ואנחנו מזהים את זה גם כי אנחנו לא מכירים אותו מ HTML וגם בגלל התחילית v-. מאפיין מיוחד כזה נקרא Directive, והמאפיין הספציפי v-model הוא Directive די מתוחכם. הוא יוצר בצורה אוטומטית קוד טיפול באירוע input ומחבר אותו לשדה text, כך שכל פעם שהטקסט בתיבה משתנה אוטומטית גם ערך השדה text באוביקט המידע מתעדכן.

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

4. כפתורים ולחיצות

נוסיף לקומפוננטה שלנו כפתור שמאפס את הטקסט כדי לראות גם איך עובדים עם כפתורים. אני מעדכן את הטמפלייט לקוד הבא:

<template>
  <input type="text" v-model="text" />
  <p>You typed: {{ text }}</p>
  <button @click="reset">Reset</button>
</template>

זה מאוד דומה להגדרת כפתור ב HTML רגיל! ההבדל היחיד הוא הסימן המצחיק @click כדי להגדיר מהי הפונקציה שתיקרא בעת לחיצה על הכפתור. בצד הסקריפט אני צריך לכתוב את הפונקציה הרלוונטית בתוך מפתח methods של הדבר שאני מחזיר מהסקריפט, ואותה פונקציה מקבלת את אוביקט המידע בתור פרמטר this שלה. הסקריפט אחרי השינוי נראה כך:

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      text: "Type something...",
    };
  },
  methods: {
    reset() {
      this.text = "";
    },
  },
};
</script>

אתם מוזמנים למצוא את התוצאה בקישור https://codesandbox.io/s/brave-varahamihira-u0370?file=/src/components/HelloWorld.vue:134-325 ולנסות ללחוץ על הכפתור כדי לראות איך הוא מוחק את הטקסט. הדבר היפה לקחת מכאן הוא הריאקטיביות - ברגע שהפונקציה מסתיימת והטקסט הופך למחרוזת ריקה, ויו באופן אוטמטי מעדכן גם את העמוד ומוחק את הטקסט מתיבת הקלט ומה p.

5. תרגילים

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

  1. כפתור ומתחתיו שורת טקסט. בהתחלה בטקסט יהיה כתוב Click The Button ואחרי הלחיצה הטקסט ישתנה ל Ouch!

  2. כפתור ומתחתיו שורת טקסט. בהתחלה הטקסט יהיה המספר 0, וכל לחיצה על הכפתור תעלה את הערך ב-1.

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

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

  5. הציגו 5 תיבות קלט מתואמות, כלומר שינוי טקסט בכל אחת מתיבות הקלט ישנה אוטומטית את הטקסט בכל 4 התיבות האחרות.