เรียนรู้ Vue.js part 2: Conditionals, Loops, Handling Input and Components

Phai Panda
5 min readJul 24, 2020

--

สืบเนื่องจาก part 1 นั้นขายดี ขนาดหนังยังมีภาคต่อดังนั้นนี่จึงเป็น part 2 ที่นำ Vue user guide มาเล่าในแบบฉบับด้นสดเอามันส์อย่างเคย

อะไรนะ!ยังเขียน Angular อยู่อีกเหรอ อุ้ยตาย! บอกเลิก React เลยใช่ไหม
ฮ่า แซวเล่นนะครับ

Composing with Components

ความเดิม part ที่แล้ว

Vue ทำให้เหล่า front end developer ได้รู้จักกับขุมพลังใหม่ที่จะยิ่งใหญ่กว่าเก่า แต่ความยิ่งใหญ่อธิบายยาก part นี้จึงขอแยกเป็น 4 เรื่องย่อยชิมลางก่อน ได้แก่

  1. Conditionals
  2. Loops
  3. Handling Input
  4. Composing with Components

Conditionals

เบื้องต้นง่ายๆคือ if ซึ่งมีผลต่อโครงสร้าง DOM กล่าวคือทำให้ DOM เกิดขึ้นหรือหายไปก็ได้ ผลลัพธ์เกิดจากค่าจริง (true) หรือเท็จ (false) ของเงื่อนไขใดๆ

จาวาสคริปต์ตีความค่าของตัวแปรใน if ที่เป็น 0 (ศูนย์) หรือ null หรือ undefined หรือสตริงว่าง (empty string) หรือ false มีค่าเท่ากับ false

ตัวอย่างต่อไปนี้ทุกคำตอบได้ค่าเท่ากับ no

สำหรับ Vue ใช้ directive ชื่อ v-if

ตัวอย่าง

<div id="app-3">
<span v-if="seen">Now you see me</span>
</div>

จากนั้นเข้าควบคุม

var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})

ผล

v-if true condition

ลองคิดว่าเราเป็นทีมใหญ่ที่มี designer มาช่วยวาดหน้าเว็บให้ (ฟินมาก~) หมอนี่ก็จะลากวาง HTML เอาตามใจชอบ แก้แล้วแก้อีกแก้แล้วแก้อีกจวบกระทั่งสมประสงค์แห่งความปรารถนาทุกฝ่าย คำถามคือ เมื่อ template นี้มี logic ซ่อนแสดงผลโครงสร้าง HTML แบบ dynamic งานของ designer จะทำออกมากี่แบบ?

คำตอบที่ดีคือหลายแบบ คำตอบที่ชั่วร้ายคือแบบเดียว

สุดท้ายแล้วไม่ว่าจะแบบไหน front end progamon (ไฟฟ้าแสนโวลต์!) ก็ต้องเอาไฟล์นั้นมาทำงานอีกที ถ้าเขาเขียนด้วย Angualr เขาจะใช้ *ngIf ถ้าเขาเขียนด้วย React เขาอาจต้องเขียนฟังก์ชันเพื่อ render JSX ตาม logic อันประหลาด แต่ถ้าเขาเขียนด้วย Vue เขาจะพบกับความอัศจรรย์

ชมกันเลยสดๆให้เห็นคาตาว่าแค่กำหนด app3.seen = false ชิ้นส่วนนี้ก็จะหายไป

หรือกลับมาใหม่ได้ดั่งใจฝัน app3.seen = true

เจ๋งใช่ไหมล่ะ

Loops

ภาษาจาวาสคริปต์กล่าวว่าเมื่อเรามีของอยู่เป็นกลุ่มพวกมันจะถูกเรียกว่า array

สมาชิกของ array มีได้ตั้งแต่ 0 ถึง n
ส่วน index ของ array มีได้ตั้งแต่ 0 ถึง n-1

ตัวอย่าง

var items = [] // ไม่มีสมาชิก

หรือ

var items = [{}] // มี 1 สมาชิก

หรือ

var items = [{}, {}] // มี 2 สมาชิก

