VueJS – Events

Bài này chúng ta sẽ tìm hiểu về thuộc tính v-on. Thêm v-on và DOM HTML sẽ giúp lắng nghe các sự kiện trong VueJS như click, rê chuột

Sự kiện Click

Ví dụ

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         <button v-on:click = "displaynumbers">Click ME</button>
         <h2> Add Number 100 + 200 = {{total}}</h2>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#databinding',
            data: {
               num1: 100,
               num2 : 200,
               total : ''
            },
            methods : {
               displaynumbers : function(event) {
                  console.log(event);
                  return this.total =  this.num1+ this.num2;
               }
            },
         });
      </script>
   </body>
</html>

kết quả

<button v-on:click = "displaynumbers">Click ME</button>

code trên gắn sự kiện click với function displaynumbers. khi click vào button sẽ gọi function và return về kết quả this.total.

Chúng ta có thể rút gọn thành

<button @click = "displaynumbers">Click ME</button>

Sự kiện mouseover mouseout

Tiếp theo chúng ta sẽ tìm hiểu về sự kiện rê chuột. Xem ví dụ sau:

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         <div v-bind:style = "styleobj" v-on:mouseover = "changebgcolor" v-on:mouseout = "originalcolor"></div>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#databinding',
            data: {
               num1: 100,
               num2 : 200,
               total : '',
               styleobj : {
                  width:"100px",
                  height:"100px",
                  backgroundColor:"red"
               }
            },
            methods : {
               changebgcolor : function() {
                  this.styleobj.backgroundColor = "green";
               },
               originalcolor : function() {
                  this.styleobj.backgroundColor = "red";
               }
            },
         });
      </script>
   </body>
</html>

Trong ví dụ này, chúng ta tạo thẻ div với style widthheight là 100px và background là màu đỏ. Khi rê chuột vào chúng ta sẽ đổi màu background sang xanh và khi kết thúc rê chuột, chúng ta sẽ chuyển nó lại màu đỏ.

Khi rê chuột, phương thức changebgcolor sẽ được gọi. Và khi bỏ rê chuột trên thẻ div phương thức originalcolor sẽ được gọi.

<div v-bind:style = "styleobj" v-on:mouseover = "changebgcolor" v-on:mouseout = "originalcolor"></div>

Kết quả

Khi rê chuột

Khi bỏ rê chuột vào vùng thẻ div

Các tùy chỉnh của v-on

Vue cung cấp các tùy chỉnh cho v-on như once, prevent

.once

Chỉ thực hiện sự kiện 1 lần.

Cấu trúc

<button v-on:click.once = "buttonclicked">Click Once</button>

Ví dụ

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         <button v-on:click.once = "buttonclickedonce" v-bind:style = "styleobj">Click Once</button>
         Output:{{clicknum}}
         <br/><br/>
         <button v-on:click = "buttonclicked"  v-bind:style = "styleobj">Click Me</button>
         Output:{{clicknum1}}
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#databinding',
            data: {
               clicknum : 0,
               clicknum1 :0,
               styleobj: {
                  backgroundColor: '#2196F3!important',
                  cursor: 'pointer',
                  padding: '8px 16px',
                  verticalAlign: 'middle',
               }
            },
            methods : {
               buttonclickedonce : function() {
                  this.clicknum++;
               },
               buttonclicked : function() {
                  this.clicknum1++;
               }
            }
         });
      </script>
   </body>
</html>

 

Trong ví dụ này, chúng ta tạo 2 button. button Click Once chúng ta gắn tùy chỉnh .onceClick Me không có tùy chỉnh này.

<button v-on:click.once = "buttonclickedonce" v-bind:style = "styleobj">Click Once</button>
<button v-on:click = "buttonclicked"  v-bind:style = "styleobj">Click Me</button>

Cả 2 sự kiện click đều gọi function return về giá trị cộng thêm 1.

buttonclickedonce : function() {
   this.clicknum++;
},
buttonclicked : function() {
   this.clicknum1++;
}

Tuy nhiên, khi click vào Click Once, kết quả chỉ tăng 1 lần duy nhất, còn Click Me sẽ tăng theo số lần click. Như vậy, sự kiện click của button Click Once chỉ được thực hiện đúng 1 lần.

.prevent

Cấu trúc

<a href = "http://www.google.com" v-on:click.prevent = "clickme">Click Me</a>

Ví dụ

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         <a href = "https://www.google.com" v-on:click = "clickme" target = "_blank" v-bind:style = "styleobj">Click Me</a>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#databinding',
            data: {
               clicknum : 0,
               clicknum1 :0,
               styleobj: {
                  color: '#4CAF50',
                  marginLeft: '20px',
                  fontSize: '30px'
               }
            },
            methods : {
               clickme : function() {
                  alert("Anchor tag is clicked");
               }
            }
         });
      </script>
   </body>
</html>

Kết quả

Khi chúng ta click, sẽ có 1 alert thông báo và mở link https://www.google.com trong tab mới.

Bây giờ chúng ta sẽ thêm thuộc tính prevent vào để chặn việc mở link sau khi click.

<a href = "http://www.google.com" v-on:click.prevent = "clickme" target = "_blank" v-bind:style = "styleobj">Click Me</a>

