[Vue入門]リアクティビティの基礎

リアクティブな状態を宣言する

リアクティブなオブジェクトや配列を作るには、reactive() 関数を使用します。

import { reactive } from 'vue'

const state = reactive({ count: 0 })

リアクティブなオブジェクトは JavaScript プロキシ で、通常のオブジェクトと同じように振る舞います。違いは、Vue がリアクティブなオブジェクトのプロパティアクセスと変更を追跡できることです。詳細については、Reactivity in Depth で Vue のリアクティブシステムの仕組みを説明していますが、このメインガイドを読み終えた後に読むことをお勧めします。

コンポーネントのテンプレートでリアクティブな状態を使うには、下記に示すように、コンポーネントの setup() 関数で宣言し、それを返します:

import { reactive } from 'vue'

export default {
  // `setup` 関数は、Composition API 専用の特別なフックです。
  setup() {
    const state = reactive({ count: 0 })

    // 状態をテンプレートに公開します
    return {
      state
    }
  }
}
<div>{{ state.count }}</div>

同様に、リアクティブな状態を変化させる関数を同じスコープで宣言し、状態と並行してメソッドとして公開することができます:

import { reactive } from 'vue'

export default {
  setup() {
    const state = reactive({ count: 0 })

    function increment() {
      state.count++
    }

    // 関数も公開することを忘れないでください。
    return {
      state,
      increment
    }
  }
}

通常、公開されたメソッドはイベントリスナーとして使用されます。

<button @click="increment">
  {{ state.count }}
</button>

<script setup>

setup() 関数を使って手動で状態やメソッドを公開すると、冗長になることがあります。幸いなことに、これはビルドステップを使用しない場合にのみ必要です。単一ファイルコンポーネント (SFC) を使用する場合は、 <script setup> を使用することで大幅に簡略化することができます。

<script setup>
import { reactive } from 'vue'

const state = reactive({ count: 0 })

function increment() {
  state.count++
}
</script>

<template>
  <button @click="increment">
    {{ state.count }}
  </button>
</template>

プレイグラウンドで試す

トップレベルのインポートと <script setup> で宣言された変数は、同じコンポーネントのテンプレートで自動的に使用できるようになります。

当ページ残りの部分では、Composition API のコード例として主に SFC + <script setup> という構文を使用します。

DOM 更新のタイミング

リアクティブな状態を変化させると、DOM は自動的に更新されます。しかし、DOM の更新は同期的に適用されないことに注意する必要があります。その代わりに Vue は、更新サイクルの「next tick」まで更新をバッファリングし、どれだけ状態を変化させても、各コンポーネントは一度だけ更新する必要があることを保証しています。

状態変化後の DOM 更新が完了するのを待つため、nextTick() というグローバル API を使用することができます:

import { nextTick } from 'vue'

function increment() {
  state.count++
  nextTick(() => {
    // DOM 更新にアクセスします
  })
}

ディープなリアクティビティ

Vue では、デフォルトで状態がリアクティブになっています。つまり、ネストしたオブジェクトや配列を変化させた場合でも、変更が検出されることが期待できます:

import { reactive } from 'vue'

const obj = reactive({
  nested: { count: 0 },
  arr: ['foo', 'bar']
})

function mutateDeeply() {
  // これらは期待通りに動作します。
  obj.nested.count++
  obj.arr.push('baz')
}

また、ルートレベルでのみリアクティビティを追跡する shallow reactive object を明示的に作成することも可能ですが、これらは一般的に高度な使用例においてのみ必要とされるものとなります。

リアクティブプロキシ vs. 独自

注意すべきは、reactive() の戻り値が、元のオブジェクトの プロキシ であり、元のオブジェクトと等しくないということです:

const raw = {}
const proxy = reactive(raw)

// プロキシはオリジナルと同じではありません。
console.log(proxy === raw) // false

プロキシだけがリアクティブとなります。元のオブジェクトを変更しても更新は行われません。したがって、Vue のリアクティブシステムを使用する際のベストプラクティスは、プロキシされた状態のバージョンだけを使用することになります

プロキシへの一貫したアクセスを保証するために、同じオブジェクトに対して reactive() を呼ぶと常に同じプロキシを返し、既存のプロキシに対して reactive() を呼ぶとその同じプロキシも返されます。

