Open5

Vue.js を Angular と比較しながら学ぶメモ

Yuma ItoYuma Ito

テンプレート構文

https://ja.vuejs.org/guide/essentials/template-syntax.html

テキスト展開

変数をHTML内で展開するためには、2重中括弧{{}}を利用する。

<span>Message: {{ msg }}</span>
Angularの場合

Angularでも同様。

<h3>Current customer: {{ currentCustomer }}</h3>

生のHTML

プレーンテキストではなくHTMLとして出力したい場合はv-htmlディレクティブを利用する。

<p>Using v-html directive: <span v-html="rawHtml"></span></p>

XSS脆弱性の危険があるため、信頼できるコンテンツにのみ利用し、ユーザーが生成したコンテンツでは決して利用しないこと。

Angularの場合

プロパティバインディングを用いてinnerHTMLプロパティに値をセットする。

<p [innerHTML]="rawHtml"></p>

属性バインディング

v-bindディレクティブを用いてHTML要素の属性とバインディングする。

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

省略記法

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

バインディングされた値がnullorundefindの場合、属性はレンダリングから外れる。

Angularの場合

プロパティバインディングでattr.という接頭辞をつける

<div [attr.id]="dynamicId"></div>

ディレクティブ

v- という接頭辞を持つ特別な属性のこと。Vue.js で用意されている組み込みディレクティブは以下。

https://ja.vuejs.org/api/built-in-directives.html

例:v-bind, v-html, v-onなど。

名前、引数、修飾子、値からなる。

<名前>:<引数>.<修飾子>=<値>
v-on:submit.prevent="onSubmit"
Angularの場合

ngClass, ngStyle, ngModel, *ngIf, *ngForなど。

組み込みディレクティブは以下。

https://angular.jp/guide/built-in-directives

自分でディレクティブを定義することができる。

Yuma ItoYuma Ito

リアクティビティーの基礎

2つのAPIタイプが存在し、コードの記述方法が異なる。

  • Options API
    • コンポーネントのインスタンスを中心とした記述方法
    • 記述方法がシンプルで初心者にとって分かりやすい
  • Composition API
    • リアクティブな状態変数を宣言し、複数の関数の組み合わせによって複雑な処理を行う、という考え方
    • 自由度が高いが、どのような仕組みで動いているか理解する必要がある
Angularの場合

Angularはコードの記述方法は統一されている。
Vue.jsのComposition APIは RxJSと同じようなもの(だと思われる)

Yuma ItoYuma Ito

まずは、Options API のスタイルで学ぼうと思います。

リアクティブな状態の宣言

dataオプションを用いて、コンポーネントのリアクティブな状態(変数)を宣言します。

export default {
  data() {
    return {
      count: 1
    }
  },

  // `mounted` は、後で説明するライフサイクルフックです。
  mounted() {
    // `this` は、コンポーネントのインスタンスを指します。
    console.log(this.count) // => 1

    // データは、変化することがある。
    this.count = 2
  }
}

dataオプションが返すオブジェクトに状態を含めることで、リアクティブな処理を行うことができる。
インスタンスが生成されたときにのみ追加されるので、必要ならばnullundefindを用いてまだ利用できない状態を宣言する。

Angularの場合

コンポーネントクラスのプロパティとして定義すれば良い。

@Component({
  selector:    'app-hero-list',
  templateUrl: './hero-list.component.html',
  providers:  [ HeroService ]
})
export class HeroListComponent {
  heroes: Hero[] = [];
  selectedHero: Hero | undefined;
}
Yuma ItoYuma Ito

メソッドの宣言

methodsオプションを利用して、インスタンスにメソッドを追加する。

export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++
    }
  },
  mounted() {
    // メソッドは、ライフサイクルフックで呼び出すこともできますし、他のメソッドでも呼び出せます!
    this.increment()
  }
}

methodsthisは自動的にコンポーネントインスタンスを参照する。よって、methodsを定義する際にアロー関数を用いてはならない。

export default {
  methods: {
    increment: () => {
      // BAD: ここでは `this` アクセスができません!
    }
  }
}

コンポーネントのテンプレート内からアクセスすることができる。

<button @click="increment">{{ count }}</button>
Angularの場合

こちらもComponentクラス内で宣言すれば良い

@Component({
  selector:    'app-hero-list',
  templateUrl: './hero-list.component.html',
  providers:  [ HeroService ]
})
export class HeroListComponent {
  heroes: Hero[] = [];
  selectedHero: Hero | undefined;

  selectHero(hero: Hero) { this.selectedHero = hero; }
}