{"id":1131,"date":"2021-05-06T14:34:08","date_gmt":"2021-05-06T07:34:08","guid":{"rendered":"https:\/\/www.marketenterprise.vn\/blog\/?p=1131"},"modified":"2021-12-29T18:02:53","modified_gmt":"2021-12-29T11:02:53","slug":"cau-truc-cua-mot-the-hien-vue","status":"publish","type":"post","link":"https:\/\/www.marketenterprise.vn\/blog\/cau-truc-cua-mot-the-hien-vue.html","title":{"rendered":"C\u1ea5u tr\u00fac c\u1ee7a 1 th\u1ec3 hi\u1ec7n Vue (Vue Instance)"},"content":{"rendered":"<div style=\"text-align: justify;\">\n<p>Trong b\u00e0i vi\u1ebft n\u00e0y, m\u00ecnh xin ti\u1ebfp t\u1ee5c n\u00f3i v\u1ec1 c\u1ea5u tr\u00fac c\u1ee7a m\u1ed9t th\u1ec3 hi\u1ec7n Vue (Vue Instance).<\/p>\n<h2>C\u00e1ch t\u1ea1o 1 th\u1ec3 hi\u1ec7n Vue Instance nh\u01b0 th\u1ebf n\u00e0o?<\/h2>\n<p>T\u1ea5t c\u1ea3 m\u1ecdi \u1ee9ng d\u1ee5ng Vue \u0111\u1ec1u \u0111\u01b0\u1ee3c b\u1eaft \u0111\u1ea7u b\u1eb1ng c\u00e1ch kh\u1edfi t\u1ea1o m\u1edbi m\u1ed9t th\u1ec3 hi\u1ec7n Vue (Vue Instance):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var vm = new Vue({\r\n  \/\/ options\r\n})\r\n\r\n<\/pre>\n<p>Tuy kh\u00f4ng \u0111\u01b0\u1ee3c thi\u1ebft k\u1ebf ch\u1eb7t ch\u1ebd theo m\u00f4 h\u00ecnh <a href=\"https:\/\/en.wikipedia.org\/wiki\/Model\u2013view\u2013viewmodel\" target=\"_blank\" rel=\"noopener\">MVVM<\/a> (MVVM pattern), nh\u01b0ng c\u1ea5u tr\u00fac c\u1ee7a n\u00f3 \u0111\u01b0\u1ee3c truy\u1ec1n c\u1ea3m h\u1ee9ng t\u1eeb ch\u00ednh m\u00f4 h\u00ecnh n\u00e0y. Theo quy \u01b0\u1edbc, ta th\u01b0\u1eddng s\u1eed d\u1ee5ng bi\u1ebfn <b>vm<\/b>\u00a0(ViewModel) \u0111\u1ec3 tham chi\u1ebfu \u0111\u1ebfn th\u1ec3 hi\u1ec7n Vue (Vue Instance) c\u1ee7a ch\u00fang ta.<\/p>\n<p>Khi ta t\u1ea1o m\u1ed9t th\u1ec3 hi\u1ec7n, ta th\u01b0\u1eddng c\u1ea7n ph\u1ea3i truy\u1ec1n v\u00e0o c\u00e1c tu\u1ef3 ch\u1ecdn \u0111\u1ec3 c\u00f3 \u0111\u01b0\u1ee3c m\u1ed9t th\u1ec3 hi\u1ec7n ph\u00f9 h\u1ee3p v\u1edbi mong mu\u1ed1n c\u1ee7a ch\u00fang ta. M\u1ed9t \u1ee9ng d\u1ee5ng Vue th\u01b0\u1eddng \u0111\u01b0\u1ee3c c\u1ea5u tr\u00fac b\u1edfi m\u1ed9t th\u1ec3 hi\u1ec7n g\u1ed1c (root Vue instance) \u0111\u01b0\u1ee3c kh\u1edfi t\u1ea1o b\u1eb1ng <b>new Vue<\/b> v\u00e0 c\u00e1c th\u00e0nh ph\u1ea7n c\u00f3 t\u00ednh t\u00e1i s\u1eed d\u1ee5ng \u0111\u01b0\u1ee3c (reuseable components) t\u1ea1o n\u00ean m\u1ed9t c\u1ea5u tr\u00fac c\u00e2u l\u1ed3ng v\u1edbi nhau.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">Root Instance\r\n    \u2514\u2500 ComponentHead\r\n       \u2514\u2500 ComponentLogo\r\n       \u2514\u2500 ComponentMenu\r\n    \u2514\u2500 ComponentBody\r\n       \u2514\u2500 ComponentItem1\r\n           \u2514\u2500ComponentButton\r\n           \u2514\u2500 ComponentInput\r\n       \u2514\u2500 ComponentItem2\r\n    \u2514\u2500 ComponentFooter\r\n       \u2514\u2500 ComponentCopyRight\r\n       \u2514\u2500 ComponentPartner\r\n\r\n<\/pre>\n<h2>D\u1eef li\u1ec7u (data) v\u00e0 ph\u01b0\u01a1ng th\u1ee9c (method)<\/h2>\n<p>Ta h\u00e3y l\u00e0m r\u00f5 ch\u1ee9c n\u0103ng c\u1ee7a 2 kh\u00e1i ni\u1ec7m tr\u00ean th\u00f4ng qua m\u1ed9t v\u00ed d\u1ee5 sau:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var dataDemo = { a: 1 }\r\n  \r\n\/\/ Ta kh\u1edfi t\u1ea1o 1 th\u1ec3 hi\u1ec7n c\u1ee7a Vue\r\nvar vm = new Vue({\r\n  \/\/ ta g\u00e1n tu\u1ef3 ch\u1ecdn data (data option) c\u1ee7a \u0111\u1ed1i t\u01b0\u1ee3ng Vue b\u1eb1ng bi\u1ebfn data ta \u0111\u00e3 t\u1ea1o ra \u1edf tr\u00ean\r\n  data: dataDemo\r\n})\r\n  \r\nvm.a === data.a \/\/ =&gt; true<\/pre>\n<p>Khi ta kh\u1edfi t\u1ea1o th\u1ec3 hi\u1ec7n Vue, n\u00f3 s\u1ebd th\u00eam t\u1ea5t c\u1ea3 c\u00e1c thu\u1ed9c t\u00ednh \u0111\u01b0\u1ee3c t\u00ecm th\u1ea5y trong \u0111\u1ed1i t\u01b0\u1ee3ng <b>data <\/b>v\u00e0o h\u1ec7 th\u1ed1ng ph\u1ea3n \u1ee9ng c\u1ee7a n\u00f3 (Vue&#8217;s reactivity system). M\u1ed9t khi gi\u00e1 tr\u1ecb c\u1ee7a m\u1ed9t trong c\u00e1c thu\u1ed9c t\u00ednh n\u00e0y thay \u0111\u1ed5i th\u00ec view s\u1ebd ph\u1ea3n \u1ee9ng v\u00e0 c\u1eadp nh\u1eadp l\u1ea1i theo gi\u00e1 tr\u1ecb m\u1edbi thay \u0111\u1ed5i c\u1ee7a ch\u00fang ta.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">vm.a = 4\r\ndata.a \/\/ =&gt; 4\r\n  \r\ndata.a = 20\r\nvm.a \/\/ =&gt; 20<\/pre>\n<p>Khi t\u1eadp <b>data<\/b> thay \u0111\u1ed5i, view s\u1ebd th\u1ef1c hi\u1ec7n vi\u1ec7c re-render v\u1edbi gi\u00e1 tr\u1ecb m\u1edbi thay \u0111\u1ed5i. Tuy nhi\u00ean, ch\u1ec9 c\u00f3 c\u00e1c thu\u1ed9c t\u00ednh trong c\u00f3 <b>data <\/b>khi ta th\u1ef1c hi\u1ec7n kh\u1edfi t\u1ea1o th\u1ec3 hi\u1ec7n c\u1ee7a Vue m\u1edbi c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c n\u1ea1p v\u00e0o h\u1ec7 th\u1ed1ng ph\u1ea3n \u1ee9ng. \u0110i\u1ec1u n\u00e0y c\u00f3 ngh\u0129a l\u00e0 khi c\u00e1c thu\u1ed9c t\u00ednh th\u00eam v\u00e0o sau thay \u0111\u1ed5i s\u1ebd kh\u00f4ng k\u00edch ho\u1ea1t view re-render. V\u00ed d\u1ee5:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">vm.b = 50<\/pre>\n<p>V\u00ec v\u1eady, n\u1ebfu ta bi\u1ebft r\u1eb1ng ta s\u1ebd c\u1ea7n \u0111\u1ebfn m\u1ed9t thu\u1ed9c t\u00ednh n\u00e0o \u0111\u00f3 trong <b>data<\/b> t\u01b0\u01a1ng lai v\u00e0 khi kh\u1edfi t\u1ea1o n\u00f3 kh\u00f4ng c\u00f3 gi\u00e1 tr\u1ecb ho\u1eb7c th\u1eadm ch\u00ed kh\u00f4ng t\u1ed3n t\u1ea1i. Ta c\u1ea7n ph\u1ea3i t\u1ea1o thu\u1ed9c t\u00ednh \u0111\u00f3 v\u00e0 g\u00e1n cho n\u00f3 m\u1ed9t gi\u00e1 tr\u1ecb m\u1eb7c \u0111\u1ecbnh n\u00e0o \u0111\u00f3.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var vm = new Vue({\r\n  data: {\r\n    content: \"\",\r\n    error: [],\r\n    status: 0\r\n    list: []\r\n  }\r\n});<\/pre>\n<p>Ngo\u00e0i c\u00e1c thu\u1ed9c t\u00ednh v\u1ec1 d\u1eef li\u1ec7u (data), m\u1ed9t th\u1ec3 hi\u1ec7n c\u1ee7a Vue (Vue instance) c\u00f2n c\u00f3 m\u1ed9t s\u1ed1 thu\u1ed9c t\u00ednh (properties) v\u00e0 ph\u01b0\u01a1ng th\u1ee9c (method) r\u1ea5t h\u1eefu d\u1ee5ng kh\u00e1c. C\u00e1c thu\u1ed9c t\u00ednh v\u00e0 ph\u01b0\u01a1ng th\u1ee9c n\u00e0y c\u00f3 k\u00fd t\u1ef1 <b>$<\/b>\u00a0trong t\u00ean \u0111\u1ec3 ph\u00e2n bi\u1ec7t n\u00f3 v\u1edbi c\u00e1c thu\u1ed9c t\u00ednh v\u00e0 ph\u01b0\u01a1ng th\u1ee9c do ng\u01b0\u1eddi d\u00f9ng \u0111\u1ecbnh danh.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var vm = new Vue({\r\n  el: '#root',\r\n  data: {\r\n    a : 1\r\n  }\r\n});\r\n\r\nvm.$el === document.getElementById('root'); \/\/ =&gt; true\r\n\r\n\/\/ watch method\r\nvm.$watch('a', function(newValue, oldValue) {\r\n  \/\/ handle watch\r\n});<\/pre>\n<h2>V\u00f2ng \u0111\u1eddi c\u1ee7a m\u1ed9t th\u1ec3 hi\u1ec7n (Instance Lifecycle Hook)<\/h2>\n<p>M\u1ed7i th\u1ec3 hi\u1ec7n Vue s\u1ebd th\u00f4ng qua l\u1ea7n l\u01b0\u1ee3t c\u00e1c b\u01b0\u1edbc \u0111\u01b0\u1ee3c \u0111\u1ecbnh s\u1eb5n khi \u0111\u01b0\u1ee3c kh\u1edfi t\u1ea1o, v\u00ed d\u1ee5 nh\u01b0 n\u1ea1p d\u1eef li\u1ec7u gi\u00e1m s\u00e1t (data observation), bi\u00ean d\u1ecbch template, g\u1eafn th\u1ec3 hi\u1ec7n v\u00e0o c\u00e2y DOM v\u00e0 c\u1eadp nh\u1eadp l\u1ea1i c\u00e2y DOM khi d\u1eef li\u1ec7u thay \u0111\u1ed5i. Vue cung c\u1ea5p cho ta c\u00e1c m\u00f3c (hook) \u1edf m\u1ed9t s\u1ed1 giai \u0111o\u1ea1n trong vi\u1ec7c kh\u1edfi t\u1ea1o \u0111\u1ec3 ta c\u00f3 th\u1ec3 ch\u00e8n th\u00eam c\u00e1c tu\u1ef3 ch\u1ec9nh c\u1ee7a m\u00ecnh v\u00e0o nh\u1eefng giai \u0111o\u1ea1n c\u1ee5 th\u1ec3.<\/p>\n<p>V\u00ed d\u1ee5:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var vm = new Vue({\r\n  data: {\r\n    a: 1\r\n  },\r\n  created: function () {\r\n    \/\/ \"this\" is vm instance\r\n    console.log('Variable a: ' + this.a);\r\n  },\r\n});<\/pre>\n<p>\u0110o\u1ea1n code tr\u00ean ta \u0111\u00e3 s\u1eed d\u1ee5ng <b>created<\/b> hook \u0111\u1ec3 ch\u00e8n \u0111o\u1ea1n x\u1eed l\u00fd c\u1ee7a m\u00ecnh v\u00e0o khi instance \u0111\u01b0\u1ee3c kh\u1edfi t\u1ea1o. Ngo\u00e0i <b>created<\/b>, ta c\u00f2n c\u00f3 c\u00e1c hook kh\u00e1c nh\u01b0 <b>mounted<\/b>, <b>updated<\/b>,&#8230;<\/p>\n<blockquote><p>L\u01b0u \u00fd, ta kh\u00f4ng n\u00ean d\u00f9ng <b>arrow function<\/b> \u0111\u1ec3 x\u1eed l\u00fd c\u00e1c hook n\u00e0y v\u00ec arrow function kh\u00f4ng c\u00f3 &#8220;<b>this<\/b>&#8221; v\u00ec v\u1eady ta kh\u00f4ng th\u1ec3 truy c\u1eadp \u0111\u1ebfn c\u00e1c thu\u1ed9c t\u00ednh c\u1ee7a Vue instance b\u00ean trong c\u00e1c <b>Hook<\/b>\u00a0n\u00e0y.<\/p><\/blockquote>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var vm = new Vue({\r\n  data: {\r\n    a: 1\r\n  },\r\n  created: () =&gt; {\r\n    console.log('Variable a: ' + this.a); \r\n    \/\/ Uncaught TypeError: Cannot read property of undefined\r\n  },\r\n});<\/pre>\n<h2>S\u01a1 \u0111\u1ed3 v\u00f2ng \u0111\u1eddi<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1132 size-full\" src=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2021\/05\/06093420\/lifecycle.png\" alt=\"\" width=\"1200\" height=\"3039\" srcset=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2021\/05\/06093420\/lifecycle.png 1200w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2021\/05\/06093420\/lifecycle-118x300.png 118w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2021\/05\/06093420\/lifecycle-404x1024.png 404w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2021\/05\/06093420\/lifecycle-768x1945.png 768w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2021\/05\/06093420\/lifecycle-607x1536.png 607w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2021\/05\/06093420\/lifecycle-809x2048.png 809w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/p>\n<h2>T\u1ed5ng K\u1ebft<\/h2>\n<p>Qua b\u00e0i vi\u1ebft, m\u00ecnh \u0111\u00e3 gi\u1edbi thi\u1ec7u v\u1edbi c\u00e1c b\u1ea1n v\u1ec1 m\u1ed9t th\u1ec3 hi\u1ec7n Vue, \u0111\u00e2y l\u00e0 ki\u1ebfn th\u1ee9c kh\u00e1 quan tr\u1ecdng \u0111\u1ec3 ta c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng Framework Vue m\u1ed9t c\u00e1ch hi\u1ec7u qu\u1ea3 nh\u1ea5t sau n\u00e0y. V\u00ec v\u1eady, c\u00e1c b\u1ea1n h\u00e3y xem th\u1eadt k\u1ef9 c\u00e0ng v\u00e0 tham kh\u1ea3o th\u00eam t\u00e0i li\u1ec7u c\u1ee7a framework m\u00ecnh \u0111\u1ec3 \u1edf d\u01b0\u1edbi \u0111\u1ec3 n\u1eafm th\u1eadt v\u1eefng ph\u1ea7n ki\u1ebfn th\u1ee9c n\u00e0y nh\u00e9. C\u1ea3m \u01a1n c\u00e1c b\u1ea1n.<\/p>\n<p>B\u00e0i vi\u1ebft li\u00ean quan : <a href=\"https:\/\/www.marketenterprise.vn\/blog\/vuejs-la-gi.html\">VueJS l\u00e0 g\u00ec?<\/a><\/p>\n<h4>T\u00e0i li\u1ec7u tham kh\u1ea3o<\/h4>\n<p><a href=\"https:\/\/vuejs.org\/v2\/guide\/instance.html#Lifecycle-Diagram\" target=\"_blank\" rel=\"noopener\">https:\/\/vuejs.org\/v2\/guide\/instance.html#Lifecycle-Diagram<\/a><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Xin ch\u00e0o c\u00e1c b\u1ea1n, b\u00e0i vi\u1ebft VueJS l\u00e0 g\u00ec? c\u1ee7a MEVN \u0111\u00e3 gi\u1edbi thi\u1ec7u cho ch\u00fang ta bi\u1ebft c\u00e1c kh\u00e1i ni\u1ec7m v\u1ec1 Client-side rendering v\u00e0 Server-side rendering. Ngo\u00e0i ra b\u00e0i vi\u1ebft c\u0169ng gi\u1edbi thi\u1ec7u t\u1ed5ng qu\u00e1t v\u1ec1 1 Frontend Framework (JS Framework) l\u00e0 Vue Framework.<\/p>\n","protected":false},"author":30,"featured_media":1090,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[4,34,22,62],"class_list":["post-1131","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology","tag-blog","tag-marketenterprise-vietnam","tag-technical","tag-vue"],"_links":{"self":[{"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/posts\/1131","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/users\/30"}],"replies":[{"embeddable":true,"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/comments?post=1131"}],"version-history":[{"count":0,"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/posts\/1131\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/media\/1090"}],"wp:attachment":[{"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/media?parent=1131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/categories?post=1131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/tags?post=1131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}