// calling reactive() on the same object returns the same proxy
console.log(reactive(raw) === proxy) // true

// calling reactive() on a proxy returns itself
console.log(reactive(proxy) === proxy) // true

このルールは、ネストされたオブジェクトにも適用されます。深いリアクティビティを持つため、リアクティブなオブジェクトの中にあるネストされたオブジェクトもプロキシとなります。

const proxy = reactive({})

const raw = {}
proxy.nested = raw

console.log(proxy.nested === raw) // false

reactive() の制限

reactive() API には 2 つの制限があります:

  1. オブジェクト型 (オブジェクト、配列、および Map や Set などの コレクション型) に対してのみ機能します。文字列、数値、ブールなどの プリミティブ型 を保持することはできません。
  2. Vue のリアクティビティ追跡はプロパティアクセス上で動作するため、リアクティブなオブジェクトへの参照を常に同じに保つ必要があります。つまり、最初の参照へのリアクティブな接続が失われるため、リアクティブなオブジェクトを簡単に「置き換える」ことはできません:let state = reactive({ count: 0 }) // 上記の参照({ count: 0 })は、もはや追跡されていません(リアクティブな接続が失われました!) state = reactive({ count: 1 }) また、リアクティブなオブジェクトのプロパティをローカル変数に代入したり、分割代入したり、そのプロパティを関数に渡したりすると、下記に示すようにリアクティブなつながりが失われることとなります:const state = reactive({ count: 0 }) // n は切り離されたローカル変数 // を state.count から取得します。 let n = state.count // 元の状態に戻りません。 n++ // count も state.count と切り離されます。 let { count } = state // 元の状態に戻りません。 count++ // この関数が受け取る平文番号と // state.count の変更を追跡することができません。 callSomeFunction(state.count)

ref() と共に使うリアクティブな変数

Vue は、reactive() の制限に対処するため、ref() という関数も提供しており、任意の値の型を保持できるリアクティブな “refs “ を作成することができます:

import { ref } from 'vue'

const count = ref(0)

ref() は引数を受け取り、それを .value プロパティを持つ ref オブジェクトにラップして返します:

const count = ref(0)

console.log(count) // { value: 0 }
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

リアクティブなオブジェクトのプロパティと同様に、ref の .value プロパティはリアクティブとなります。また、オブジェクト型を保持する場合、ref は .value を reactive() で自動的に変換します。

オブジェクトの値を含む ref は、オブジェクト全体をリアクティブに置き換えることができます:

const objectRef = ref({ count: 0 })

// これはリアクティブに動きます。
objectRef.value = { count: 1 }

また、Ref を関数に渡したり、プレーンオブジェクトから分解したりしても、リアクティビティが失われることはありません。

const obj = {
  foo: ref(1),
  bar: ref(2)
}

// ref を受け取るこの関数は、
// .value を介して値にアクセスする必要がありますが、それは
// リアクティビティを保持します。
callSomeFunction(obj.foo)

// リアクティビティを保持しています。
const { foo, bar } = obj

つまり、ref() を使うと、任意の値への「参照」を作り、リアクティビティを失わずに受け渡しすることができます。この能力は、ロジックを Composable Functions に抽出する際に頻繁に使用されるため、非常に重要となります。

Ref Unwrapping in Templates

ref がテンプレートのトップレベルのプロパティとしてアクセスされた場合、それらは自動的に「アンラップ」されるので、.value を使用する必要はありません。以下は、先ほどのカウンターの例で、代わりに ref() を使用したものとなります:

<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <button @click="increment">
    {{ count }} <!-- .value は必要ありません -->
  </button>
</template>

プレイグラウンドで試す

アンラップは、ref がテンプレートに描画されるコンテキスト上のトップレベルのプロパティである場合にのみ適用されることに注意してください。例として foo はトップレベルのプロパティですが、object.foo はトップレベルではありません。

そこで、下記に示したようなオブジェクトが与えられた:

const object = { foo: ref(1) }

下記に示した式は、期待通りに動作 しません :

{{ object.foo + 1 }}

レンダリング結果は [object Object] となります。これは object.foo が ref オブジェクトであるためです。これを解決するには、下記に示すように foo をトップレベルのプロパティにします:

