Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

vue.js

Last updated at Posted at 2024-04-28

Vue.jsとは

  • コンポーネントを配置してアプリケーションを作る
  • コンポーネントは「.vue」というファイル
  • 「.vue」のファイルはシングルファイルコンポーネントと呼ぶ
  • vueファイルの中身はvue独自のもの
    ブラウザはそのままだと読み込むことができない
  • ブラウザが理解できるようにjavascriptなどの形に変換する必要がある
  • ※vue.jsが内部的に変換する機能も持っている
    スクリーンショット 2024-03-02 143848.png
  • こちらで「js」を押すとvue.jsの機能で変換されたjavascriptのコードを見ることができる
    この画面が何なのかはわからない
  • 変換処理は毎回やっていたら大変なので自動でやってほしい
  • それを自動でやってくれるのが→「Vite」(ビート)
    ※vue.jsとは直接関係はない、ただ作ったひとが同じなのでvue.jsと非常に相性がいい

環境づくり

  • Vite自体もjavascriptで書かれている

  • コンピュータ上でjavascriptを実行する環境を整える必要がある

  • そこでインストールするのが「Node.js」

  • 「Node.js」→Javascriptを実行するソフトウェア
    ※これがないとブラウザ以外ではコンピュータ上でJavascriptを実行できない(Viteも使えない)

  • ここでインストールした(よくわからないがとりあえずインストールまでやった)
    https://nodejs.org/en

基本作業はvs codeで行う

  • viteとvue.jsを使うには、HTMLのファイルや設定ファイルを準備する必要があって面倒。
  • vue.jsはViteを使う場合に必要となるファイルをまとめて作ってくれるコマンドがある
    スクリーンショット 2024-04-28 172031.png
  • ユーザーの階層で「npm create vue@latest」を入力→エンター
  • proceedはyで進めた。
  • 名前を付けるなどする、そのあとは講座通りに設定した。

スクリーンショット 2024-04-28 172346.png

  • コマンドを入力した階層に名付けたフォルダができている(vue-lesson)
    スクリーンショット 2024-04-28 172534.png
  • vs codeで開いてみるとこんな具合にファイルができている

「npm create vue@latest」の意味とは

  • 「create-vue」というソフトウェアの最新バージョンをインストールした上で、「create-vue」というコマンドを入力する、という処理が1行で行われている
  • 色んなファイルが作成されたのは「create-vue」の機能によるもの
  • 「create-vue」はファイルを作ってくれるもの、とざっくりおぼえておく

「npm create vue@latest」で作られたファイルの中身

  • Vite.config.js
    →Viteの設定ファイル
  • READMR.md
    →このプロジェクトの説明
  • package.json
    →重要なファイル!プロジェクト全体における様々な設定が書かれているファイル
vue.js
{
  "name": "vue-lesson",
  "version": "0.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
    "format": "prettier --write src/"
  },
  "dependencies": {
    "vue": "^3.4.21"
  },
  "devDependencies": {
    "@rushstack/eslint-patch": "^1.8.0",
    "@vitejs/plugin-vue": "^5.0.4",
    "@vue/eslint-config-prettier": "^9.0.0",
    "eslint": "^8.57.0",
    "eslint-plugin-vue": "^9.23.0",
    "prettier": "^3.2.5",
    "vite": "^5.2.8"
  }
}
  • dependenciesdevDependenciesの中身
    →プロジェクト内で必要な第三者が作成したソフトウェア(パッケージと呼ぶ)が一覧で書かれている
    ※vueやViteも書かれている
  • dependenciesdevDependenciesの違い
    →「devDependencies」は開発の時だけ使うパッケージ
    →「dependencies」は本番環境、実際にブラウザに渡されるパッケージ(vueのみ)
ここに書いているパッケージはまだインストールされていない!
  • create-vueが必要なパッケージをjsonの中に羅列したにすぎない状態

  • インストールする必要がある

  • インストール方法
    →「npm install」というコマンドを入力するだけ
    スクリーンショット 2024-04-28 175518.png

  • インストールされたパッケージは「node_modules」というフォルダにすべて入る

