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

# Vue Instance

Recovered from a request errorRecovered from a request errorĐược, mình sẽ đi sâu từng phần một về **Vue Instance** trong Vue 2.7. Mình chia thành các mục để bạn dễ theo dõi.

***

## 1. Vue Instance là gì?

Trong Vue 2, mọi ứng dụng Vue đều bắt đầu bằng việc **tạo một root instance** thông qua hàm khởi tạo `new Vue()`:

```js
const vm = new Vue({
  data: { message: 'Hello' }
})
```

`vm` (ViewModel) chính là **Vue Instance**. Nó đóng vai trò là **cầu nối giữa DOM và data**. Khi data thay đổi, instance tự động cập nhật DOM và ngược lại.

***

## 2. Cấu trúc một Vue Instance

Khi bạn truyền một **options object** vào `new Vue({...})`, Vue sẽ:

1. **Khởi tạo** event lifecycle
2. **Thiết lập reactivity system** (để theo dõi data)
3. **Biên dịch template** thành render function (nếu có template)
4. **Mount** vào DOM
5. **Patches** DOM mỗi khi data thay đổi

```mermaid
graph LR
    A[Options Object] --> B[Vue Constructor]
    B --> C["initLifecycle()"]
    C --> D["initEvents()"]
    D --> E["initRender()"]
    E --> F["initState()<br>data, props, computed, watch, methods"]
    F --> G["compile Template"]
    G --> H["$mount()"]
    H --> I[Virtual DOM Render]
```

***

## 3. Các thuộc tính và phương thức cốt lõi trên instance

Mỗi Vue instance đều có các **thuộc tính bắt đầu bằng `$`**:

### Data & DOM

| Thuộc tính | Ý nghĩa                                 | Ví dụ                            |
| ---------- | --------------------------------------- | -------------------------------- |
| `$data`    | Object reactive data                    | `this.$data.message = 'Hi'`      |
| `$props`   | Props nhận từ parent                    | `this.$props.title`              |
| `$el`      | Element DOM thực mà instance đã mount   | `this.$el.querySelector('.btn')` |
| `$refs`    | Truy cập component/element có `ref`     | `this.$refs.input.focus()`       |
| `$options` | Object options gốc dùng để tạo instance | `this.$options.name`             |

### Methods

| Phương thức      | Công dụng                                |
| ---------------- | ---------------------------------------- |
| `$mount(el)`     | Gắn instance vào một DOM node            |
| `$destroy()`     | Hủy instance, gỡ watcher, event listener |
| `$forceUpdate()` | Ép re-render (ít khi dùng)               |
| `$nextTick(cb)`  | Chạy callback sau khi DOM cập nhật xong  |

### Event (chỉ trong component con)

| Phương thức             | Công dụng             |
| ----------------------- | --------------------- |
| `$on(event, fn)`        | Lắng nghe event       |
| `$once(event, fn)`      | Lắng nghe 1 lần       |
| `$off(event, fn)`       | Bỏ lắng nghe          |
| `$emit(event, payload)` | Phát event lên parent |

***

## 4. Lifecycle Hooks — Instance sống như thế nào?

Lifecycle hook là các **function được Vue gọi tự động** tại các giai đoạn khác nhau của instance.

```mermaid
graph TD
    A[new Vue()] --> B["beforeCreate"]
    B --> C["initState()"]
    C --> D["created"]
    D --> E["compile template / render"]
    E --> F["beforeMount"]
    F --> G["$mount() — tạo Virtual DOM"]
    G --> H["mounted"]
    H --> I["Data thay đổi"]
    I --> J["beforeUpdate"]
    J --> K["Virtual DOM re-render"]
    K --> L["updated"]
    L --> M["$destroy() được gọi"]
    M --> N["beforeDestroy"]
    N --> O["Gỡ watcher, event, child components"]
    O --> P["destroyed"]
```

### Chi tiết từng hook trong instance

| Hook            | Data có reactive chưa? | DOM có sẵn chưa?     | Dùng để làm gì?                               |
| --------------- | ---------------------- | -------------------- | --------------------------------------------- |
| `beforeCreate`  | ❌ Chưa                 | ❌ Chưa               | Không nên đụng tới data/DOM                   |
| `created`       | ✅ Rồi                  | ❌ Chưa               | Gọi API, khởi tạo logic                       |
| `beforeMount`   | ✅ Rồi                  | ❌ Chưa               | Cuối cùng sửa data trước render               |
| `mounted`       | ✅ Rồi                  | ✅ Rồi                | Truy cập DOM, init library (Swiper, Chart...) |
| `beforeUpdate`  | ✅ Rồi                  | DOM cũ đang hiển thị | Xử lý trước khi re-render                     |
| `updated`       | ✅ Rồi                  | DOM mới đã hiển thị  | DOM manipulate sau update                     |
| `beforeDestroy` | ✅ Rồi                  | DOM còn              | Cleanup: timer, interval, event listener      |
| `destroyed`     | ❌ Mất reactive         | ❌ DOM đã gỡ          | Dọn dẹp cuối cùng                             |

***

## 5. Reactivity System — "Ma thuật" bên trong Instance

Đây là phần **quan trọng nhất** để hiểu Vue Instance hoạt động như thế nào.

### Cách Vue 2 theo dõi data

```js
data() {
  return { count: 0 }
}
```

Bên trong Vue 2, nó làm các bước:

