Vue3 の ref , reactive 比較

● ref

● 1. ref まとめ

1. アクセス方法
・スクリプト内からアクセスする場合は .value でアクセスする(Reactivity Transform を使用すると .value なしでアクセスできる)
・テンプレート内からアクセスする場合はそのままアクセスできる(階層が深いと .value か?)

2. 値の直接更新 → OK 。 ref はリアクティブを保ったまま更新することができる

3. 値の再代入 → OK 。refはリアクティブを保ったまま再代入することができる

ref のサンプル

<template>
  <ul>
    <li v-for="todo in todos" :key="todo.id">
      <div>{{ todo.id }} : {{ todo.name }}</div>
    </li>
  </ul>
</template>

<script lang="ts" setup>
import { ref } from 'vue'

interface Todo {
  id: number
  name: string
}

const todos = ref<Todo[]>([
  {
    id: 1,
    name: 'TODOその1'
  },
  {
    id: 2,
    name: 'TODOその2'
  }
])

// OK
setTimeout(() => {
  todos.value[0].name = 'TODOその1 ● 変更'
}, 1000)

// OK
setTimeout(() => {
  todos.value = [
    ...todos.value,
    {
      id: 3,
      name: 'TODOその3 ● 追加'
    }
  ]
}, 2000)
</script>

Vue.js は Reactivity Transform でさらに進化する

● 2. reactive まとめ

1. アクセス方法
・スクリプト、テンプレート内からアクセスする場合でもそのままアクセスできる

2. 値の直接更新 → OK 。 reactive はリアクティブを保ったまま更新することができる

3. 値の再代入 → NG × 。const で定義した場合は再代入NG

reactive のサンプル

<template>
  <ul>
    <li v-for="todo in todos" :key="todo.id">
      <div>{{ todo.id }} : {{ todo.name }}</div>
    </li>
  </ul>
</template>

<script lang="ts" setup>
import { reactive } from 'vue'

interface Todo {
  id: number
  name: string
}

const todos = reactive<Todo[]>([
  {
    id: 1,
    name: 'TODOその1'
  },
  {
    id: 2,
    name: 'TODOその2'
  }
])

console.log('### todos.value')
console.log(todos)

// OK
setTimeout(() => {
  todos[0].name = 'TODOその1 ● 変更しました'
}, 1000)

// NG × (constへの再代入のためコンパイルエラー)
setTimeout(() => {
  todos = [
    ...todos,
    {
      id: 3,
      name: 'TODOその3 ● 追加'
    }
  ]
}, 2000)

setTimeout(() => {
  todos.push({
    id: 4,
    name: 'TODOその4 ● push'
  })
}, 3000)
</script>
No.2247
11/29 09:33

edit