- vừa được xem lúc

VueJs cho người mới phần 2

0 0 53

Người đăng: Đức Phạm

Theo Viblo Asia

1. Event Handling

Listening to Events

Chúng ta có thể sử dụng chỉ thị v-on để lắng nghe các sự kiện DOM và chạy một số JavaScript khi chúng được kích hoạt.

Ví dụ:

<div id="example"> <button v-on:click="counter += 1">Click me</button> <p>Count clicked {{ counter }} </p>
</div>
var app = new Vue({ el: '#example', data: { counter: 0 }
})

Method Event Handlers

Trong thực tế, logic để xử lí sự kiện thường phức tạp hơn, vì thế chứa JavaScript trực tiếp trong giá trị của thuộc tính v-on như trên là không khả thi. Đó là lí do v-on cũng có thể nhận tên của một phương thức mà bạn muốn gọi.

Ví dụ:

<button v-on:click="HandleClick">Click me</button>
 methods:{ HandleClick(){ this.counter += 1; } 

Methods in Inline Handlers

Thay vì bind trực tiếp tên phương thức, ta cũng có thể gọi phương thức trong một câu lệnh JavaScript:

<button v-on:click="HandleClick(2)">Click me</button>
HandleClick(number){ this.counter += number; },

Đôi khi chúng ta cũng muốn truy xuất đến sự kiện DOM ban đầu từ câu lệnh JavaScript inline. Bạn có thể truyền sự kiện DOM vào phương thức thông qua biến $event:

<button v-on:click="HandleClick($event,2)">Click me</button>
HandleClick(event,number){ this.counter += number; console.log(event.target); },

Event Modifiers

Trong rất nhiều trường hợp, chúng ta cần gọievent.preventDefault() hoặcevent.stopPropagation()bên trong một phương thức xử lí sự kiện. Tuy việc này không có gì khó, sẽ tốt hơn nếu các phương thức chỉ phải tập trung giải quyết logic dữ liệu thay vì cáng đáng các sự kiện DOM.

Để giải quyết vấn đề này, Vue cung cấp các event modifier chov-on. Event modfier là một hậu tố (postfix) cho directive, được biểu thị bằng một dấu chấm.

 <form action="" v-on:submit.prevent="HandleModifier"> <label for="">Name</label> <input type="text" name="name"> <br> <label for="">Email</label> <input type="email" name="email"> <input type="submit" value="submit"> </form>
 HandleModifier(event){ console.log(event); }

Form Input Bindings

Basic Usage

Bạn có thể sử dụng directivev-model để tạo ràng buộc dữ liệu 2 chiều lên các phần tử form input và textarea. Vue sẽ tự động chọn cách phù hợp để cập nhật phần tử này dựa trên kiểu của input. Có một chút ma thuật,v-model là syntax sugar trong việc cập nhật dữ liệu dựa trên các sự kiện input từ người dùng kèm theo một số trường hợp đặc biệt khác.

v-model sẽ bỏ qua giá trị khởi tạo của các thuộc tính value, checked hoặc selected trong mọi phần tử form. Nó luôn luôn xem data trong đối tượng Vue là nguồn đáng tin cậy duy nhất. Bạn nên khai báo các giá trị khởi tạo trong JavaScript, bên trong option data của component.

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

đây là một trong những rằng buộc. bạn có thể tìm hiểu thêm tại https://v2.vuejs.org/v2/guide/forms.html

Conditional Rendering

Conditional Groups with v-if on <template>

Vì là một directive,v-ifphải được dùng trên một phần tử đơn lẻ (single element) như <p>hoặc <div>. Nếu chúng ta muốn bật tắt một nhóm các phần tử thì sao? Chỉ cần dùng v-if trên một phần tử<template> với vai trò wrap (bọc) các phần tử lại thành một nhóm. Kết quả render cuối cùng sẽ không có phần tử<template> này.

 <!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://cdn.jsdelivr.net/npm/_@.com/dist/vue.js"></script> <title>Document</title> <style> .tabs { margin: 0; padding: 0; } .tabs li { cursor: pointer; padding: 15px 10px; border: 1px solid #ccc; display: inline-block; } .login, .register { border: 1px solid green; width: 500px; height: 100px; padding: 15px 10px; } </style>
</head> <body> <div id="app"> <ul class="tabs"> <li v-on:click="changeTab('login')">dang nhap</li> <li v-on:click="changeTab('register')">đăng xuất</li> </ul> <br> <div class="login" v-if="tabSelected === 'login'"> <h2>Form Dang Nhap</h2> <form action=""> <input type="email" placeholder="email"> <input type="pass" name="" id="" placeholder="password"> <input type="submit" value="dang nhap"> </form> </div> <div class="register" v-else-if="tabSelected === 'register'"> <h2>Form Dang Ky</h2> <form action=""> <input type="email" placeholder="email"> <input type="pass" name="" id="" placeholder="password"> <input type="submit" value="dang ky"> </form> </div> </div> </body>
<script src="/Render_Template/main.js"></script> </html>

Controlling Reusable Elements with key

Vue cố gắng render các phần tử một cách hiệu quả đến mức có thể, với một trong những cách làm là sử dụng lại thay vì tạo mới từ đầu. Ngoài việc giúp cho Vue thao tác cực kì nhanh, điều này còn mang lại một số lợi ích đáng kể khác. Ví dụ, nếu bạn cho phép người dùng được đăng nhập bằng username hoặc email:

<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Nhập username">
</template>
<template v-else> <label>Email</label> <input placeholder="Nhập địa chỉ email">
</template>

thì việc chuyển đổi giá trị của loginType trong đoạn code trên sẽ không xóa đi thông tin mà người dùng đã điền vào. Vì cả hai <template>dùng các phần tử giống nhau, phần tử <input> sẽ không bị thay thế, chỉ có thuộc tính placeholder là thay đổi.

Tuy nhiên không phải lúc nào đây cũng là điều bạn mong muốn. Vì thế, Vue cung cấp một thuộc tính gọi là key. Khi dùng key với giá trị độc nhất (unique), về căn bản bạn đang dặn Vue “xem hai phần tử này là hoàn toàn khác nhau và đừng dùng lại”:

<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Nhập username" key="username-input">
</template>
<template v-else> <label>Email</label> <input placeholder="Nhập địa chỉ email" key="email-input">
</template>

Bây giờ thì hai phần tử <input> này sẽ được render lại từ đầu mỗi khi giá trị loginType được thay đổi.

List Rendering

Mapping an Array to Elements with v-for

Chúng ta có thể dùng directive v-for để render một danh sách các item dựa trên một mảng. Directive v-for đòi hỏi một cú pháp đặc biệt dưới dạng item in items, trong đó items là mảng dữ liệu nguồn và item trỏ đến phần tử mảng đang được duyệt đến:

<div id="app"> <div class="list-blog" > <div v-for="blog in blogList" class="blog"> <div class="title">{{blog.title}}</div> <div class="description">{{blog.body}}</div> </div> </div> 
 data: { blogList: [ { "userId" : 1, "id": 1, "title": "Chúng ta đều là khách qua đường vội vã", "body": "Hôm nay đã là ngày 13/2, vậy một chút nữa thôi là tròn 3 năm tớ đánh mất người con gái từng rất yêu. Valentine năm nay, tớ nhìn dòng người vội qua, nhìn những cặp đôi dắt tay nhau tớ lại chạnh lòng nghĩ đến cậu. Thanh xuân êm đẹp ấy có cậu kề bên thực xứng đáng" }, { "userId" : 1, "id": 2, "title": "Nhìn cuộc đời một cách bình yên", "body": " Cuộc đời tàn nhẫn với ta mười lần thì xin hãy một lần thương xót. Cuộc đời lấy đi của ta mười thứ chỉ xin lại một thứ là bình yên gia đình. Chỉ thế thôi. Lúc đó là lúc ta có thể nhẹ nhàng an nhiên chào đón những tàn nhẫn, vô tâm mà cuộc đời thử thách rồi. " }, { "userId" : 1, "id": 3, "title": "Khi cô đơn quá lâu người ta chẳng cần một ai quan tâm nữa", "body": "Khi cô đơn quá lâu con người ta chẳng cần thêm một ai quan tâm nữa, họ chỉ muốn vậy một mình đi qua những ngày nắng ấm hay gió rét, một mình tận hưởng cuộc sống không có ai bước vào bên trong, không vì ai mà vui mà buồn." }, { "userId" : 1, "id": 4, "title": "Tôi của sau này không còn thích chàng trai đứng dưới mưa", "body": "Có ai đó đứng đợi mình dưới những cơn mưa là một điều gì đó ngọt ngào, lãng mạn. Nhưng có lẽ sau này chúng ta sẽ không còn thích những chàng trai đứng dưới mưa đợi mình nữa. Bởi trải rồi, thấm rồi mới xót người đứng dưới mưa" } ] },

Array Change Detection

Mutation Methods

Vue wrap các phương thức biến đổi (mutation method) của một mảng được quan sát (observe) để việc gọi phương thức này cũng sẽ kích hoạt thay đổi trên view. Các phương thức được wrap gồm có:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

Replacing an Array

Các phương thức biến đổi, như tên gọi cho thấy, biến đổi nội dung của mảng. Chúng ta cũng có những phương thức không biến đổi (non-mutating method) như filter(), concat(), slice()… Thay vì biến đổi nội dung của mảng gốc, các phương thức này luôn trả về một mảng mới. Khi làm việc với các phương thức này, bạn có thể thay mảng cũ bằng mảng mới:

example1.items = example1.items.filter(function (item) { return item.name.match(/à/)
})

Có thể bạn sẽ nghĩ là làm thế này Vue sẽ bỏ đi toàn bộ DOM có sẵn và render lại từ đầu, nhưng không phải thế. Vue thực hiện một số phỏng đoán thông minh để dùng lại DOM đến mức tối đa, vì thế thay thế một mảng bằng một mảng khác chứa các object chồng nhau là một cách làm rất hiệu quả.

v-for with an Object

 <ul> <li v-for="(value,key) in scores">{{key}}:{{value}}}</li> </ul>
 data: { scores: { math: 9.0, english:7, history:9.5 },

key

Khi cập nhật một danh sách các phần tử được render với v-for, mặc định Vue sẽ sử dụng kĩ thuật “inline patch” (hiểu nôm na là “vá tại chỗ”). Điều này có nghĩa là nếu thứ tự của các item thay đổi, thay vì dịch chuyển các phần tử web theo thứ tự tương ứng, Vue sẽ patch mỗi phần tử tại chỗ và bảo đảm phản ánh đúng những gì cần phải render tại vị trí đó. Cách xử lí này tương tự với track-by="$index" trong Vue 1.x.

Kĩ thuật nói trên rất hiệu quả, nhưng chỉ thích hợp khi danh sách cần render không phụ thuộc vào trạng thái của component con (child component state) hay trạng thái DOM tạm thời (ví dụ như thông tin người dùng nhập vào form).

Để Vue có thể nhận ra từng node và nhờ đó có thể tái sử dụng và sắp xếp các phần tử, bạn cần cung cấp một thuộc tính key với giá trị độc nhất cho từng item (ví dụ, id sẽ là một giá trị key lí tưởng). key tương đương với track-by trong 1.x, nhưng vì nó là một thuộc tính, bạn cần dùng v-bind để bind nó vào các giá trị động như sau:

<!-- ở đây ta dùng shorthand `:key` thay vì `v-bind:key` -->
<div v-for="item in items" :key="item.id"> <!-- nội dung -->
</div>

v-for with v-if

Khi được dùng trên dùng một node, v-for có độ ưu tiên cao hơn v-if, có nghĩa là v-if sẽ được thực thi một cách riêng biệt trên mỗi vòng lặp của v-for. Điều này có thể có ích khi bạn muốn render cho chỉ một số item, như trong ví dụ sau:

<li v-for="todo in todos" v-if="!todo.isComplete"> {{ todo }}
</li>

Ví dụ trên sẽ chỉ render những todo chưa hoàn thành.

Ngược lại, nếu bạn muốn bỏ qua việc thực thi vòng lặp v-for theo điều kiện, hãy dùng v-if trên một phần tử wrapper (hoặc <template>). Ví dụ:

<ul v-if="todos.length"> <li v-for="todo in todos"> {{ todo }} </li>
</ul>
<p v-else>Mọi việc đã hoàn thành.</p>

Components Basics

Đây là ví dụ về một component trong Vue:

// Định nghĩa một component với tên là "button-counter"
Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">Bạn đã bấm {{ count }} lần.</button>'
})