const { foo } = object
{{ foo + 1 }}

これで、レンダリング結果は「2」になります。

注意点としては、ref がテキスト補間の最終評価値(つまり {{ }} タグ)である場合もアンラップされるので、以下のように 1 がレンダリングされます。

{{ object.foo }}

これはテキスト補間の便利な機能に過ぎず、 {{ object.foo.value }} と等価になります。

リアクティブなオブジェクトにおける Ref のアンラッピング

リアクティブなオブジェクトのプロパティとして ref にアクセスしたり変化させたりすると、自動的にアンラップされるので、通常のプロパティと同じように振る舞うことができます:

const count = ref(0)
const state = reactive({
  count
})

console.log(state.count) // 0

state.count = 1
console.log(count.value) // 1

既存の ref にリンクされたプロパティに新しい ref が割り当てられた場合、下記に示すように、それは古い ref を置き換えることとなります:

const otherCount = ref(2)

state.count = otherCount
console.log(state.count) // 2
// 元の ref は state.count から切り離されました。
console.log(count.value) // 1

Ref のアンラッピングは、より深いリアクティブなオブジェクトの内部にネストされている場合にのみ発生します。浅いリアクティブなオブジェクト のプロパティとしてアクセスされた場合は適用されません。

配列とコレクションにおける Ref のアンラッピング

リアクティブなオブジェクトと異なり、ref がリアクティブな配列の要素や、Map のようなネイティブコレクション型としてアクセスされた場合には、アンラップは行われません。

const books = reactive([ref('Vue 3 Guide')])
// ここでは .value が必要となります
console.log(books[0].value)

const map = reactive(new Map([['count', ref(0)]]))
// ここでは .value が必要となります
console.log(map.get('count').value)

Reactivity Transform 

Ref で .value を使わなければならないのは、JavaScript の言語的な制約による欠点です。しかし、コンパイル時の変換 (ここでいうコンパイル時とは SFC を JavaScript コードへ変換する時) を利用すれば、適切な場所に自動的に .value を追加して人間工学を改善することができます。Vue はコンパイル時の変換を提供しており、先ほどの「カウンター」の例をこのように記述することができます。

<script setup>
let count = $ref(0)

function increment() {
  // ここでは .value が不要です
  count++
}
</script>

<template>
  <button @click="increment">{{ count }}</button>
</template>

Reactivity Transform の詳細については、専用のセクションで説明されています。ただし、現在はまだ実験的なものであり、最終的に完成するまでに変更される可能性があることに注意してください。

Vue Options APIとCompostion APIの違い

これからVueJSを学ぶ方へ。

VueはReactやAngularと同じようにSPA(Single Page Application)を作るためのJavaScriptフレームワークです。

Reactが統計上では一番人気で求人も多いという事ですが、Vueは初心者にもわかりやすく、数年でReact以上の人気が出ると思います。

現段階ではVueはバージョン3まで出ており、今から始めるなら最新のVue3から学び始めて問題ありません。

Options APIとCompostion API

Options API

Vueのコードを書くにあたり2つ(正確には3つ)方法があります。

一つ目が初心者向けのOptions APIです。

まずはOptionsAPIの例を見てみましょう。

<script>
export default {
  // Properties returned from data() becomes reactive state
  // and will be exposed on `this`.
  data() {
    return {
      count: 0
    }
  },

  // Methods are functions that mutate state and trigger updates.
  // They can be bound as event listeners in templates.
  methods: {
    increment() {
      this.count++
    }
  },

  // Lifecycle hooks are called at different stages
  // of a component's lifecycle.
  // This function will be called when the component is mounted.
  mounted() {
    console.log(`The initial count is ${this.count}.`)
  }
}
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

Options APIの特徴はdata()でデータをまとめmethod()で使用するファンクションをまとめ、このようにブロックごとでコードを分けていくことです。

短所として、thisのキーワードを使わないといけないこと、ブロックごとでコードをまとめるのでコードの文にまとまりがなくなることです。

一応、Options APIという存在があるという事だけ覚えておいて、まったく学ぶ必要はありません。

Composition API

Vueの強みといえるCompostion APIと<script setup>を紹介します。