「scripts」の意味

vue.js
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
    "format": "prettier --write src/"
  },
  • コマンドと関係している
npm run dev

スクリーンショット 2024-04-28 180221.png

  • このように入力すると、"scripts"の中の"dev"の"vite"を実行することになる
    スクリーンショット 2024-04-28 180430.png

  • Viteコマンドが実行されて、Viteが開発用のサーバーを起動する

  • http://localhost:5173/にブラウザでアクセスすると開発中のアプリケーションを見れる

  • 開発中はそのページを見ながら開発することになる
    スクリーンショット 2024-04-28 180835.png

  • 開発用サーバーを閉じたい場合は「ctrl + c」でできる

  • なんか聞かれるので「Y」押したらいける
    スクリーンショット 2024-04-28 181055.png

npm run build
  • 開発がすべて終わった場合に入力するコマンド
  • 入力すると、「dist」フォルダができる
    スクリーンショット 2024-04-28 181405.png
  • distフォルダの中に入っているファイルはすべて公開用に最適化(軽量化など?)された状態になっている
  • distフォルダをアプリを公開してくれるようなサービス(静的ホスティングサービス)に渡すことでアプリを世界中に公開できる
npm run preview
  • buildで作ったdistフォルダが正しく動いているかチェックするもの
  • 入力するとサーバーが立ち上がる
  • 「dist」フォルダの中身をシンプルにレスポンスとして返すサーバーになっている
  • 実行して表示されるURLを見ると本番も開発用サーバーと同様に表示されているかを確かめることができる
    ※これも「ctrl + c」で止めれる
    スクリーンショット 2024-04-28 182423.png
    スクリーンショット 2024-04-28 182444.png
npm run lint
  • コードが正しく書けているかをチェックしてくれる
  • 今のところ変なコードはないのでエラーは出ない
    スクリーンショット 2024-04-28 182818.png
npm run format
  • prettierがコードを綺麗にフォーマットしてくれる
  • 最初のコードがすでにきれいな状態なので現状とくに修正されない

「npm create vue@latest」で作られたファイルの中身の続きに戻る

  • pacakge-lock.json
    ※そんなに重要じゃない
    npm installのコマンドを打った時にインストールされたNode_modulesの中にあるパッケージの厳密な一覧が表示されている

  • jsconfig.json
    →vscodeが効率よくコードを管理するために必要な設定ファイル
    特に普段意識する必要はない

  • index.html
    →アプリケーション全体の元になるHTMLファイル
    ルート直下にあるindex.htmlは開発用、distの中にあるindex.htmlは本番用として返している
    中身は少しだけ違う状態になっている
    distの中にあるindexはルート直下を元にして作られている

  • .prettierrc.json
    →prettierの設定ファイル

  • .gitignore
    →gitの設定ファイル

  • .eslintrc.cjs
    →eslintの設定ファイル

  • srcフォルダ
    スクリーンショット 2024-04-28 184852.png
    →ここが開発者がもっとも使用するフォルダとなる
    基本的に.vueファイルや、css、javascriptはすべてこの中に置く
    ※Viteはsrcフォルダの中身にはさまざまな変換処理を行っている
    (vueのファイルをjavascriptに変換する処理、公開時の最適化の処理)

  • 基本的には色んな処理をViteがやってくれる

  • 外に何も操作されたくないようなファイルを作りたい場合は?
    →srcフォルダの1つ上にある「public」フォルダを使用
    スクリーンショット 2024-04-28 185303.png

  • Viteはpublicフォルダの中だけは一切なにも手を加えない

  • publicの中身は「dist」フォルダの場合、その直下においてくれる
    ※現状favicon.ico
    スクリーンショット 2024-04-28 185539.png

  • 開発サーバーURL/対象のファイルでそのファイル取得できる
    スクリーンショット 2024-04-28 185609.png

  • publicフォルダに関しては開発中というよりはリリースするタイミングでしようすることが多い

  • とりあえずなんとなく把握しておけばよさそう

  • .vscode
    →vscodeの設定をするファイル
    ここは長くなるので項目分けて説明