จาวาสคริปต์ให้สามาชิกเป็นได้ทุกสิ่งอย่างในโลกแห่งค่าของตัวแปร ตัวอย่างข้างต้นคือมีค่าเป็น empty object หรือเรียกว่า ออบเจ็กต์ว่าง

ตัวอย่างอื่นๆสำหรับให้มือใหม่มองแล้วเข้าใจเลย เช่น

var items = [11, -1, 99.9] // มี 3 สมาชิก

เวลาอ้างอิงก็ใช้ index เช่น

items[0] // ให้ค่าเป็น 11

หรือ

items[2] // ให้ค่าเป็น 99.9

ส่วน

items[3] // ให้ค่าเป็น undefined
array value & array index

โดยทั่วไปเรามักทำงานกับ array และมักเป็น array of object เช่น

var p1 = {code: '12345', name: 'John'}
var p2 = {code: '12346', name: 'Jim'}
var persons = [p1, p2]

ซึ่งใช้ index อ้างอิงไม่ต่างจากตัวอย่างก่อนหน้า

เพิ่ม HTML นี้ลงไป

<div id="app-4">
<ol>
<li v-for="person in persons">
{{person.name}}
</li>
</ol>
</div>

จับคู่ id ค่า app-4 กับ Vue instance จากนั้นผูก persons ใน HTML กับ persons ในจาวาสคริปต์ด้วย v-for directive ซึ่งทำหน้าที่เป็น loop

var p1 = { code: '12345', name: 'John' }
var p2 = { code: '12346', name: 'Jim' }
var persons = [p1, p2]
var app4 = new Vue({
el: '#app-4',
data: {
persons
}
})

สิ่งที่ได้คือ array ถูกอ่านค่าที่ index 0 ถึง n-1 อัตโนมัติ

หรือถ้าต้องการ index ของ loop บนหน้า HTML ก็เขียนได้ว่า

<div id="app-4">
<div v-for="(person, i) in persons">
{{i}} - {{person.name}}
</div>
</div>

เมื่อ i เป็นชื่อตัวแปรที่ตั้งเองตามใจชอบ ตำแหน่งของมันหมายถึง index ซึ่งจะเพิ่มค่าเองอัตโนมัติ

v-for with index

อ่านเพิ่มเติม

Handling Input

มาถึง event ที่เกี่ยวข้องกับ user input ไม่ว่าจะ click, change, key press, key down และอื่นๆ Vue สร้าง v-on directive มาเพื่อสิ่งนี้

<div id="app-5">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">Reverse Message</button>
</div>

ควบคุม

