For AI agents: the complete documentation index is available at https://nhanbe.id.vn/llms.txt, the full documentation bundle is available at https://nhanbe.id.vn/llms-full.txt, and this page is available as Markdown at https://nhanbe.id.vn/frontend/articles/mvvm.md.
Trong tài liệu Vue, vm như 1 biến đại diện minh họa cho Vue instace.
var vm = new Vue({ data: { a : 1 }})
Ví dụ:
// Cách 1: Đặt tên tùy ývar app = new Vue({ el: '#app', data: { message: 'Hello Vue!' }})// Cách 2: Không gán vào biến nào cả (thường dùng trong main.js)new Vue({ el: '#app', render: h => h(App)})// Cách 3: Trong component (phổ biến nhất)export default { data() { return { count: 0 } }, methods: { increment() { this.count++ // this chính là Vue instance (tương đương vm trong docs) } }}
var data = { a: 1 }var vm = new Vue({ data: data})// Vue "proxy" các thuộc tính từ data vào vm// Nên vm.a thực chất là truy cập đến data.avm.a = 2 // Thay đổi vm.adata.a // => 2 (data cũng thay đổi theo)data.a = 3 // Thay đổi data.avm.a // => 3 (vm.a cũng thay đổi theo)
Khi tạo Vue instance, Vue sử dụng Object.defineProperty (trong Vue2) để tạo getter/setter cho các thuộc tính
vm.a thực chất không phải là một thuộc tính riêng, mà là "cửa ngõ" để truy cập data.a
Khi bạn thay đổi vm.a, Vue biết và cập nhật data.a, sau đó kích hoạt re-render view
// Cách 1: Dùng el trong optionsvar vm = new Vue({ el: '#app', // Tự động mount ngay khi tạo data: { message: 'Hello' }})// => Vue instance được tạo và mount ngay lập tức vào #app
// === Cách 1: el - Mount ngay lập tức ===var vm = new Vue({ el: '#app', data: { count: 0 }, created() { console.log('Created!') console.log(this.$el) // undefined - vì chưa mount xong }, mounted() { console.log('Mounted!') console.log(this.$el) // <div id="app">...</div> }})// Created! và Mounted! chạy ngay// === Cách 2: $mount - Có thể delay ===var vm = new Vue({ data: { count: 0 }, created() { console.log('Created!') }})// Làm gì đó trước khi mount...console.log('Chuẩn bị mount...')// Mount sauvm.$mount('#app') // Lúc này mounted() mới chạy
<details>
<summary><strong>✅ Dùng el: "#app" khi nào?</strong></summary>
Dùng khi bạn muốn mount ngay lập tức và không cần làm gì trước khi mount.
Phù hợp cho:
Ứng dụng Vue thuần túy (không kèm thư viện khác)
Code đơn giản, trực tiếp
Không cần kiểm tra điều kiện trước khi mount
// Trường hợp phổ biếnnew Vue({ el: '#app', data: { /* ... */ }, methods: { /* ... */ }})
</details>
<details>
<summary><strong>✅ Dùng .$mount('#app') khi nào?</strong></summary>
Dùng khi bạn cần kiểm soát thời điểm mount hoặc cần làm gì đó trước khi mount.
Phù hợp cho:
Kết hợp với các thư viện khác (như Vue Router, Vuex cần khởi tạo trước):
// main.js trong Vue CLI projectimport Vue from 'vue'import App from './App.vue'import router from './router'import store from './store'// Tạo instance nhưng chưa mountconst app = new Vue({ router, store, render: h => h(App)})// Có thể làm gì đó ở đây (ví dụ: kiểm tra auth)console.log('App created, preparing to mount...')// Mount sauapp.$mount('#app')
Server-Side Rendering (SSR):
// Trong SSR, bạn tạo app nhưng mount ở clientexport default function createApp() { const app = new Vue({ // ... }) return { app, router }}// Sau đó mount ở client
// main.jsimport Vue from 'vue'import App from './App.vue'Vue.config.productionTip = falsenew Vue({ render: h => h(App),}).$mount('#app') // Dùng $mount
👉 Lý do: Vue CLI thường dùng cách này vì tính nhất quán và dễ mở rộng.
2. Code đơn giản, không dùng build tool:
// index.js hoặc script trực tiếpnew Vue({ el: '#app', // Dùng el data: { message: 'Hello Vue!' }})
👉 Lý do: Đơn giản, trực tiếp, dễ hiểu.
3. Khi cần kiểm soát thời điểm mount:
const app = new Vue({ // options})// Chờ API, hoặc kiểm tra điều kiệnfetch('/api/config') .then(() => { app.$mount('#app') })
Lời khuyên: Nếu làm việc với Vue CLI hoặc dự án thực tế, hãy quen với .$mount('#app'). Còn nếu viết code đơn giản trực tiếp, el: "#app" cũng hoàn toàn ổn.
Cả hai cách đều hoạt động giống nhau về kết quả cuối cùng, chỉ khác nhau về thời điểm mount thôi. 😊