.vscode
  • extensions.json
    →おすすめのvscode拡張機能が書かれている
    スクリーンショット 2024-04-29 011827.png
    ※それぞれインストールしていく

    • Vue.volar
      これがないとvscodeは.vueファイルを正しく認識しない

    • dbaeumer.vscode-eslint
      これがあるとjavascriptのファイルで存在しないデータを書いた場合、エラーを表示してくれる
      スクリーンショット 2024-04-29 012255.png

    • esbenp.prettier-vscode
      これがあるとドキュメントフォーマットでprettierのルールに従ったものを選択できる

  • settings.json
    インストールしたeslintとprettierの拡張機能に対する設定が書かれている

vue.js
{
  "editor.codeActionsOnSave": {
    "source.fixAll": "explicit"
  },
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}
vue.js
"editor.codeActionsOnSave": {
    "source.fixAll": "explicit"
  },

こちらがeslintの拡張機能の設定
eslintのエラーを保存時に自動で修正してくれる。
※「!!!true」→「!true」でよい
保存時に「!true」に変換してくれる

vue.js
"editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}

こちらがprettierの設定
prettierも保存時に自動でフォーマット化してくれる

eslintやprettierの細かい設定は各設定ファイルでできる
  • .eslintrc.cjs
vue.js
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')

module.exports = {
  root: true,
  'extends': [
    'plugin:vue/vue3-essential',
    'eslint:recommended',
    '@vue/eslint-config-prettier/skip-formatting'
  ],
  parserOptions: {
    ecmaVersion: 'latest'
  }
}
  • 'plugin:vue/vue3-essential',
    'plugin:vue/vue3-recommended',に変更する
    これでeslintがvue.jsのコードに対してかなり厳密なエラーを出す。
    今回はその設定にした。

createAppを使ってVueのアプリを作る方法

  • Viteで開発されるアプリはindex.htmlがベースになっている
    スクリーンショット 2024-04-29 015308.png
  • まずはmain.jsが実行される
いったんやったこと
  • main.jsの中身削除した
  • 「assets」フォルダ、「components」フォルダ、app.vueを削除した(その後、新しく作成した)

main.js

import { createApp } from 'vue'
  • vueから提供される「create」という値をインポートする必要がある。
  • このように書くことによってViteが良い感じにNode_modulesフォルダの中にあるvueのパッケージの中で定義されている「createApp」を引っ張って使えるようにしてくれる
import { createApp } from 'vue'
createApp()
  • createAppは関数になっていて、関数として呼び出すことができる
  • この関数を呼び出すことがvue.jsのアプリケーションを作りだす第一ステップとなる
import { createApp } from 'vue'
import App from './App.vue'
createApp(App)
  • createApp()関数には引数としてコンポーネントを1つ渡してあげる必要がある
  • コンポーネントとは?→vueファイル
  • vueファイルを準備→1番最初のvueファイルには「App.vue」と名付けることが多い
  • javascriptのデフォルトインポート文(波カッコなどを使わないインポート文)
  • import App from './App.vue'
    こちらの「App」の箇所は任意だが、ファイル名に合わせることが多い
  • 設定した「App」をcreateApp()の引数として渡すことで引数にコンポーネントを渡すことができる
  • Viteがvueファイル内部でデフォルトインポートできるようなjavascriptのファイルに変換している
  • 実際には変換されたjavascriotのファイルをここでインポートしているようなこと
  • vueのファイルを使う時はデフォルトインポート文を使う、と覚える