1. **Walk object**: Duyệt tất cả property trong `data`, `props`, `computed`
2. **Object.defineProperty**: Định nghĩa lại getter/setter cho từng property
3. **Dep (Dependency)**: Mỗi property có một `Dep` — danh sách các `Watcher` đang "theo dõi" nó
4. **Watcher**: Mỗi computed, template, hoặc watch function là một Watcher

```
┌─────────────┐         getter          ┌─────┐
│  Template   │ ───────────────────────►│ Dep │
│  (Watcher)  │◄─────────────────────────│     │
└─────────────┘         setter notify     └─────┘
                                              ▲
                                              │
                                        ┌──────────┐
                                        │  data:   │
                                        │  count   │
                                        └──────────┘
```

### Vì sao phải dùng `this.$set`?

Vue 2 dùng `Object.defineProperty`, nên nó chỉ **phát hiện được property có sẵn khi khởi tạo**. Nếu bạn thêm property mới sau đó, nó **không reactive**:

```js
// ❌ Không reactive — Vue không biết để theo dõi
this.user.age = 30;

// ✅ Đúng — Vue kích hoạt reactivity cho property mới
this.$set(this.user, 'age', 30);
```

Với **array** cũng vậy — chỉ các method được wrap (`push`, `pop`, `splice`...) mới trigger update. Gán index trực tiếp không được:

```js
// ❌ Sai
this.items[0] = 'new';

// ✅ Đúng
this.$set(this.items, 0, 'new');
// hoặc
this.items.splice(0, 1, 'new');
```

***

## 6. Root Instance vs Component Instance

### Root Instance

```js
// main.js
new Vue({
  render: h => h(App)
}).$mount('#app')
```

- **Không có parent** — không nhận props
- `$parent === undefined`
- `$root === chính nó`

### Component Instance (do `export default { ... }` tạo ra)

Mỗi khi Vue compiler gặp một component tag trong template, nó tạo một **Vue component instance** mới:

```vue
<!-- App.vue -->
<template>
  <HelloWorld msg="hi" />
</template>
```

- **Có parent**: `this.$parent` trỏ tới `App`
- **Có props**: `this.$props.msg === 'hi'`
- **Có slots**: `this.$slots`
- **Có scoped slots**: `this.$scopedSlots`

### Ví dụ về component tree instance

```mermaid
graph TD
    A["Root Instance<br>new Vue()"] --> B["App instance"]
    B --> C["HelloWorld instance<br>$parent = App"]
    B --> D["Header instance<br>$parent = App"]
    D --> E["NavItem instance x3<br>$parent = Header"]
```

Trong tree này:

- `E.$root` = `A`
- `E.$parent` = `D`
- `D.$children[0]` = `E` (một trong các NavItem)

***

## 7. Render Function và Virtual DOM

Mọi Vue instance đều có một **render function**. Nếu bạn viết template, Vue compile thành render function.

```js
// Template:
// <div>{{ message }}</div>

// Compile thành:
render(h) {
  return h('div', {}, [ this.message ])
}
```

### `h` (createElement)

```js
h('div',       // tag
  { class: 'box', on: { click: this.handleClick } },  // data object
  [ h('span', 'Hello') ]  // children
)
```

Virtual DOM là cây object JavaScript thể hiện cấu trúc DOM thực. Khi data thay đổi:

1. Vue chạy render function → tạo **new Virtual DOM tree**
2. So sánh với **old Virtual DOM tree** (diffing)
3. Tính toán những node thực sự thay đổi
4. Cập nhật **DOM thật** (patch) — chỉ những chỗ cần thiết

***

## 8. Instance Methods thực tế hay dùng

### `$watch` — Theo dõi data thủ công

```js
created() {
  const unwatch = this.$watch('count', (newVal, oldVal) => {
    console.log('count changed:', oldVal, '->', newVal);
  });
  
  // Sau này có thể bỏ theo dõi
  unwatch();
}
```

### `$refs` — Truy cập DOM/Component

```vue
<template>
  <input ref="inputRef" />
  <ChildComp ref="childRef" />
</template>

<script>
export default {
  mounted() {
    // Truy cập DOM element
    this.$refs.inputRef.focus();
    
    // Truy cập component instance (gọi method của nó)
    this.$refs.childRef.someMethod();
  }
}
</script>
```

### `$nextTick` — Đợi DOM cập nhật xong

```js
methods: {
  increment() {
    this.count++;
    // DOM chưa cập nhật ngay lập tức đâu!
    console.log(this.$el.textContent); // vẫn là giá trị cũ
    
    this.$nextTick(() => {
      console.log(this.$el.textContent); // giá trị mới
    });
  }
}
```

***

## 9. Tổng kết

| Khái niệm           | Hiểu ngắn gọn                                             |
| ------------------- | --------------------------------------------------------- |
| **Vue Instance**    | Object JavaScript kết nối data, template, và DOM          |
| **Options object**  | `{ data, props, methods, computed, watch, lifecycle... }` |
| **Reactivity**      | `Object.defineProperty` + Dep + Watcher                   |
| **$set / $delete**  | Công cụ xử lý limit của Vue 2 reactivity                  |
| **Lifecycle**       | Các giai đoạn từ khởi tạo → mount → update → destroy      |
| **Render function** | `h()` tạo Virtual DOM tree                                |

***

Bạn muốn mình đi sâu thêm phần nào? Ví dụ:

- **Reactive system** code nội bộ Vue 2 (Observer, Dep, Watcher)?
- **Cách `computed` cache** hoạt động bên trong instance?
- **Slot mechanism** và scoped slots?