Component là các đối tượng Vue có thể sử dụng lại được với một cái tên: trong trường hợp này là <button-counter>. Chúng ta có thể dùng component này như là một phần tử bên trong đối tượng Vue gốc được tạo bởi new Vue:

<div id="components-demo"> <button-counter></button-counter>
</div>
new Vue({ el: '#components-demo' })

Vì là những đối tượng Vue tái sử dụng được, các component cùng nhận các tùy chọn như new Vue, ví dụ data, computed, watch, methods, và các hook vòng đời. Các ngoại lệ duy nhất là một số ít tùy chọn đặc biệt cho root như el.

Reusing Components

Bạn có thể tái sử dụng component bao nhiêu lần tùy ý:

<div id="components-demo"> <button-counter></button-counter> <button-counter></button-counter> <button-counter></button-counter>
</div>

Để ý là khi bấm các nút trên đây, mỗi nút giữ một giá trị count riêng hoàn toàn tách biệt. Điều này là vì mỗi khi bạn dùng một component, một đối tượng của component đó được tạo mới.

data Must Be a Function

tùy chọn data của component phải là một hàm. Bằng cách này, mỗi đối tượng của component có thể duy trì một bản sao riêng biệt của đối tượng data được trả về:

data: function () { return { count: 0 }
}