createApp()関数は具体的になにをしているのか
  • 引数に指定されたコンポーネントを元にしてvue.jsのメイン機能であるユーザーインターフェイスを作るという処理をしている
  • createApp()はvue.jsの根幹的働きをしている。必ず呼び出す必要がある。
  • インターフェイスを作るだけで、作ったものを表示する処理はしていない!
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
  • 表示のための処理
  • createApp()関数は返り値を返している
  • 返り値の「App」が持っている「mount」というメソッドを呼び出す
  • こうすることで実際にcreateup関数が作成したインターフェイスを表示することができる
  • ユーザーインターフェイスをどこに表示するのか
    →mountの引数に文字列でcssセレクタと同じルールで指定する必要がある
    スクリーンショット 2024-04-29 023432.png
    この<div id="app"></div>の中(divタグの中)に表示を指定
    ※divタグの中になにか記述があった場合、そちらは削除される

vueファイルの中身とは

スクリーンショット 2024-04-29 120222.png

  • <script><template><style>の3つの要素から構成されている

スクリーンショット 2024-04-29 120423.png

  • 厳密に言うとscriptタグにはsetupというhtmlの属性みたいなものを書く必要がある
  • scriptの中にはjavascriptを書くことができる
  • templateにはhtmlを書ける
  • styleにはcssを書ける
App.vue
<script setup>
const userName = 'Test'
console.log(userName)
</script>
<template>
  <h1>Title</h1>
</template>
<style>
h1 {
  color: red;
}
</style>

スクリーンショット 2024-04-29 121022.png

  • これで開発用サーバーを立ち上げる
    スクリーンショット 2024-04-29 121100.png
    スクリーンショット 2024-04-29 121132.png
  • すでに開発用サーバーに内容が反映されている

スクリーンショット 2024-04-29 121252.png

  • <template>の中身が<div id="app">の中に入っている状態

スクリーンショット 2024-04-29 121558.png

  • scriptとstyleはなくても動くのは動く
  • templateは無いとエラーになる

スクリーンショット 2024-04-29 121839.png

  • Appをcosole.logした状態
  • コンポーネントはファイルだが、最終的には複雑なオブジェクトとなる
vueファイルにおいて重要なもの
  • templateとscript
  • templateとscriptをうまく組み合わせることが重要
  • それによって複雑なユーザーインターフェイスを作り出すことができる

Javascriptのデータを表示させる方法

  • scriptとtemplateを組み合わせる方法を確認
App.vue
<script setup>
const title = 'Vue.js Course'
</script>
<template>
  <h1>Title {{ title }}</h1>
</template>

スクリーンショット 2024-04-29 122402.png

  • 二重波括弧の中に定数を書くと表示することができる
App.vue
<script setup>
const title = 'Vue.js Course'
let price = 9.99
</script>
<template>
  <h1>Title: {{ title }}</h1>
  <h1>Price: ${{ price }}</h1>
</template>
  • 変数も書ける
    スクリーンショット 2024-04-29 122801.png
App.vue
<script setup>
const title = 'Vue.js Course'
let price = 9.99
</script>
<template>
  <h1>Title: {{ title }}</h1>
  <h1>Price: ${{ price - 1 }}</h1>
</template>
  • 定数、変数1つしか入れられないわけではなく、Javascriptの式を記入できる
  • 表示にも反映される
    スクリーンショット 2024-04-29 122801.png

クリックされた時に処理を実行する

App.vue
<script setup>
const title = 'Vue.js Course'
let price = 9.99
function increment() {
  console.log('click!')
}
</script>
<template>
  <h1>Title: {{ title }}</h1>
  <h1>Price: ${{ price - 1 }}</h1>
  <button @click="increment">button</button>
</template>
  • 関数incrementとbuttonを追加
  • 記述した関数に対してタグ内で<button @click="increment">button</button>と指定するだけでボタンをクリックするとイベントが発火する
    スクリーンショット 2024-04-29 123648.png

リアクティビティ

App.vue
<script setup>
const title = 'Vue.js Course'
let price = 9.99
function increment() {
  price += 1
  console.log(price)
}
</script>
<template>
  <h1>Title: {{ title }}</h1>
  <h1>Price: ${{ price - 1 }}</h1>
  <button @click="increment">button</button>
</template>
  • 関数incrementの中にprice += 1というpriceの追加記述を追加した。
    ※consoleもpriceを出力
    スクリーンショット 2024-04-29 124135.png
  • コンソールの中は+1されているが、画面の数値は+されていかない