Lúc này khi click vào Click Me, chỉ hiển thị ra alert thông báo và không mở link sau đó.

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         <a href = "http://www.google.com" v-on:click.prevent = "clickme" target = "_blank" v-bind:style = "styleobj">Click Me</a>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#databinding',
            data: {
               clicknum : 0,
               clicknum1 :0,
               styleobj: {
                  color: '#4CAF50',
                  marginLeft: '20px',
                  fontSize: '30px'
               }
            },
            methods : {
               clickme : function() {
                  alert("Anchor tag is clicked");
               }
            }
         });
      </script>
   </body>
</html>

Key Modifiers

VueJS cung cấp Key Modifiers để bắt sự kiện bàn phím. Ví dụ, bạn tạo input và gọi function xử lý khi có sự kiện nhấn enter.

Cấu trúc

<input type = "text"  v-on:keyup.enter = "showinputvalue"/>

Cách dùng là v-on:eventname.keyname. Bạn cũng có thể sử dụng cho nhiều keyname : v-on:keyup.ctrl.enter

Ví dụ:

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         <input type = "text" v-on:keyup.enter = "showinputvalue" v-bind:style = "styleobj" placeholder = "Enter your name"/>
         <h3> {{name}}</h3>
      </div>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#databinding',
            data: {
               name:'',
               styleobj: {
                  width: "30%",
                  padding: "12px 20px",
                  margin: "8px 0",
                  boxSizing: "border-box"
               }
            },
            methods : {
               showinputvalue : function(event) {
                  this.name=event.target.value;
               }
            }
         });
      </script>
   </body>
</html>

Kết quả

Nhập dữ liệu vào input và kết quả chỉ hiển thị khi nhấn phím Enter.

Custom Events

Trong VueJS component cha binding data xuống component con thông qua thuộc tính props. Và component con có thể thông báo lại component cha thông qua Custom Events. Component cha sẽ lắng nghe component con dùng sự kiện v-on.

Ví dụ

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
   </head>
   <body>
      <div id = "databinding">
         <div id = "counter-event-example">
            <p style = "font-size:25px;">Language displayed : <b>{{ languageclicked }}</b></p>
            <button-counter
            v-for = "(item, index) in languages"
            v-bind:item = "item"
            v-bind:index = "index"
            v-on:showlanguage = "languagedisp"></button-counter>
         </div>
      </div>
      <script type = "text/javascript">
         Vue.component('button-counter', {
            template: '<button v-on:click = "displayLanguage(item)"><span style = "font-size:25px;">{{ item }}</span></button>',
            data: function () {
               return {
                  counter: 0
               }
            },
            props:['item'],
            methods: {
               displayLanguage: function (lng) {
                  console.log(lng);
                  this.$emit('showlanguage', lng);
               }
            },
         });
         var vm = new Vue({
            el: '#databinding',
            data: {
               languageclicked: "",
               languages : ["Java", "PHP", "C++", "C", "Javascript", "C#", "Python", "HTML"]
            },
            methods: {
               languagedisp: function (a) {
                  this.languageclicked = a;
               }
            }
         })
      </script>
   </body>
</html>

Kết quả

Trong ví dụ này, data được truyền qua lại giữ component chacomponent con.

Đầu tiên, tạo component.

<button-counter
   v-for = "(item, index) in languages"
   v-bind:item = "item"
   v-bind:index = "index"
   v-on:showlanguage = "languagedisp">
</button-counter>

Trong component này v-for sẽ lặp qua mảng languages. Giá trị mảng được lưu trữ trong itemindex.

v-bind:item = "item"
v-bind:index = "index"

Để lấy các giá trị này (item) trong component con chúng ta cần thông qua Props property để truyền vào.

Ngoài ra, chúng ta còn thêm một sự kiện showlanguage sẽ gọi function languagedisp trong Vue instance.

Tiếp theo, trong component chúng ta các button. Số button được tạo sẽ bằng số phần từ trong mảng.

template: '<button v-on:click = "displayLanguage(item)"><span style = "font-size:25px;">{{ item }}</span></button>',

Khi click button, function displayLanguage sẽ được gọi với tham số item.

Vue.component('button-counter', {
   template: '<button v-on:click = "displayLanguage(item)"><span style = "font-size:25px;">{{ item }}</span></button>',
   data: function () {
      return {
         counter: 0
      }
   },
   props:['item'],
   methods: {
      displayLanguage: function (lng) {
         console.log(lng);
         this.$emit('showlanguage', lng);
      }
   },
});

Khi phương thức displayLanguage gọi, nó gọi tiếp phương thước this.$emit(‘showlanguage’, lng). $emi sẽ phát ra thông báo là có sự kiện showlanguage kèm tham số lng. Và lúc component cha sẽ lắng nghe thông qua v-on.

<button-counter
   v-for = "(item, index) in languages"
   v-bind:item = "item"
   v-bind:index = "index"
   v-on:showlanguage = "languagedisp">
</button-counter>

Khi có sự kiện showlanguage. Nó sẽ gọi function languagedisp trong component cha với tham số lng. Như vậy data đã được truyền từ component con sang component cha.

var vm = new Vue({
   el: '#databinding',
   data: {
      languageclicked: "",
      languages : ["Java", "PHP", "C++", "C", "Javascript", "C#", "Python", "HTML"]
   },
   methods: {
      languagedisp: function (a) {
         this.languageclicked = a;
      }
   }
})

Phương thức languagedisp trong component cha được gọi ra và thay đổi giá trị languageclicked hiển thị ra kết quả.

<p style = "font-size:25px;">Language displayed : <b>{{ languageclicked }}</b></p>