下記がcompostion APIの例になります。

特徴としては、

  • <script setup>が導入され少ないコードでかけるようになった。
  • setupのキーワードをscriptタグに入れた場合はvueからメソッドをインポートする必要があります。
  • 機能ごとにコードをまとめるので後から読みやすい。
  • インポートしたコンポーネントや変数をそのままHTMLのテンプレートで使用できる。
<script setup>
import { ref, onMounted } from 'vue'

// reactive state
const count = ref(0)

// functions that mutate state and trigger updates
function increment() {
  count.value++
}

// lifecycle hooks
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

ではrefやonMountのLifecycle Hook(ライフサイクルフック)は今後、基本のコンポーネントやプロップの使い方を紹介した後に詳しく説明していきたいと思います。

今日、覚えてほしいことです。

  • VueはCompostion APIの書き方で書くようにする。
  • VueはJavaScriptとhtml、cssが一つのファイルにまとまった.vueファイルで構成される。

Viteを使ってVueを始めよう

Viteとは

Vite(発音:ヴィート)はVue Cliの次世代のビルドツールで軽量でデベロップメントのスピードを速くするために作られました。

今まではnpmやvue cliでVueアプリを作ってきましたが、Viteを使ってVueだけでなくReactやSvelteも構築できてしまいます。


Viteをつかってみよう

現段階ではNode.jsの12.2.0以上のバージョンが必要とされています。ではnpm、もしくはyarnが入っていることを確認してViteを使ってみましょう。

npmの場合

npm create vite@latest

yarnの場合

yarn create vite

インストールが終わったら下のコマンドでパッケージをインストールしてデベロップメント用のウェブサーバーを起動しましょう。

  cd vite-project
  npm install
  npm run dev

index.html と プロジェクトルート

通常、Vue Cliやnpmで作成したVueアプリケーションのindex.htmlはpublicフォルダに格納されますが、Viteで作った場合はindex.htmlがプロジェクトの直下に作成されます。このファイルがアプリケーションのエントリーポイントとなっているからです。

アプリケーションのビルド

Viteでアプリケーションが完成したら下記のコマンドでコードをコンパイルしましょう。

npm run build

 

Vue3 のドキュメンテーションを日本語でみる方法

Vueの公式ドキュメンテーションを見てみるとまだ日本語の翻訳は準備中の様です。

しかし、翻訳したリポジトリをクローンして読むことができるので是非試してみましょう。

翻訳のGitHubページ

https://github.com/vuejs-translations/docs-ja

上記のリンクからGitを使ってリポジトリをローカル環境にクローンしましょう。

Gitが無い人はこちらを先に見てくださいね。

pnpmのインストール

リポをクローンする前に先にpnpmをインストールしておきましょう。

npm install -g pnpm

リポのクローン

ではリポジトリをクローンしていきます。

git clone https://github.com/vuejs-translations/docs-ja.git
cd docs-ja

pnpm i
pnpm run dev

で、URLがコマンドラインに表示されたらそこからドキュメンテーションを見てみましょう。

私はいつも英語ドキュメンテーションを読みますが翻訳するのが大変なのでこれは助かります!

お疲れっす。

[Vue入門] テンプレートシンタックス

Vue では、HTML ベースのテンプレート構文を使用します。テンプレート構文では、基盤とするコンポーネントのインスタンスのデータと、レンダリングされる DOM を宣言的にバインドすることが可能です。すべての Vue テンプレートは、仕様に準拠しているブラウザーや HTML パーサーでパースできる、構文的に正規の HTML です。

内部では、Vue はテンプレートをコンパイルし、高度に最適化された JavaScript のコードにします。リアクティビティ機構と組み合わせ、Vue はアプリの状態が変化したとき、再レンダリングを必要とする最小限のコンポーネントをインテリジェントに見つけ出すことができます。そして、最小限の DOM 操作を適用します。

仮想 DOM の各種概念をよく知っていて、生の JavaScript が持つパワーを活かしたいという場合には、テンプレートの代わりに render 関数を直接記述することもできます。さらに、オプションで JSX もサポートされています。ただし、これらの書き方をする場合には、コンパイル時の最適化がテンプレートと同等のレベルでは利用できないことに注意してください。

テキスト展開