変数を更新したにも関わらず一切反映されない理由

スクリーンショット 2024-04-29 124351.png

  • ↑【例】最後にaの数値を変えてもcの値に変化は無い
  • 変数を更新したからといってそれを使っている場所まで更新されないのはjavascriptでは当たり前の状態
できれば変数が更新されたら表示も更新されてほしい!
  • vue.jsではそのような動きにする機能がある
  • なにかしらのデータが変わった時にそれに依存するデータも自動的に更新されるような動きのことを抽象的に「リアクティビティ」と呼ぶ
  • vue.jsはリアクティビティシステムをjavascriptで使える機能を提供している
  • その機能こそがvue.jsにおける根幹的な基礎の部分となる

ref()を使ってリアクティブなデータを作る方法

App.vue
<script setup>
import { ref } from 'vue'
const title = 'Vue.js Course'
let price = ref(9.99)
function increment() {
  price.value += 1
  console.log(price)
}
</script>
<template>
  <h1>Title: {{ title }}</h1>
  <h1>Price: ${{ price - 1 }}</h1>
  <button @click="increment">button</button>
</template>
  • import { ref } from 'vue'
    →名前付きimport文でrefという関数をインポートする
  • let price = ref(9.99)
    →リアクティビティデータを提供したいデータに対して引数に入れて呼び出す
    (その返り値を元のデータのように扱う)
    スクリーンショット 2024-04-29 130412.png
  • ボタン押すと表示上の数値も増えるようになる
注意点
  • javascriptに本来存在しないリアクティブシステムを提供するために技術的な問題でデータをオブジェクトとして管理する必要がある
    スクリーンショット 2024-04-29 130635.png
    スクリーンショット 2024-04-29 130727.png
  • refを利用した場合のpriceをコンソールしてみると、9.99という数値ではなく複雑なオブジェクトとして扱われている
  • vue.jsはリアクティビティシステムを提供するために裏で複雑な動きをしている(データをオブジェクト管理している)
  • ref関数が返す複雑なオブジェクトのことを「ref関数」と呼んだりもする
オブジェクトじゃなくて、単純に9.99という値が欲しい場合はどうする?

スクリーンショット 2024-04-29 131335.png
スクリーンショット 2024-04-29 131350.png

  • price.valueとすることで単純に9.99という値を取得できる
値を更新したい場合

price.value = 3.33
のように.valueを付ける必要がある

スクリーンショット 2024-04-29 131616.png
スクリーンショット 2024-04-29 131627.png

  • eslintの拡張機能を追加していれば、データ保存時に勝手に.value付けてくれる(基本的に付け忘れることは少なさそう?)
templateの方には.value不要

スクリーンショット 2024-04-29 131801.png

  • templateは自動的に変数や定数に関してはそれがrefオブジェクトかどうかを毎回内部的にチェックしている
  • refオブジェクトであれば.valueを自動で付けるという動きになっている
App.vue
<template>
  <h1>Title: {{ title }}</h1>
  <h1>Price: ${{ price.value - 1 }}</h1>
  <button @click="increment">button</button>
</template>

スクリーンショット 2024-04-29 132145.png

  • <h1>Price: ${{ price.value - 1 }}</h1>
    ここに.valueを付けると表示はエラーになる
    price.value.valueのようになってしまっている状態
  • templateの方には.valueは付けないようにする!

refの引数にオブジェクトを入れることも可能

const info = ref({
  student: 1000,
  rating: 4
})
  • 受講者数が1000人で評価レートが4の情報を持ったリアクティブなオブジェクトデータのようなものも作ることができる
const info = ref({
  students: 1000,
  rating: 4
})
console.log(info.value.students)

スクリーンショット 2024-04-29 132956.png

  • info.value.studentsと指定することでオブジェクトの中身まで取得できる
App.vue
<template>
  <h1>Title: {{ title }}</h1>
  <h1>Price: ${{ price.value - 1 }}</h1>
  <button @click="increment">button</button>
  <h2>Students: {{ info.students }}</h2>