var app5 = new Vue({
el: '#app-5',
data: {
message: 'Hello Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})

v-on ถูกจับให้ทำงานกับ click event เมื่อปุ่มถูกคลิกจะทำงานฟังก์ชัน reverseMessage

ที่น่าสนใจคือออบเจ็กต์ data กับออบเจ็กต์ methods ตรงนี้ละไว้ก่อน คำถามคือ Vue แยกสองสิ่งนี้ออกจากกันด้วยเงื่อนไขอะไร?

Angular มี two-way data binding กล่าวคือค่าของตัวแปรฝั่ง model (จาวาสคริปต์) เปลี่ยนจะมีผลให้ค่าของตัวแปรเดียวกันฝั่ง view (HTML template หรือหน้าเว็บ) เปลี่ยนตาม นี่เรียก one-way ในทิศทางตรงข้ามเมื่อค่าของตัวแปรฝั่ง view เปลี่ยนจะมีผลให้ค่าของตัวแปรเดียวกันฝั่ง model เปลี่ยนตาม นี่จึงเรียกว่า two-way การผูกข้อมูลลักษณะนี้วิธีดั่งเดิมจะใช้ ng-model แต่ถ้าเป็นวิธีใหม่จะใช้ reactive from โดยอาศัย RxJS

React ผมลืมไปแล้ว

ส่วน Vue มี v-model รับผิดชอบ data binding

ตัวอย่าง

<div id="app-6">
<p>{{message}}</p>
<input v-model="message">
</div>

ควบคุม

var app6 = new Vue({
el: '#app-6',
data: {
message: 'Hello Vue!'
}
})

ผล

view เปลี่ยนส่งผลต่อ model
model เปลี่ยนส่งผลต่อ view

ความเก่งกาจของจาวาสคริปต์สมัยใหม่นอกเหนือจาก syntax ใหม่ๆยังต้องมีวิธีการจัดการที่ดีด้วย ไม่ว่าจะเป็นด้านของข้อมูลหรือการจัดการโครงสร้าง แท้จริงแล้วเราเขียนจาวาสคริปต์เพียวเลยก็ได้ถ้าชีวิตไม่ลำบากเกินไป แต่ความเป็นจริงนั้นมันลำบากเกินไปที่จะหาคนที่เชียวชาญจาวาสคริปต์อย่างที่สุดเพื่อจะทำงาน front end อย่างเดียวกับโปรเจกต์ขนาดใหญ่ (เดี๋ยวนี้มี Node.js แล้ว — เขียนจาวาสคริปต์ back end) นี่ยังไม่นับการดูแลรักษาโค้ด การเขียนเทสตลอดจนการส่งมอบชิ้นงานให้กับลูกค้าหรือทีมอื่นพัฒนาต่อ โลกจึงมักสร้างสรรค์วิธีการต่างๆออกมาทุ่นแรงหนุนส่งกำลังให้สามารถจัดการกับปัญหาเหล่านี้อยู่ตลอดเวลา

ไม่แปลกที่จะมีจาวาสคริปต์แล้วก็มี jQuery มี React มี Angualr และ Vue

สุดท้ายนี้พูดถึงการจัดการโครงสร้าง แบ่งหน้าเว็บออกเป็นส่วนย่อย เรียกแต่ละส่วนย่อยว่า component แต่ละ component จะมีชื่อและชื่อของมันจะนำไปเป็นแท็กแปะไว้ในหน้าเว็บอีกที

Composing with Components

เพื่อนๆต้องรู้ก่อนว่าแต่ไหนแต่ไรมาเราสามารถสร้างแท็ก HTML ที่ชอบได้และควบคุมมันได้ด้วยจาวาสคริปต์ เช่น

<pros>Hello I am ProS</pros>
var pros = document.getElementsByTagName('pros')[0]
pros.style.display = 'block'
pros.style.color = 'white'
pros.style.backgroundColor = 'orange'
var div = document.createElement('div')
div.innerHTML = 'this is my short name'
pros.append(div)

เมื่อหน้าเว็บมีขนาดใหญ่ การจัดการที่ดีที่สุดในตอนนี้คือเราจะแยกมันออกเป็นส่วนย่อย แต่ละส่วนย่อยจะเรียกว่า component

หรือกล่าวได้ว่า component ใดๆจะประกอบด้วย 2 ส่วน

  1. view (HTML template)
  2. model (จาวาสคริปต์)

ตัวอย่าง

<div id="app-7">
<todo-item></todo-item>
</div>

ควบคุม

Vue.component('todo-item', {
template: '<li>This is a todo</li>'
})
var app7 = new Vue({
el: '#app-7'
})

ผล

display todo-item component

เมื่อเราจะ reuse component ก็ง่ายๆแบบนี้เลย

<div id="app-7">
<todo-item></todo-item>
<todo-item></todo-item>
<todo-item></todo-item>

</div>

ผล

แถมเรายังสามารถส่งตัวแปรเข้าไปได้ด้วยผ่านช่องทางที่เรียกว่า props

แปลงไส้ก่อนเพื่อจะส่งตัวแปร todo เข้ามา

Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{todo.text}}</li>'
})

แล้วใช้ v-bind มาเชื่อม data ใช้ v-for มา loop

<div id="app-7">
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id"

></todo-item>
</div>

ควบคุม

var app7 = new Vue({
el: '#app-7',
data: {
groceryList: [
{ id: 0, text: 'Vegetables' },
{ id: 1, text: 'Cheese' },
{ id: 2, text: 'Whatever else humans are supposed to eat' }
]
}

})

ผล

Vue ถูกออกแบบมาดีใช่ไหมล่ะ รออะไรล่ะ โปรเจกต์ถัดไปก็ใช้ได้เลยนะครับ

โค้ดทั้งหมด

อ้างอิง

https://vuejs.org/v2/guide/

--

--

No responses yet