データバインディングで最も基本の形式は、「マスタッシュ構文」(二重中括弧) によるテキスト展開です:

<span>Message: {{ msg }}</span>

マスタッシュのタグの中身は、対応するコンポーネントのインスタンスが持つ msg というプロパティの値に置き換えられます。msg プロパティが変更されるたびに、マスタッシュの中身も更新されます。

HTMLタグを含めたデータ

マスタッシュの中では、データが HTML ではなくプレーンテキストとして解釈されます。本来の HTML を出力したい場合は、次のように v-html ディレクティブを用いる必要があります:

<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

Using text interpolation: <span style=”color: red”>This should be red.</span>

Using v-html directive: This should be red.

ここで、新たな要素が登場しました。この例にある v-html という属性は、「ディレクティブ」と呼ばれるものです。ディレクティブは v- という接頭辞を持ち、Vue によって提供される特別な属性であることを示します。そしてご想像の通り、ディレクティブはレンダリングされる DOM に、特別なリアクティブな振る舞いを割り当てます。この例では、簡単に言うと、「現在アクティブなインスタンスが持つ rawHtml というプロパティをこの要素の inner HTML に適用して最新に保つ」ということが書かれています。

span の中身は rawHtml プロパティが持つ値に置き換えられ、プレーンな HTML として解釈されます。データバインディングは無視されます。v-html は、テンプレートの断片を組み立てるのには利用できないことに注意してください。これは、Vue が文字列ベースのテンプレートエンジンではないためです。それに代わり、UI の再利用や組み立ての基本単位として推奨されているのが「コンポーネント」です。

セキュリティーに関する警告

ウェブサイト上で任意の HTML を動的にレンダリングすることは、クロスサイトスクリプティング (XSS) 脆弱性を招きやすく、非常に危険です。v-html は信頼できるコンテンツにのみ使用し、ユーザーから渡されるコンテンツには決して使用しないでください。

属性バインディング

HTML 属性の中ではマスタッシュ構文が使えません。代わりに、以下の v-bind ディレクティブを使用します:

<div v-bind:id="dynamicId"></div>

この v-bind ディレクティブは、要素の id という属性を、コンポーネントが持つ dynamicId というプロパティと同期させるよう Vue に指示しています。バインドされた値が null または undefined の場合、その属性はレンダリングされる要素から除外されます。

省略記法

v-bind は使用頻度が非常に高いため、以下の専用の省略記法があります:

<div :id="dynamicId"></div>

: で始まる属性は、普通の HTML の記法とは少し異なるように見えますが、実際には属性名として有効な文字です。Vue をサポートするすべてのブラウザーは、これを正しく解析することができます。なお、これは最終的にレンダリングされるマークアップには現れません。この省略記法を使うかどうかは任意ですが、その使い方を後ほど詳しく知れば、良さがわかるはずです。

このガイドの残りの部分では、Vue を用いる開発者にとって最も一般的な書き方である省略記法をコード例のなかで使用します。

ブーリアン属性

ブーリアン属性は、要素に含まれるかどうかによって「真」または「偽」の値を表す属性です。例えば、disabled は最も一般的に用いられるブーリアン属性の 1 つです。

以下のケースでは、v-bind は少し特別な動作をします:

<button :disabled="isButtonDisabled">Button</button>

この disabled という属性は、isButtonDisabled が 真値 (truthy value) である場合に要素に含まれます。また、<button disabled=""> との一貫性を保つため、値が空の文字列である場合にも含まれます。それ以外の偽値 (falsy values) の場合には、属性が要素から取り除かれます。

複数の属性を動的にバインドさせる

次のような複数の属性を持つ JavaScript オブジェクトがあるとします:

data() {
  return {
    objectOfAttrs: {
      id: 'container',
      class: 'wrapper'
    }
  }
}

以下のように v-bind を引数なしで用いると、これらの複数の属性を 1 つの要素にバインドすることができます:

<div v-bind="objectOfAttrs"></div>

JavaScript の式を用いる

ここまで、テンプレート内のプロパティのキーに単純なバインドを行う方法だけを見てきました。しかし、実は Vue ではあらゆるデータバインディングにおいて、以下のように JavaScript 式のフルパワーを活用することができます:

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div :id="`list-${id}`"></div>