</template>

スクリーンショット 2024-04-29 133157.png

  • templateの方では<h2>Students: {{ info.students }}</h2>とすることで表示できる
  • templateはvalueが不要なのでinfo.studentsでOK!

reactive()を使ってオブジェクトをリアクティブにする方法

  • ref関数以外のデータをリアクティブにする方法
  • データをリアクティブにするには技術的な問題でそのデータをオブジェクトで管理する必要がある
    スクリーンショット 2024-04-29 143019.png
  • だからref関数は9.99をオブジェクトとして管理していた
    スクリーンショット 2024-04-29 143057.png
  • しかし、infoに関してはもともとのデータがオブジェクト。
{
  students: 1000,
  rating: 4
}
  • この部分がオブジェクト
  • わざわざこのオブジェクトをリアクティブにするためにもう1新しいオブジェクトを作り出してvalueプロパティでアクセスするのは2度手間
    ↑意味があんまりわからん!
  • もともとがオブジェクトなんだからそれをそのままリアクティブにすればよい
App.vue
<script setup>
import { ref, reactive } from 'vue'
const title = ref('Vue.js Course')
let price = ref(9.99)
function increment() {
  price.value += 1
}
const info = ref({
  students: 1000,
  rating: 4
})
const instructor = reactive({
  name: 'Testname',
  age: 25
})
console.log(instructor.age)
</script>
<template>
  <h1>Title: {{ title }}</h1>
  <h1>Price: ${{ price.value - 1 }}</h1>
  <button @click="increment">button</button>
  <h2>Students: {{ info.students }}</h2>
</template>
  • 冒頭のimportと、const instructorを追加
import { ref, reactive } from 'vue'
  • ractive関数をインポートに設定
const instructor = reactive({
  name: 'Testname',
  age: 25
})
console.log(instructor.age)

スクリーンショット 2024-04-29 143900.png

  • reactive関数の引数にオブジェクトを設定することで、instructor.ageで取得ができる。
  • reactive関数で作られるリアクティブなデータはあたかも元のデータがそのまま使われているかのように扱うことができる
  • recative関数から生成されるオブジェクトはrefオブジェクトと差別化してリアクティブオブジェクトと呼ばれる
incrementに処理を追加する場合でも、、
function increment() {
  price.value += 1
  instructor.age += 1
}

スクリーンショット 2024-04-29 144658.png

  • ここにも「.value」は不要になる

refの場合は、、

const instructor = ref({
  name: 'Testname',
  age: 25
})
console.log(instructor.value.age)
  • このように書く必要があった。「.value」を省略できることになる

スクリーンショット 2024-04-29 144354.png

  • reactiveの中にオブジェクト以外を入れると警告が出るので必ずオブジェクトを入れる

  • ref関数の引数にオブジェクトを入れたとき、内部的にreactive関数を使っている。
    reactive関数を使ってその関数の第1引数に指定されたオブジェクトをリアクティブにしている。
    そのリアクティブになったものをvalueプロパティに格納している。

const instructor = reactive({
  name: 'Testname',
  age: 25
})
instructor.bio = 'hello'
  • instructor.bio = 'hello'で普通に新しいプロパティを追加できる
  • 「bio」はリアクティブになっている
App.vue
<script setup>
import { ref, reactive } from 'vue'
const title = ref('Vue.js Course')
let price = ref(9.99)
function increment() {
  price.value += 1
  instructor.age += 1
  instructor.bio = 'hi'
}
const info = ref({
  students: 1000,
  rating: 4
})
const instructor = reactive({
  name: 'Testname',
  age: 25
})
instructor.bio = 'hello'
console.log(instructor.age)
</script>
<template>
  <h1>Title: {{ title }}</h1>
  <h1>Price: ${{ price.value - 1 }}</h1>
  <button @click="increment">button</button>
  <h2>Students: {{ info.students }}</h2>
  <h2>Instructor age: {{ instructor.age }}</h2>
  <h2>Instructor bio: {{ instructor.bio }}</h2>
