עבור המעבדה הזאת אני ממליץ לכם:
- להוריד את כלי הפיתוח עבור vue בתוך הדפדפן:
- לייבא את הקוד מgithub
- להוריד את התוספים הבאים לvscode:
- Markdown All in One
- Live Server
- לפתוח את הדוקומנטציה של Vue
בזמנכם הפנוי לראות את הדוקומנטרי של Vue
המטרה שלכם במעבדה היא ללמוד ולהתנסות ב Vue.js בפעם הראשונה ובעזרתה ליצור עמוד Register.
לעומת עבודה 2, שבה יצרתם עמוד Register באמצעות שימוש בjavascript בסיסי ובספרייה JQuery, כעת אנחנו ניעזר ביכולת של Vue.js בנוסף לjavascript הבסיסי.
Vue.js (או בקיצור - Vue) היא ספריית javascript מתקדמת שעוזרת לנו ליצור SPA (Single Page Application) בצד הלקוח.
הקובץ שאיתו תעבדו הוא register.html שכרגע ריק.
(דף Login יהיה בנוי בצורה דומה רק שלא נבדוק בו קלט. אתם מוזמנים ליצור אותו לאחר מכן ולבדוק שהצלחתם)
את Vue אנחנו יכולים לייבא בכמה דרכים.
במעבדה הזאת נייבא את Vue על ידי תג script (מומלץ להכריז עליו בhead):
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
אפשר לראות שזה דומה לצורה בא ייבאנו את ספריית JQuery ש Vue באה להחליף.
כאשר אנחנו רוצים ליצור אובייקט Vue חדש, נרשום בקוד javascript:
var vm = new Vue({
// options
});
כאשר הoptions הם:
var vm = new Vue({
el: "#template" // selector for template
data(){
return{
// variables
}
} ,
methods: {
// methods
},
// etc... ,
});
הoptions שלנו יכלול selector לelement בHTML כך שאותו אלמנט יהיה הtemplate של אובייקט הVue שלנו.
לאחר היצירה של האובייקט, האובייקט יהיה מקושר לtemplate שהגדרנו לו ויוכל להאזין וליצור שינויים בDOM של אותו template.
קובץ הHTML שבו משולב אובייקט הVue יראה כך:
<!DOCTYPE html>
<!-- The View -->
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<!-- The Template -->
<div id="template">
hello world vue
</div>
</body>
</html>
<!-- The Logic -->
<script>
// The Vue instance
var vm = new Vue({
el: "#template"
});
</script>
<!-- The Style -->
<style></style>
בקובץ register.html יש ליצור את השלד של המסמך.
כמו בדוגמא מעל ראינו שהשל מורכב משלושה חלקים -
-
התצוגה - תחת תג HTML, שתייבא את Vue בhead ובbody תכיל אלמנט (לדוגמא div) שיהיה הtemplate של אובייקט הVue
-
הלוגיקה - תחת תג script, שתיצור אובייקט Vue המקושר לאלמנט שיצרתם ב (1)
-
עיצוב - (אופציונלי) תג style, שבתוכו נציין את העיצוב של המסמך שלנו
לאובייקט Vue יש מספר רחב של פרמטרים עליהם אנחנו מצהירים בזמן יצירת האובייקט (options כמו שרשום למעלה)
במעבדה הזאת אנחנו נדבר על מספר פרמטרים:
data() {
return {
message: "Hello Vue!"
};
}
כל הפרמטרים שחוזרים מdata נוספים כפרמטרים של האובייקט, והפנייה אליהם בתוך האובייקט היא כמו במחלקה בjava - דרך הפוינטר this.
this.message;
כאשר הערכים של אותם פרמטרים משתנים, התצוגה תגיב ותתעדכן לפי הערכים החדשים.
אחת האפשרויות לתצוגה של אותם ערכים ניתנת באמצעות שימוש בסוגריים מסולסלים ובתוכם הפרמטר:
{{ message }}
בקובץ register.html יש להגדיר משתנים שיחזיקו לנו את קלטי המשתמש של הform. את המשתנים האלה יש לרשום בתוך הdata כמו message בדוגמא למעלה.
username: "",
first_name: "",
last_name: "",
country: "",
password: "",
confirmation_password: "",
email: "",
profile_image_url: ""
methods: {
plus: function () {
this.message += " And ";
console.log(this.message);
}
}
כל הפונקציות שבתוך methods נוספות כפונקציות של האובייקט, והפנייה אליהם בתוך האובייקט היא דרך הפוינטר this.
this.plus();
הפנייה לפונקציה מתוך התצוגה תהיה מתוך expression שנרשום באחד הdirectives.
דוגמא לכך היא על ידי directive בשם v-on שמטרתו תיהיה להפעיל את הפוקנציה אחרי הevent של click (שנדבר עליו בהמשך):
<button v-on:click="plus">plus button</button>
בקובץ register.html יש ליצור:
- אלמנט form שלו נגדיר את v-on בצורה הבאה:
<form v-on:submit="handleRegister">
...
</form>
- אלמנט input מסוג
- פונקציה בתוך הפרמטר methods שתקרא בעת לחיצה על הכפתור. אתם יכולים לאתחל את הפונקציה שתעשה alert למחרוזת מסוימת.
הערה:
שלוחצים על submit בform, הevent שיופעל הוא submit של האלמנט form.
במקרה שלנו, הפונקציה handleRegister תופעל, אך לאחר סיומה תופעל גם הפונקציה הדיפולטית של אלמנט הform.
בשביל למנוע את זה נוכל:
- להשתמש בתוך handleRegister ב:
event.preventDefault();
- לציין prevent לצד הפעולה:
v-on:submit.prevent
סימונים על אלמנט DOM שאומרים לספרייה של Vue לחבר התנהגות מסוימת לאותו אלמנט.
לרוב הסימונים האלה בVue יתחילו ב -v.
היום במעבדה נדבר על directives מפורסמים שגם נעשה בהם שימוש במעבדה.
אני ממליץ לכם לקרוא על עוד directives ולהעשיר את הידע.
ההתנהגות יכולה להיות:
- פעולה שתופעל ברגע שevent מסוים יתקיים
- הvalue של הElement יהיה תמיד שווה לפרמטר של האובייקט
- הElement יופיע רק כאשר ערך בוליאני (שיכול להתחשב בפרמטר של האובייקט) יהיה true
Inside template:
<button v-on:click="handleClick">
Click me!
</button>
Inside Vue Object:
methods: {
handleClick: function() {
alert('Clicked');
}
}
מאפשר לצרף לאלמנט פעולה שתופעל כאשר event קורה.
אותה פעולה נקראת event handler.
צורת הכתיבה תיהיה:
v-on:EventName="Function | Inline Statement | Object"
בצורה מקוצרת במקום לרשום :v-on , נרשום @
<a @click="handleClick">Click me!</a>
טיפ: באנגלית קוראים לסימן @ = at, אז אפשר לזכרור את זה כ - at EventName, do somthing
תזכורת: כאשר יצרנו את הכפתור submit השתמשנו בv-on.
כעת בregister.html אתם יכולים להוריד את :v-on ולהשאיר רק את @ כמו שראינו בדוגמא למעלה
Inside template:
<input v-model="message" />
Inside Vue Object:
data(){
return {
message: ""
};
}
מאפשר לנו ליצור two-way binding בין משתנה של אובייקט Vue לאלמנטי input.
אלמנטי input שקיימים בhtml הם:
- input
- select
- textarea
מאחורי הקלעים, v-model הוא סוכר תחבירי המשתמש בv-on לevent של קלט עבור אלמנטיי input
צורת הכתיבה תיהיה:
v-model="variable"
בקובץ register.html יש ליצור את כל התגים הדרושים בתוך תג הform ולקשר אותם למשתנים שהגדרתם במשימה 2
* username - type=input.text
* first_name - type=input.text
* last_name - type=input.text
* country - type=select (you can start with a simple input.text)
* password - type=input.password
* confirmation_password - type=input.password
* email - type=input.email
* profile_page_url - type=input.text
Inside template:
<div v-if="flag">
Good
</div>
<div v-else-if="flag2">
Maybe Good
</div>
<div v-else>
Not Good
</div>
Inside Vue Object:
data(){
return {
flag: false,
flag2: true
};
}
מאפשר לנו להציג ולהסתיר אלמנטים בהתבסס על ערך האמת של תנאי בוליאני.
האלמנטים יווצרו וימחקו מהDom בהתאם לתנאי.
תהליך זה נעשה באופן דינאמי בהתאם לתנאי, כלומר, ברגע שתוצאת התנאי משתנה, האלמנט ימחק/יתווסף לDom.
v-else ו v-else-if בעלות אותו הגיון כמו בשאר שפות תכנות בכך שelse או else-if יופיע רק לאחר if.
צורת הכתיבה תיהיה:
v-if="expression"
v-else-if="expression"
v-else
עוד על v-if
עוד על v-else
עוד על v-else-if
בקובץ register.html יש ליצור:
-
משתנה של שגיאות (מסוג מערך)
-
בפונקציה שמטפלת בsubmit יש להוסיף בדיקות ובמידה ובדיקה יצאה שגויה יש להוסיף אותה למשתנה השגיאות.
הבדיקות יהיו:- שם משתמש יהיה באורך בין 3 ל- 8 תווים (בעבודה יש להוסיף בדיקת הכלה של אותיות בלבד)
- הסיסמה תהיה באורך של בין 5 ל- 10 תווים (בעבודה יש להוסיף בדיקת הכלה של לפחות מספר אחד ותו מיוחד אחד)
-
תג div שמציג את השגיאות אם הsubmit לא עבר בהצלחה ונתקל בשגיאות
-
תג div שמציג הודעת הצלחה - "ההרשמה האחרונה שלך עברה בהצלחה" במקרה והsubmit קרה בלי שגיאות
inside template:
<div v-for="m in messages">
{{ m }}
</div>
inside Vue Object:
data(){
return {
messages: ["a", "b", "c"]
};
}
מאפשר לנו לשכפל אלמנט מספר פעמים על פי קלט איטרטיבי (במקרה שלנו messages) כך שהtemplate שלהם זהה, אך הdata שלהם משתנה (לכל אחד message יהיה אחר)
לדוגמא, אם נרצה להציג רשימה, איך צורך לכתוב עבור כל אלמנט ברשימה תגיות <li>, נוכל לעשות זאת בקלות על ידי ריצה על איברי הרשימה ושימוש בv-for
נוכל לרשום את זה בפסאודו קוד בצורה כזאת:
for item in Iterable:
CreateDomElement(Element, item)
צורת הכתיבה תיהיה:
v-for="alias in Array | Object | number | string | Iterable"
צורת הכתיבה חייבת להיות בצורה
alias in expression
, כדי לספק כינוי לאלמנט הנוכחי באיטרציה.
בנוסף, אפשר לציין כינוי לאינדקס (וגם למפתח אם עוברים על אובייקט):
v-for="(item, index) in items"
v-for="(val, key) in object"
v-for="(val, name, index) in object"
Inside template:
<div v-for="(message, i) in messages">
{{ i }}) {{ message }}
</div>
<ol>
<li v-for="message in messages">
{{ message }}
</li>
</ol>
Inside Vue Object:
data(){
return {
messages: [
"Eran: hey! 😁",
"Yossi: hey! whats up? 🤷♂️",
"Eran: i'm good ✌"
]
};
}
כברירת מחדל vue מנסה לעשות מינימום שינויים בDom.
אם סדר האלמנטים שיצרנו חשוב, ואנו רוצים כי בעת שינוי ברשימה/אובייקט גם התצוגה תתעדכן, עלינו להוסיף לכל אלמנט key (מזהה) ייחודי.
את הkey נקח מתוך הפרמטרים של המשתנה.
לדוגמא, אם נקח את הדוגמא ממקודם, מה שיכול להיות ייחודי עבור הודעה היא הזמן שבו היא נשלחה (הסדר יכול להשתנות כי יכולה להיות אפשרות למחוק הודעות).
לכן אם נשמור את ההודעות בצורה הבאה:
Inside Vue Object:
data(){
return {
messages: [
{ time:1, sender:"Eran", message: "hey! 😁"},
{ time:2, sender:"Yossi", message: "hey! whats up? 🤷♂️"},
{ time:3, sender:"Eran", message: "i'm good ✌"}
]
};
}
נוכל להגדיר את v-for בצורה הבאה:
Inside template:
<ol>
<li v-for="message in messages" :key="message.time">
{{ message.sender }}: {{message.message}} (time={{message.time}})
</li>
</ol>
יש לשנות את התצוגה של השגיאות לתצוגה שמשתמשת בv-for
בעזרת כל מה שלמדנו עד עכשיו נוכל לראות שיצרנו form element שבזמן submit יעשה ואלידציה לקלט.
אם הקלט לא עבר את הואלידציה, נציג למשתמש מה הטעויות שלו.
במידה וכל הקלט תקין, נוכל להוסיף באמצעות axios שליחה של בקשה עם כל הנתונים ששמרנו.
קישור לקוד של שרת אפשר למצוא פה
מידע על שימוש בform inputs ב Vue
מידע על form validations ב Vue
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
עבור fullName, שכאשר נריץ:
this.fullName = "John Doe";