これらの式は、現在のコンポーネントインスタンスのデータスコープ内で、JavaScript の式として評価されます。

Vue のテンプレートでは、以下の場所で JavaScript の式を使用することができます:

  • テキスト展開の内部 (マスタッシュ構文内)
  • 任意の Vue ディレクティブ (v- で始まる特殊な属性) の属性値の中身

式に限られる

それぞれのバインディングには、単一の式しか含めることができません。そのため、以下はうまく動作しません:

<!-- これは文であり、式ではありません: -->
{{ var a = 1 }}

<!-- フロー制御も動作しません。代わりに三項演算子を使用してください。 -->
{{ if (ok) { return message } }}

関数の呼び出し

コンポーネントから公開されているメソッドであれば、以下のようにバインディングの式の内部で呼び出すことができます:

<span :title="toTitleDate(date)">
  {{ formatDate(date) }}
</span>

TIP

バインディングの式の内部で呼び出される関数は、コンポーネントが更新されるたびに呼び出されます。そのため、データの変更や非同期処理をトリガーするような副作用を持たせてはいけません

グローバルへのアクセスの制限

テンプレートで用いる式はサンドボックス内で実行され、限定的なグローバルのリストにのみアクセスできます。このリストには、Math や Date などのよく使われる組み込みグローバルが含まれています。

ユーザーが window に付与したプロパティなど、このリストに明示的に含まれていないグローバルには、テンプレート内の式からアクセスすることができません。ただし、app.config.globalProperties に追加することにより、Vue のあらゆる式で利用できるグローバルを明示的に定義することができます。

ディレクティブ

ディレクティブは、v- という接頭辞を持つ特別な属性です。Vue では、上で紹介した v-html や v-bind をはじめ、数々の組み込みディレクティブが用意されています。

ディレクティブの属性値は、JavaScript の単一の式であることが期待されます (ただし v-forv-onv-slot は例外であり、後ほどそれぞれのセクションで説明します)。ディレクティブの役割は、式が示す値が変化したとき、リアクティブに更新を DOM に適用することです。例えば、v-if を取り上げてみます:

<p v-if="seen">Now you see me</p>

この例では、v-if というディレクティブを用いて、式 seen が示す値の真偽に基づいて要素 <p> を削除したり挿入したりします。

引数

一部のディレクティブは引数を取ることができます。引数は、ディレクティブ名の後にコロンで示します。以下は、v-bind ディレクティブを使って HTML 属性の 1 つをリアクティブに更新する例です:

<a v-bind:href="url"> ... </a>

<!-- 省略記法 -->
<a :href="url"> ... </a>

この例では href が引数です。これにより、要素の href という属性を url という式の値にバインドするという指示が v-bind ディレクティブに伝えられます。省略記法では、引数の前に置かれる v-bind: の部分がすべて : という 1 文字に凝縮されます。

別の例として、DOM イベントをリッスンする v-on ディレクティブを紹介します:

<a v-on:click="doSomething"> ... </a>

<!-- 省略記法 -->
<a @click="doSomething"> ... </a>

この例では、リッスンするイベント名の click が引数です。ごく一部のディレクティブには省略記法の記号として @ を持つものがあり、v-on もその 1 つです。イベントのハンドリングについても、後ほど詳しく説明します。

動的引数

ディレクティブの引数を指す部分では、以下のように角括弧で囲んだ JavaScript の式を用いることもできます:

<!--
引数で使用できる式には、いくつか制約があります。詳細は以下の
「動的引数の値に関する制約」および「動的引数の構文上の制約」セクションで説明します。
-->
<a v-bind:[attributeName]="url"> ... </a>

<!-- 省略記法 -->
<a :[attributeName]="url"> ... </a>

この例では、attributeName が JavaScript の式として動的に評価され、そこで評価された値が最終的な引数を指す値として使用されます。例えば、コンポーネントのインスタンスが attributeName というデータプロパティを持ち、その値が "href" のとき、このバインディングは v-bind:href と同等になります。

同じように、動的引数を用いてハンドラーを動的なイベント名にバインドすることもできます:

<a v-on:[eventName]="doSomething"> ... </a>

<!-- 省略記法 -->
<a @[eventName]="doSomething">