</template>
  • こんな感じで変更した
function increment() {
  price.value += 1
  instructor.age += 1
  instructor.bio = 'hi'
}
<h2>Instructor bio: {{ instructor.bio }}</h2>
  • こちらを追記。

スクリーンショット 2024-04-29 150043.png
スクリーンショット 2024-04-29 150049.png

  • ボタンを押すとhelloがhiに変わる
オブジェクトの中にオブジェクトを追加した場合
const instructor = reactive({
  name: 'Testname',
  age: 25,
  sns:{
    twitter:'@test_twitter',
    youtube: '@test_youtube'
  }
})
  • snsオブジェクトの内部もリアクティブになる
  • リアクティブオブジェクトの中のオブジェクトはすべてリアクティブになる!

reactive()とref()はこうして一緒に使える

  • reactiveオブジェクトの中でrefオブジェクトが使われているパターン
const instructor = reactive({
  name: 'Testname',
  age: 25,
  sns: {
    twitter: '@test_twitter',
    youtube: '@test_youtube'
  },
  email: ref('test@example.com')
})
  • email: ref('test@example.com')を追加
console.log(instructor.email.value)
  • このように書く必要がありそうに思うが違う!
console.log(instructor.email)
  • このようにvalueを省略できる!
  • むしろ付けるとエラーになる
  • vue.jsはリアクティブオブジェクトのプロパティにアクセスするときは、毎回そのプロパティがrefオブジェクトかどうかをチェックしている。
  • もしrefオブジェクトだった場合、valueを毎回自動的に内部で付ける、というテンプレート内でおこなわれているような処理をしている。
function increment() {
  price.value += 1
  instructor.age += 1
  instructor.bio = 'hi'
  instructor.sns.twitter = 'hello'
  instructor.email = 'info@example.com'
}
  • データを更新するときも同じ。
  • instructor.email = 'info@example.com'でvalueは不要となる
  • reactiveオブジェクトの中にあるrefオブジェクトはすべて.valueを気にせず使用できる!
【注意点】「.value」が自動で付く動きは配列の時だけは機能しないようになっている
const items = reactive([ref(1), ref(2).ref(3)])
console.log(items[0].value)
  • reactive関数の引数にはオブジェクトを入れることができる
  • 配列もオブジェクトの1種なので入れることができる
  • その配列要素にrefオブジェクトを入れた場合、この配列の要素を取得する時は、reactiveオブジェクトの要素の中身であっても「.value」は自動で付かない!!
console.log(items[0])
  • これだとrefオブジェクトがそのままの状態で返ってきてしまう
なぜ配列にだけ「.value」が自動で付かないのか?
  • 配列特有のメソッドと動きがバッティングしないように最初から「.value」の自動付与が無しになっている

普通のオブジェクトとref()を一緒に使う

  • refオブジェクトが、reactiveオブジェクトの中ではなく、普通のオブジェクトの中にある場合
const courseInfo = {
  section: ref(10),
  language: ref('Japanese')
}
console.log(courseInfo.sections.value)
  • 普通のオブジェクトの中にrefオブジェクトがある場合、呼び出しは通常通り「.value」を付ける形で問題ない
templateの中でアクセスしようとするときが要注意
<template>
  <h2>Course Info Sections: {{ courseInfo.sections }}</h2>
</template>
  • この場合、courseInfo.sectionsに「.value」は自動で付かない!
<template>
  <h2>Course Info Sections: {{ courseInfo.sections.value }}</h2>
</template>
  • 末尾に.value付けてあげる必要がある。
なぜtemplateの中で「.value」が自動で付かないのか
  • vue.jsがrefオブジェクトに対して「.value」を自動で付ける時に、各データの先頭しか見てないから
    スクリーンショット 2024-04-29 155025.png
  • {{}}の中身の1番左側しか見てないということ
  • 1番左がrefオブジェクトだったら「.value」を自動で付けるような動きをする
  • そのあとはなにもしない
  • なので1番左のデータが普通のオブジェクトなので「.value」は付かない、ということになる
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?