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

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ụ: <divid="example"><buttonv-on:click="counter += 1">Click me</button><p>Count clicked {{ counter }} </p></div> var app =newVue({ el:'#example', data:{ counter:0}}) Method Event Handlers Trong thực tế,

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ụ:

<divid="example"><buttonv-on:click="counter += 1">Click me</button><p>Count clicked {{ counter }} </p></div>
var app =newVue({
  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ụ:

<buttonv-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:

<buttonv-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:

<buttonv-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.

<formaction=""v-on:submit.prevent="HandleModifier"><labelfor="">Name</label><inputtype="text"name="name"><br><labelfor="">Email</label><inputtype="email"name="email"><inputtype="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.

<inputv-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.

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width, initial-scale=1.0"><scriptsrc="https://cdn.jsdelivr.net/npm/[email protected]/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><divid="app"><ulclass="tabs"><liv-on:click="changeTab('login')">dang nhap</li><liv-on:click="changeTab('register')">đăng xuất</li></ul><br><divclass="login"v-if="tabSelected === 'login'"><h2>Form Dang Nhap</h2><formaction=""><inputtype="email"placeholder="email"><inputtype="pass"name=""id=""placeholder="password"><inputtype="submit"value="dang nhap"></form></div><divclass="register"v-else-if="tabSelected === 'register'"><h2>Form Dang Ky</h2><formaction=""><inputtype="email"placeholder="email"><inputtype="pass"name=""id=""placeholder="password"><inputtype="submit"value="dang ky"></form></div></div></body><scriptsrc="/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:

<templatev-if="loginType === 'username'"><label>Username</label><inputplaceholder="Nhập username"></template><templatev-else><label>Email</label><inputplaceholder="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”:

<templatev-if="loginType === 'username'"><label>Username</label><inputplaceholder="Nhập username"key="username-input"></template><templatev-else><label>Email</label><inputplaceholder="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:

<divid="app"><divclass="list-blog"><divv-for="blog in blogList"class="blog"><divclass="title">{{blog.title}}</div><divclass="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><liv-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` --><divv-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:

<liv-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ụ:

<ulv-if="todos.length"><liv-for="todo in todos">
    {{ todo }}
  </li></ul><pv-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:

<divid="components-demo"><button-counter></button-counter></div>
newVue({ 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 ý:

<divid="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:

newVue({
  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-postv-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/

Nguồn: viblo.asia

Bài viết liên quan

Thay đổi Package Name của Android Studio dể dàng với plugin APR

Nếu bạn đang gặp khó khăn hoặc bế tắc trong việc thay đổi package name trong And

Lỗi không Update Meta_Value Khi thay thế hình ảnh cũ bằng hình ảnh mới trong WordPress

Mã dưới đây hoạt động tốt có 1 lỗi không update được postmeta ” meta_key=

Bài 1 – React Native DevOps các khái niệm và các cài đặt căn bản

Hướng dẫn setup jenkins agent để bắt đầu build mobile bằng jenkins cho devloper an t

Chuyển đổi từ monolith sang microservices qua ví dụ

1. Why microservices? Microservices là kiến trúc hệ thống phần mềm hướng dịch vụ,