この例では、eventName の値が "focus" のとき、v-on:[eventName] が v-on:focus と同等になります。

動的引数の値に関する制約

動的引数は、評価結果が null または文字列のいずれかになることが期待されます。null は特別な値で、バインディングを削除することを明示的に表します。それ以外の非文字列の値を指定すると、警告が発生します。

動的引数の構文上の制約

動的引数の式には、構文上の制約がいくつかあります。これは、スペースや引用符など特定の文字が HTML の属性名の中では無効となるためです。例えば、次のようなものは無効となります:

<!-- この場合、コンパイラーで警告が発生します。 -->
<a :['foo' + bar]="value"> ... </a>

複雑な動的引数を渡す必要がある場合は、後ほど取り上げる算出プロパティを使用するとよいでしょう。

また、HTML ファイルに直接記述する DOM 内テンプレートを使用する場合、ブラウザーでは属性名が小文字であることが求められるため、以下のように大文字のキー名を使用することは避ける必要があります:

<a :[someAttr]="value"> ... </a>

上のコードは、DOM 内テンプレートでは :[someattr] に変換されます。もしコンポーネントに someattr ではなく someAttr というプロパティしかなければ、このコードは動作しません。

修飾子

修飾子は、ドット (.) で示される特別な接頭辞で、ディレクティブを何らかの特別な方法でバインドすることを表します。例えば、以下に示す .prevent という修飾子は、イベントがトリガーされたときに event.preventDefault() を呼び出すことを v-on ディレクティブに伝えます:

<form @submit.prevent="onSubmit">...</form>

この後、v-on 向けや v-model 向けの修飾子の例を、その機能のページで見ることになるでしょう。

最後に、ディレクティブの構文の全容をこちらの図にまとめました:

Vue JSを始めよう!

準備しておくこと

・NodeJS Version 10~

今回使用するもの

・VueJS バージョン3

公式ドキュメンテーション

https://vuejs.org/guide/introduction.html

イントロ

VueJSはフロントエンドのJavaScriptフレームワークでユーザーインターフェースを作ることができます。

通常のHTML、CSS、JavaScriptに合わせてビルドでき、コンポーネントという概念で開発をより効率よくできます。

他の主要概念として、Declarative Rendering(宣言的レンダリング)やReactivity(反応性)などがありますが、まずは実際にVueJSを触りながら理解していきましょう。

ここでVueJSを開発するうえで2種類のAPIのスタイルがあることを簡単に説明します。この2つはOptionsAPIとCompositionAPIになりますが、CompositionAPIはOptionsAPIの上にできたものなので、まずはOptionsAPIから学ぶことをお勧めします。

ビルドツール

では、早速vueのアプリケーションを作成していきましょう。

Npmでもできますが、今日はvue cliというツールを使っていきます。他にvite(ヴィート)というビルドツールも人気が出てきましたね。色々選択肢が多くてほんと追いつけないっすね。

npmでインストールする方法

このコマンドです。

npm init vue@latest

Vue cliのインストール

npm install -g @vue/cli

# OR

yarn global add @vue/cli


Vue cliのバージョンを確認する

vue --version

Vue cliのバージョンを更新する

npm update -g @vue/cli
# OR

yarn global upgrade --latest @vue/cli

Vue CliでVueプロジェクトを作成する

vue create hello-world

#Helloe-worldの所は自分のプロジェクト名

ここでマニュアルで何をインストールしたいか選択できます。

また、これをプリセットとして保存して再度使う事もできるので便利ですね。

ファイル構成を見る

.gitはバージョンコントロールのGITファイルがあります。

Node_moduleにインストールしたパッケージが格納されます。

例えばBootstrapとか、ChartJSとかですね。

publicにはfav-iconとindex.htmlがあり、vueJSがこの中のid=”app”の部分にアプリをマウントすることになります。

Scrはソースフォルダです。

ここにコンポーネント、ルーティング、ビューのファイルが格納されます。

assetsはグローバルのCSSとか画像を保管するときに使います。

で、App.jsがVueの親のアプリのようなものです。

Main.jsがこの親アプリをどうするか指示するためのファイルになります。

では詳しいファイルの内容は動画で見てくださいね。

お疲れ様です。