VueJS – Render Function

Trong component đối với những content được dùng nhiều lần, chúng ta có thể tạo component để tái sử dụng.

Ví dụ

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
   </head>
   <body>
      <div id = "component_test">
         <testcomponent></testcomponent>
      </div>
      <script type = "text/javascript">
         Vue.component('testcomponent',{
            template : '<h1>Hello World</h1>',
            data: function() {
            },
            methods:{
            }
         });
         var vm = new Vue({
            el: '#component_test'
         });
      </script>
   </body>
</html>

Kết quả

Bây giờ chúng ta muốn tái sử dụng component testcomponent này, chúng ta có thể lặp lại nó.

<div id = "component_test">
   <testcomponent></testcomponent>
   <testcomponent></testcomponent>
   <testcomponent></testcomponent>
   <testcomponent></testcomponent>
</div>

Kết quả

Nếu chúng ta muốn thay đổi nội dung của các component này, Chúng ta thử truyền nội dung text cho testcomponent này.

<div id = "component_test">
   <testcomponent>Hello Jai</testcomponent>
   <testcomponent>Hello Roy</testcomponent>
   <testcomponent>Hello Ria</testcomponent>
   <testcomponent>Hello Ben</testcomponent>
</div>

Như vậy text đã không hiển thị đúng như mong muốn của chúng ta. Lúc này, chúng ta phải sửa lại component. VueJS cung cấp slots để làm đc việc này.

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
   </head>
   <body>
      <div id = "component_test">
         <testcomponent>Hello Jai</testcomponent>
         <testcomponent>Hello Roy</testcomponent>
         <testcomponent>Hello Ria</testcomponent>
         <testcomponent>Hello Ben</testcomponent>
      </div>
      <script type = "text/javascript">
         Vue.component('testcomponent',{
            template : '<h1><slot></slot></h1>',
            data: function() {
            },
            methods:{
            }
         });
         var vm = new Vue({
            el: '#component_test'
         });
      </script>
   </body>
</html>

Bây giờ, nếu chúng ta muốn các component này linh động hơn, như có thể thay đổi font-size, color, hay render các thẻ p, div… thì chúng ta cần sử dụng chức năng render function.

<html>
   <head>
      <title>VueJs Instance</title>
      <script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
   </head>
   <body>
      <div id = "component_test">
         <testcomponent :elementtype = "'div,red,25,div1'">Hello Jai</testcomponent>
         <testcomponent :elementtype = "'h3,green,25,h3tag'">Hello Roy</testcomponent>
         <testcomponent :elementtype = "'p,blue,25,ptag'">Hello Ria</testcomponent>
         <testcomponent :elementtype = "'div,green,25,divtag'">Hello Ben</testcomponent>
      </div>
      <script type = "text/javascript">
         Vue.component('testcomponent',{
            render :function(createElement){
               var a = this.elementtype.split(",");
               return createElement(a[0],{
                  attrs:{
                     id:a[3],
                     style:"color:"+a[1]+";font-size:"+a[2]+";"
                  }
               },
               this.$slots.default
               )
            },
            props:{
               elementtype:{
                  attributes:String,
                  required:true
               }
            }
         });
         var vm = new Vue({
            el: '#component_test'
         });
      </script>
   </body>
</html>

Trong ví dụ trên, chúng ta đã thay đổi trong component, thêm render function và thuộc tính props.

Vue.component('testcomponent',{
   render :function(createElement){
      var a = this.elementtype.split(",");
      return createElement(a[0],{
         attrs:{
            id:a[3],
            style:"color:"+a[1]+";font-size:"+a[2]+";"
         }
      },
      this.$slots.default
      )
   },
   props:{
      elementtype:{
         attributes:String,
         required:true
      }
   }
});

Thuộc tính propselementtype với 2 trường attributes là kiểu string và là yêu cầu bắt buộc.

props:{
  elementtype:{
     attributes:String,
     required:true
  }
}

Trong render function chúng ta sẽ lấy giá trị của elementtype và sử dụng.

render :function(createElement){
   var a = this.elementtype.split(",");
   return createElement(a[0],{
      attrs:{
         id:a[3],
         style:"color:"+a[1]+";font-size:"+a[2]+";"
      }
   },
   this.$slots.default
   )
}

Chúng ta return CreateElement để tạo DOM như trong javascipt. Đầu tiên chung ta sẽ lấy giá trị của elementtype và cắt tại dấu “,” chẳng hạn như div,red,25,div1 và lưu thành biến a. Lúc này chúng ta sẽ có a[0] là tag HTML, a[1] là color, a[2] là font-size, a[3] là id.

Hàm createElement sẽ tạo DOM với tag là div, và 2 thuộc tính là id và style.

Text dùng trong hàm createElement là giá trị slots.

this.$slots.default

Tương tự cho những components khác.

<div id = "component_test">
   <testcomponent :elementtype = "'div,red,25,div1'">Hello Jai</testcomponent>
   <testcomponent :elementtype = "'h3,green,25,h3tag'">Hello Roy</testcomponent>
   <testcomponent :elementtype = "'p,blue,25,ptag'">Hello Ria</testcomponent>
   <testcomponent :elementtype = "'div,green,25,divtag'">Hello Ben</testcomponent>
</div>