Organizing Components

Ví dụ, bạn có thể có các component cho header, sidebar, khu vực nội dung, mỗi component này lại chứa các component dành cho trình đơn, blog post, vân vân.

Để có thể được sử dụng trong các template, component phải được đăng kí. Có hai cách đăng kí component: toàn cục và cục bộ. Trên đây chúng ta chỉ mới đăng kí component ở cấp toàn cục với Vue.component:

Vue.component('my-component-name', { // ... tùy chọn ...
})

Passing Data to Child Components with Props

Prop là các thuộc tính tùy chỉnh mà bạn có thể đăng kí trên một component. Khi một giá trị được truyền vào một prop, nó trở thành một _prop_ertycủa đối tượng component đó. Để truyền tựa đề (title) vào component bài viết (blog-post), chúng ta sử dụng tùy chọn props:

Vue.component('blog-post', { props: ['title'], template: '<h3>{{ title }}</h3>'
})

Tuy nhiên, trong một ứng dụng điển hình, bạn có lẽ sẽ có một mảng các bài viết trong data:

new Vue({ el: '#blog-post-demo', data: { posts: [ { id: 1, title: 'Giới thiệu về Vue' }, { id: 2, title: 'Các khái niệm trong Vue' }, { id: 3, title: 'Vue căn bản và vô cùng nâng cao' } ] }
})

