---
# System prepended metadata

title: 第二週
tags: [Vue 直播班 DLC - 2023 冬季班]

---

# 第二週

作業挑戰：https://hackmd.io/rwbi3F1OTlWAe8mZe1oYPQ

## 什麼是 Proxy

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy

![空白](https://hackmd.io/_uploads/HydomVVkA.png)


- 為什麼要拆 Reactive、Ref ：
> 參考：

```jsx
 class RefImpl {
    constructor(value, __v_isShallow) {
      this.__v_isShallow = __v_isShallow;
      this.dep = void 0;
      this.__v_isRef = true;
      this._rawValue = __v_isShallow ? value : toRaw(value);
      this._value = __v_isShallow ? value : toReactive(value);
    }
    get value() {
      trackRefValue(this);
      return this._value;
    }
    set value(newVal) {
      const useDirectValue = this.__v_isShallow || isShallow(newVal) || isReadonly(newVal);
      newVal = useDirectValue ? newVal : toRaw(newVal);
      if (hasChanged(newVal, this._rawValue)) {
        this._rawValue = newVal;
        this._value = useDirectValue ? newVal : toReactive(newVal);
        triggerRefValue(this, 4, newVal);
      }
    }
  }
```

RefImpl: https://github.com/vuejs/core/blob/7bedaef4b15d0a402fda5aa0cf9185b5a3d7f98e/packages/reactivity/src/ref.ts#L155

toReactive: https://github.com/vuejs/core/blob/7bedaef4b15d0a402fda5aa0cf9185b5a3d7f98e/packages/reactivity/src/reactive.ts#L402
    

### 限制：

- ref
    - 必須使用 .value 存取值：因為純值無法直接套用響應式
- reactive
    - 不能使用在純值上
- 共同限制：
    - 均不可使用解構取出純值

延伸運用：toRefs, toRef → 兩者均會與原始值產生關聯

- toRef：少用
    - 解構出單一值，並維持響應式
- toRefs：常用
    - 解構出多個值，並維持響應式

## 元件化 Composition API

### Props

在 setup 環境中使用 Props

```jsx
app.component('child', {
  props: ['parentValue'],
  setup({parentValue}) {
    // ... 
  },
});
```

在 script setup 中使用 Props

```jsx
import { defineProps } from 'vue';

const props = defineProps({
  todo: {
    type: Object,
    required: true
  },
});
```

### Emits

在 script setup 使用 emit

```jsx
const emit = defineEmits(['edit-todo', '...']);

const editTodo = (todo) => {
  emit('edit-todo', todo);
};
```

### 課程主線沒有提到的 slot、v-slot

與今日作業有關（Vue 直播班課前影音有介紹到）

## 我是 Vue，我是縫合怪

### 技法一：使用 defineModel 解決煩人的 v-model

1. 使用 defineModel 可以製作專為 v-model 使用的值

```jsx
// #defineModel 的使用方式
const initialTextModel = defineModel({ type: String });
initialTextModel.value = '123';
```

2. 元件定義中，可以直接將 model 直傳入

```jsx
<Child v-model="initialTextModel" />
```

3. 內層可以使用 相同方式，與外部資料達到雙向綁定

```jsx
import { defineModel } from 'vue';
const initialTextModel = defineModel({ type: String });
```

```html
<input v-model="initialTextModel" />
```

### 技法二：單一檔案實現跨元件資料處理

1. 將資料獨立檔案定義
2. 要使用該資料的檔案直接 import（略過 pinia 等工具
3. 完成

優點：

- 小型專案非常容易上手

缺點：

- 容易有管理問題

### 技法三：React 那個招式我要了

### use…

React：https://react.dev/reference/react/useState

Vue：https://vuejs.org/guide/reusability/composables.html#composables

### useRouter

https://router.vuejs.org/zh/api/#Functions-useRoute

### UseFetch

React：https://usehooks.com/usefetch

### 拆分 ref 進行跨元件溝通行為

以 TodoList 為例