và sau đó render một component cho mỗi bài viết:

<blog-post v-for="post in posts" v-bind:key="post.id" v-bind:title="post.title"
></blog-post>

Nguồn tham khảo: https://v2.vuejs.org/v2/guide/

Bình luận

Bài viết tương tự

- vừa được xem lúc

Link prefetching và Lazy loading (Vue Router)

Khi bạn học về Vuejs hay Reactjs thì không ít lần các bạn sẽ gặp từ khóa Lazy loading ở phần Code-Splitting (React) và Lazy Loading (Vue Router). Đọc tài liệu thì dường như chỉ hiểu sơ sài bản chất của nó rồi xem những example và apply vào dự án.

0 0 49

- vừa được xem lúc

5 Tip bỏ túi khi làm việc với Vue

1. Ghi đè scoped style.

0 0 61

- vừa được xem lúc

Tự học Vue.js tập 1 - Intro & Demo

Vue.js là gì.

0 0 44

- vừa được xem lúc

VueJs cho người mới

1. Vue Js là gì. 2. Vue instance.

0 0 17

- vừa được xem lúc

So sánh Vue và React

Khi phát triển một ứng dụng mới hoặc chỉnh sửa giao diện người dùng của một ứng dụng hiện có, tôi nghĩ sẽ có lúc bạn phải tìm hiểu và cân nhắc việc lựa chọn framework js. Trong bài viết này tôi sẽ cố

0 0 50

- vừa được xem lúc

Những điều cơ bản về VueJS

1. Giới thiệu về VueJS. Vậy VueJS là gì. 2.

0 0 18