開発者ドキュメント

スロット、ミックスイン、CompositionAPIを使用してVue.jsアプリケーションをドライにする方法

著者は、 Write for DOnations プログラムの一環として、 Open Sourcing MentalIllnessを選択して寄付を受け取りました。

序章

DRY は、「Don’tRepeatYourself」の略であるプログラミング戦略です。 コードが繰り返されるのではなく再利用されるモジュラーアーキテクチャを通じて、コードの再利用を促進します。 これにより、動的でスケーラブルなコードが得られることがよくあります。 つまり、この原則は、プログラマーがコードを繰り返したり、アプリケーションで値をハードコーディングしたりしないようにするためのものです。

Vue.js には、コードの繰り返しスニペットをモジュール化して再利用するためのいくつかの戦略が含まれています。 このチュートリアルでは、サンプルのVue.jsアプリケーションをDRYにして、これらの戦略を試してみます。 チュートリアルでは、 templatescript コンポーネント内で乾燥させます。 経由でコンテンツを配置できるHTML構造を確立するレイアウトコンポーネントを使用します slots. 次に、 mixins を使用します。これは、以下を含むJavaScriptファイルです。 data, methods、 と computed 既存のコンポーネントオプションと混合するプロパティ。 最後に、Vue3で導入された新しいCompositionAPIを使用します。 Composition APIは、コンポーネントを構造化するための別の方法であり、コンポーネントのプロパティの統合を促進します。

前提条件

ステップ1—サンプルアプリケーションのセットアップ

スケーラブルでDRYVue.jsコードを作成する方法を説明するために、最初にサンプルアプリケーションをセットアップします。 このサンプルアプリケーションは、空港カードのリストを表示するメイン/詳細アプリケーションになります。 クリックすると、これらのカードは、その空港に関する追加の詳細を含む別のビューに移動します。

まず、新しいVue.jsアプリケーションを作成する必要があります。 これを行うには、ターミナルで次のコマンドを実行します。

  1. vue create favorite-airports

プロンプトが表示されたら、 Manually select features. 選択する次のオプションは次のとおりです。 Choose Vue version, Babel、 と Router. 選択したら、 RETURN キーを押して、次のようにプロンプトに入力し続けます。

Output
Vue CLI v4.5.15 ? Please pick a preset: Manually select features ? Check the features needed for your project: Choose Vue version, Babel, Router ? Choose a version of Vue.js that you want to start the project with 3.x ? Use history mode for router? (Requires proper server setup for index fallback in production) Yes ? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files

一度 favorite-airports プロジェクトが作成されたら、ターミナルウィンドウを開いて cd (ディレクトリを変更)に favroite-airports ルートフォルダ。 ディレクトリを変更したら、このプロジェクトのすべてのローカルデータを保持する新しいディレクトリを作成します。

  1. mkdir src/data

このフォルダ内に、という名前の新しいJavascriptファイルを作成します src/data/airports.js 選択したテキストエディタで開きます。 アプリにサンプルデータを提供するには、次のコンテンツをファイルに追加します。

お気に入り-airports/src / data / airports.js
export default [
  {
    name: 'Cincinnati/Northern Kentucky International Airport',
    abbreviation: 'CVG',
    city: 'Hebron',
    state: 'KY',
    destinations: {
      passenger: [ 'Toronto', 'Seattle/Tacoma', 'Austin', 'Charleston', 'Denver', 'Fort Lauderdale', 'Jacksonville', 'Las Vegas', 'Los Angeles', 'Baltimore', 'Chicago', 'Detroit', 'Dallas', 'Tampa' ],
      cargo: [ 'Anchorage', 'Baltimore', ' Chicago' , 'Indianapolis', 'Phoenix', 'San Francisco', 'Seattle', 'Louisville', 'Memphis' ]
    }
  },
  {
    name: 'Seattle-Tacoma International Airport',
    abbreviation: 'SEA',
    city: 'Seattle',
    state: 'WA',
    destinations: {
      passenger: [ 'Dublin', 'Mexico City', 'Vancouver', 'Albuquerque', 'Atlanta', 'Frankfurt', 'Amsterdam', 'Salt Lake City', 'Tokyo', 'Honolulu' ],
      cargo: [ 'Spokane', 'Chicago', 'Dallas', ' Shanghai', 'Cincinnati', 'Luxenbourg', 'Anchorage', 'Juneau', 'Calgary', 'Ontario' ]
    }
  },
  {
    name: 'Minneapolis-Saint Paul International Airport',
    abbreviation: 'MSP',
    city: 'Bloomington',
    state: 'MN',
    destinations: {
      passenger: [ 'Dublin', 'Paris', 'Punta Cana', 'Winnipeg', 'Tokyo', 'Denver', 'Tulsa', 'Washington DC', 'Orlando', 'Mexico City' ],
      cargo: [ 'Cincinnati', 'Omaha', 'Winnipeg', 'Chicago', 'St. Louis', 'Portland', 'Philadelphia', 'Milwaukee', 'Ontario' ]
    }
  }
]

これは、米国内のいくつかの空港で構成されるオブジェクト配列です。 このアプリケーションのメインビューでは、このデータを反復処理して、 name , abbreviation, city、 と state プロパティ。

保存 data/airports.js ターミナルに戻ります。

その手順を完了したら、次の名前の単一ファイルコンポーネント(SFC)を作成します。 AirportCard.vue. このファイルは components プロジェクトのディレクトリであり、空港カードのすべてのスタイルとロジックが含まれます。 開ける AirportCard.vue テキストエディタで、以下を追加します。

お気に入り-airports/src / components / AirportCard.vue
<template>
  <div class="airport">
    <p>{{ airport.abbreviation }}</p>
    <p>{{ airport.name }}</p>
    <p>{{ airport.city }}, {{ airport.state }}</p>
  </div>
</template>

<script>
export default {
  props: {
    airport: {
      type: Object,
      required: true
    }
  }
}
</script>

<style scoped>
.airport {
  border: 3px solid;
  border-radius: .5rem;
  padding: 1rem;
  margin-bottom: 1rem;
}

.airport p:first-child {
  font-weight: bold;
  font-size: 2.5rem;
  margin: 1rem 0;
}

.airport p:last-child {
  font-style: italic;
  font-size: .8rem;
}
</style>

このコードスニペットにCSSが含まれていることに気付くかもしれません。 の中に AirportCard.vue コンポーネント、ラッパー <div> のクラスが含まれています airport. このCSSは、各空港に「カード」の外観を与えるために境界線を追加することにより、生成されたHTMLにスタイルを追加します。 The :first-child:last-child 最初と最後に異なるスタイルを適用する疑似セレクターです <p> 内部のHTMLのタグ <div> クラスの要素 airport. それに加えて、このコンポーネントには prop が含まれていることに気付くかもしれません。これは、Vue.jsでは親コンポーネントから子コンポーネントにデータを渡す方法です。

ファイルを保存して終了します。

この設定をまとめる前に、既存のものを交換してください views/Home.vue 次のコンポーネントコード:

お気に入り-airports/src / views / Home.vue
<template>
  <div class="wrapper">
    <div v-for="airport in airports" :key="airport.abbreviation">
      <airport-card :airport="airport" />
    </div>
  </div>
</template>

<script>
import allAirports from '@/data/airports.js'
import AirportCard from '@/components/AirportCard.vue'

export default {
  components: {
    AirportCard
  },
  data() {
    return {
      airports: allAirports
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-column-gap: 1rem;
  max-width: 960px;
  margin: 0 auto;
}

p,
h3 {
  grid-column: span 3;
}
</style>

このコードには、v-forループが含まれています。 airports.js データと一連のレンダリング AirportCards.vue 小道具を介して渡された空港データを含むコンポーネント :airport. このコードを保存して、コマンドラインに戻ります。

プロジェクトを設定したら、を使用してローカル開発サーバーを実行します。 npm run serve ターミナルのコマンド:

  1. npm run serve

これにより、サーバーが起動します localhost、通常は港で 8080. 選択したWebブラウザを開き、次のWebサイトにアクセスします。 localhost:8080 以下を参照してください。

サンプルアプリケーションがセットアップされたので、次のステップでは、後でページレイアウトとして使用できる2つの異なるVue.jsコンポーネントを作成します。

ステップ2—使用 slot レイアウトコンポーネントを作成するには

レイアウトコンポーネントは、 slot さまざまなコンテンツで再利用できるHTMLテンプレートを構成する要素。 これらは、2列または3列のレイアウトなど、再利用したい複数のテンプレートがある場合に最適です。

レイアウトコンポーネントを作成するには、最初にそれらが存在するディレクトリを作成します。 あなたはそれらを入れることができます components ただし、これらのコンポーネントには非常に特殊な役割があるため、それらを区別すると、プロジェクトは他のプログラマーにとって読みやすくなります。 と呼ばれるディレクトリを作成します layouts の中に src ディレクトリ:

  1. mkdir src/layouts

次に、ファイルを作成します layouts 名前の付いたディレクトリ DefaultLayout.vue. The DefaultLayout.vue コンポーネントは、ビューのコンテンツを含み、ブラウザウィンドウの中央に配置するラッパーになります。 開ける DefaultLayout.vue テキストエディタで、以下を追加します。

お気に入り-airports/src / layouts / DefaultLayout.vue
<template>
  <div class="default-layout">
    <slot />
  </div>
</template>

<style scoped>
  .default-layout {
    max-width: 960px;
    margin: 0 auto;
  }
</style>

このコンポーネントは div のクラスで default-layout. このクラスを利用して、いくつかのスタイルを追加できます。 上記のコンポーネントに表示されるCSSスタイルは、その幅を最大 960px、サイドマージンは自動です。 これにより、 div ブラウザウィンドウで水平方向に。 The slot elementはデフォルトのスロットです。 2つの間に置かれるもの <layout-default> タグはこれがどこに注入されます <slot /> は。 リファクタリングしてこれを試すことができます Home.vue 前の手順で変更したもの。

あなたの DefaultLayout.vue ファイル。 テキストエディタで、 src/views/Home.vueimport the DefaultLayout.vue 成分。

お気に入り-airports/src / views / Home.vue
...
<script>
import allAirports from '@/data/airports.js'
import AirportCard from '@/components/AirportCard.vue'
import DefaultLayout from '@/layouts/DefaultLayout.vue'

export default {
  components: {
    AirportCard,
    DefaultLayout
  },
  data() {
    return {
      airports: allAirports
    }
  }
}
</script>
...

とともに DefaultLayout.vue コンポーネントがインポートされ、含まれているものを置き換えることができるようになりました <div /><default-layout />.

お気に入り-airports/src / views / Home.vue
<template>
  <default-layout class="wrapper">
    <div v-for="airport in airports" :key="airport.abbreviation">
      <airport-card :airport="airport" />
    </div>
  </default-layout>
</template>
...

これで、を削除できます max-widthmargin のプロパティ .wrapper を含み、中央に配置するクラス div. このファイルを保存して開きます localhost:8080 ブラウザウィンドウで。 視覚的には何も変わりませんが、中央にコンテンツを含めるための新しいレイアウトコンポーネントができました div.

次の手順に進む前に、もう1つのレイアウトコンポーネントを作成します。 これは2列のレイアウトになります。 1つの列は補足情報用で、もう1つの列はビューのメインコンテンツ用です。 で新しいファイルを作成します src/layouts/TwoColumnLayout.vue. 作成したら、開きます TwoColumnLayout.vue テキストエディタのコンポーネントを追加し、以下を追加します。

お気に入り-airports/src / layouts / TwoColumnLayout.vue
<template>
  <div class="two-column-layout">
    <aside>
      <slot name="sideBar" />
    </aside>
    <main>
      <slot name="content" />
    </main>
  </div>
</template>

<style>
  .two-column-layout {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-column-gap: 1rem;
  }

  .two-column-layout aside,
  .two-column-layout main {
    border: 1px solid;
    border-radius: 5px;
  }

  .two-column-layout aside {
    grid-column: span 1;
  }

  .two-column-layout main {
    grid-column: span 2;
  }
</style>

このコンポーネントには、サイドバー用とメインコンテンツ用の2つの名前付きスロットがあります。 含む上で <div>、CSSを使用して3つの列のグリッドを作成し、1つは1つの列にまたがり、もう1つは2つの列にまたがっています。

このレイアウトを使用するには、空港の詳細ビューの新しいビューを作成します。 src/views/AirportDetail.vue、次に次のコードを新しいファイルに追加します。

お気に入り-airports/src / views / AirportDetail.vue
<template>
  <two-column-layout>
    <template v-slot:sideBar>
      <p>Sidebar</p>
    </template>
    <template v-slot:content>
      <p>Main Content</p>
    </template>
  </two-column-layout>
</template>

<script>
import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'

export default {
  components: {
    TwoColumnLayout
  },
}
</script>

この新しいビューはインポートします TwoColumnLayout.vue その後、 v-slot 名前付きスロットを適切なコンテンツで埋めます。

このファイルを保存します。 このビューを表示可能にするには、 Vuerouterファイルにルートを追加します。

お気に入り-airports/src / router / index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import AirportDetail from '../views/AirportDetail'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/airport/:code',
    name: 'AirportDetail',
    component: AirportDetail
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]
...

ここでは、訪問したときにロードされるルートを登録しています AirportDetail.vue 成分。 The :code の中に path は、後で特定の空港のデータを取得するために活用できる引数です。

ファイルを保存してから、ブラウザを開いて localhost:8080/airport/cvg. あなたは以下を見つけるでしょう:

このステップでは、スロットを利用してレイアウトコンポーネントを作成しました。 これらのレイアウトコンポーネントは、ウェブページの構造を作成するときに重複するコードを排除することで、アプリをドライに保つのに役立ちます。 次のステップでは、コンポーネント間でメソッドとプロパティを共有するためにミックスインを試してみます。

ステップ3—ミックスインを使用してメソッドとプロパティを共有する

ミックスインは、再利用可能なコンポーネントオプションを任意の数のコンポーネントに再配布する方法です。 ミックスインがインポートされると、ミックスインのコンポーネントオプションが現在のコンポーネントに「ミックスイン」されます。 これを説明するために、このステップでは最初にミックスイン構文の例を実行し、次にミックスインをサンプルアプリに追加します。

一意のプロパティを持つ2つのファイルがあるとします。 最初のものは data 次のようなメソッドと計算されたプロパティ:

サンプルコンポーネント
<script>
  export default {
    data() {
      return {
        firstName: 'Dave',
        lastName: 'Berning'
      }
    },
    computed: {
      fullName() {
        return `${this.firstName} ${this.lastName}`
      }
    }
  }
</script>

2つ目は、再利用したいいくつかのコンポーネントオプションを含むファイルです。

someMixin
export default {
  data() {
    return {
      counter: 0
    }
  },
  methods: {
    increment() {
      this.counter++
    }
  }
}

ミックスインをインポートすることで、これら2つのファイルを一緒にミックスできます(someMixin)コンポーネントに(sample-component). この架空のコンポーネントでは、次のコマンドを使用してインポートします。 import キーワードを使用して割り当てます mixin 財産:

サンプルコンポーネント
<script>
import someMixin from '@/mixins/someMixin'
      
export default {
  data() {
    return {
      firstName: 'Dave',
      lastName: 'Berning'
    }
  },
  mixins: [ 'someMixin' ],
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`
    }
  }
}
</script>

インポートすると、架空のコンポーネントはすべてにアクセスできます methods, data, computed プロパティ、およびそれに含まれる可能性のあるその他のコンポーネントオプション。

次に、を含むミックスインを作成します methoddata 財産。 この機能は空港を結合します nameabbreviation に保存します data 財産。

ターミナルで、を使用して新しいディレクトリを作成します mkdir 指図:

  1. mkdir src/mixins

名前の付いたファイルを作成します src/mixins/airport.jsexport 次のプロパティを含むオブジェクト:

src / mixins / airport.js
export default {
  data() {
    return {
      airportWithCode: ''
    }
  },
  methods: {
    getAirportWithCode(airport) {
      this.airportWithCode = `${airport.name} - ${airport.abbreviation}`
    }
  }
}

このオブジェクトには、 data methodとmethodは、データを空港の名前と略語に設定します。 このファイルを保存します。

これを作成したら、にインポートします Home.vue 見る。 これを活用します methoddata ユーザーがカードをクリックしたときに返される文字列を表示するプロパティ:

src / views / Home.vue
<template>
  <default-layout class="wrapper">
    <div v-for="airport in airports" :key="airport.abbreviation" @click="getAirportWithCode(airport)">
      <airport-card :airport="airport" />
    </div>
    <p>test: {{ airportWithCode }}</p>
  </default-layout>
</template>

<script>
import allAirports from '@/data/airports.js'
import AirportCard from '@/components/AirportCard.vue'
import DefaultLayout from '@/layouts/DefaultLayout.vue'
import airportMixin from '@/mixins/airport.js'

  export default {
    components: {
      AirportCard,
      DefaultLayout
    },
    mixins: [ airportMixin ],
    data() {
      return {
        airports: allAirports
      }
    }
  }
</script>
...

あなたはにアクセスできるので methodsdata そのミックスイン内で、他のコンポーネントオプションと同じようにそれらを参照できます。 このコードスニペットでこれを実行して、 airportWithCode ユーザーがカードをクリックしたときの値。次に、段落要素に文字列値をレンダリングします。 ファイルを保存します。

次に、この同じミックスインをで再利用します AirportDetail.vue. 開ける AirportDetail.vue テキストエディタで、JavaScriptを記述します filter を返すには airport オブジェクトの場合 abbreviation 一致します :code 以前にルーターで定義された引数:

src / views / AirportDetail.vue
...
<script>
import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
import allAirports from '@/data/airports.js'
  
export default {
  components: {
    TwoColumnLayout
  },
  data() {
    return {
      airport: ''
    }
  },
  methods: {
  getAirportByCode() {
    return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
    }
  },
  mounted() {
    this.airport = this.getAirportByCode()
  }
}
</script>

このスニペットでは、新しいものを作成しています method 名前付き getAirportByCode これは、空港データをフィルタリングして、ルートURLの略語と一致する略語を持つ空港オブジェクトを返します。 マウント時に、 airport 返されるそのオブジェクトへのデータプロパティ。

ファイルを保存します。 次に、前に使用したミックスインをインポートします。 同じことを活用します datamethod 以前に行ったプロパティ:

src / views / AirportDetail.vue
<template>
  <two-column-layout>
    <template v-slot:sideBar>
      <p>Sidebar</p>
    </template>
    <template v-slot:content>
      <p>Main Content</p>
      <p>{{ airportWithCode }}</p>
    </template>
  </two-column-layout>
</template>

<script>
import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
import allAirports from '@/data/airports.js'
import airportMixin from '@/mixins/airport.js'

export default {
  components: {
    TwoColumnLayout
  },
  mixins: [ airportMixin ],
  data() { ... },
  methods: { ... },
  mounted() {
    this.airport = this.getAirportByCode()
    this.getAirportWithCode(this.airport)
  }
}
</script>

特定の空港を決定したので getAirportByCode() に設定します this.airport、これで使用できます getAirportWithCode の値を設定する方法 airportWithCode ミックスインから。 次に、その変数をテンプレートに追加して値を表示できます。

このファイルを保存して開きます localhost:8080/airport/cvg ブラウザウィンドウで。 の文字列値が見つかります airportWithCode 次の画像に示すように、メインコンテンツセクションでレンダリングされます。

このステップでは、ミックスインを使用して、コンポーネント間でメソッドと計算されたプロパティを共有しました。 ミックスインは、コンポーネントを整理し、アプリケーション全体で再利用可能なコードを活用するための優れた方法です。 次に、新しいComposition API、それが作成された理由、および次のVueアプリケーションの構成を改善する方法について学習します。

ステップ4—コンポジションAPIを使用する

このチュートリアルでこれまでに試したミックスインとレイアウトコンポーネントは、Vue2以前を含むVueのすべてのメジャーバージョンで使用できます。 これらはオプションAPIを構成します。 ただし、Vue 3には、アプリケーションをDRYにするために使用できる別のAPIがあります。CompositionAPIです。

Composition APIは、コンポーネントを設定するための新しい方法です。 のための別々のセクションを持つ代わりに data, computed, methods、 と props、あなたはシングルを持っています setup すべてが住んでいるフック。 この中で setup プロパティでは、コンポーネントが作成される前にコンポーネントが動作するために必要なすべてのものがここに入ります。 さらに、OptionsAPIでオプションを定義するために必要なすべてのものをインポートする必要があります。 しかし、これはコンポジションAPIには当てはまりません。

このステップでは、コンポーネントの1つをOptionsAPIの使用から新しいCompositionAPIにリファクタリングします。

テキストエディタで、 AirportDetail.vue 成分。 現在、このコンポーネントにミックスインがインポートされています。 そのミックスインは、いくつかの関数とデータプロパティを提供します。 ただし、Composition APIでは、コンポーネントがレンダリングする必要のあるものはすべて、 setup 方法; このメソッドをインポートする必要はありません。

ミックスインのインポートを削除し、 setup 下の方法 mounted:

お気に入り-airports/src / views / AirportDetail.vue
...
<script>
import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
import allAirports from '@/data/airports.js'

export default {
  components: { ... },
  methods: {
    getAirportByCode() {
      return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
    }
  },
  mounted() { ... },
  setup() {
  
  }
}
</script>

あなたと setup メソッドが作成されたら、新しいメソッドを追加してリファクタリングを開始します onMounted ライフサイクルフック。 The onMounted 関数は1つの引数、通常は無名関数を受け入れます。

お気に入り-airports/src / views / AirportDetail.vue
...
<script>
import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
import allAirports from '@/data/airports.js'
import { onMounted } from 'vue'

export default {
  components: { ... },
  methods: {
    getAirportByCode() {
      return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
    }
  },
  mounted() { ... },
  setup() {
    onMounted(() => {
      
    })
  }
}
</script>

このコンポーネントがマウントされると、現在の空港オブジェクトをリアクティブデータプロパティに保存します。 変数または定数をリアクティブにするには、値を ref インポート元の関数 vue. 定数の名前は、あなたの参照の名前になります setuptemplate コンポーネントのセクション。 また、を削除します getAirportByCode から methods 内部の通常のJavaScript関数のように定義します setup:

お気に入り-airports/src / views / AirportDetail.vue
...
<script>
import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
import allAirports from '@/data/airports.js'
import { onMounted, ref } from 'vue'

export default {
  components: { ... },
  mounted() { ... },
  setup() {
    function getAirportByCode() {
      return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
    }
      
    onMounted(() => {
      const airport = ref(getAirportByCode())
    })
  }
}
</script>

それを行った後、先に進んで古いものを削除することができます mountedmethods コンポーネントファイルのプロパティ。

現在ミックスインを使用していないので、次のように定義します getAirportWithCode あなたの内側 setup 関数とそれを変数に割り当てます airportWithCode したがって、ビューで使用できます。

お気に入り-airports/src / views / AirportDetail.vue
...
<script>
import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
import allAirports from '@/data/airports.js'
import { onMounted, ref } from 'vue'

export default {
  components: {
    TwoColumnLayout
  },
  setup() {
    const airportWithCode = ref('')
    
    function getAirportByCode() {
      return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
    }
      
    function getAirportWithCode(airport) {
      return `${airport.name} - ${airport.abbreviation}`
    }

      onMounted(() => {
        const airport = ref(getAirportByCode())
      })
    }
  }
</script>

Composition APIを使用したリアクティブデータプロパティに関する非常に重要なことの1つは、 ref オブジェクトを返します。 値にアクセスするには、その値にアクセスする必要があります .value 財産:

お気に入り-airports/src / views / AirportDetail.vue
...
<script>
import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
import allAirports from '@/data/airports.js'
import { onMounted, ref } from 'vue'

export default {
  components: {
    TwoColumnLayout
  },
  setup() {
    const airportWithCode = ref('')

    function getAirportByCode() {
      return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
    }

    function getAirportWithCode(airport) {
      return `${airport.name} - ${airport.abbreviation}`
    }

    onMounted(() => {
      const airport = ref(getAirportByCode())
      airportWithCode.value = getAirportWithCode(airport.value)
    })
  }
}
</script>

これをCompositionAPIを使用して完全に変換する前に、2つのことを行う必要があります。 最初に変更する必要があるのは this.$route の中に getAirportByCode 関数。 Composition APIでは、ルートまたはルーターにアクセスすることはできません。 this.$routethis.$router、 それぞれ。

ルートにアクセスするには、 useRoute から vue-router パッケージ。 これをに保存することをお勧めします const アプリケーション全体で参照できること:

お気に入り-airports/src / views / AirportDetail.vue
...
<script>
import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
import allAirports from '@/data/airports.js'
import { onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'

export default {
  components: {
    TwoColumnLayout
  },
  setup() {
    const route = useRoute()
    const airportWithCode = ref('')

    function getAirportByCode() {
      return allAirports.filter(airport => airport.abbreviation === route.params.code.toUpperCase())[0]
    }

    function getAirportWithCode(airport) {
      return `${airport.name} - ${airport.abbreviation}`
    }

    onMounted(() => {
      const airport = ref(getAirportByCode())
      airportWithCode.value = getAirportWithCode(airport.value)
    })
  }
}
</script>

それが終わったら、あなたのオブジェクトを返します setup 関数。 このオブジェクトで返されるプロパティは、 template:

お気に入り-airports/src / views / AirportDetail.vue
...
  setup() {
    const route = useRoute()
    const airportWithCode = ref('')

    function getAirportByCode() {
      return allAirports.filter(airport => airport.abbreviation === route.params.code.toUpperCase())[0]
    }

    function getAirportWithCode(airport) {
      return `${airport.name} - ${airport.abbreviation}`
    }

    onMounted(() => {
      const airport = ref(getAirportByCode())
      airportWithCode.value = getAirportWithCode(airport.value)
    })
    
    return { airportWithCode }
  }
}
</script>

コードを保存してリロードします localhost:8080/airport/cvg ブラウザで。 コードをリファクタリングした後、レンダリングされる内容に変更はありません。 ただし、現在、CompositionAPIを利用しています。

結論

このチュートリアルでは、アプリケーションをDRYにするためのいくつかの戦略を試しました。 具体的には、複数のビューでレイアウトコンポーネントを再利用してから、モジュール化されたプロパティとメソッドをミックスインで再利用しました。 最後に、Vue3で導入された新しいCompositionAPIを使用するようにアプリをリファクタリングしました。 このAPIは、コンポーネントが作成される前にコンポーネントをセットアップする新しい方法であり、より多くの状況で機能するようになります。

MixinsまたはCompositionAPI について詳しく知りたい場合は、Vueの公式ドキュメントを確認することを強くお勧めします。 Vueのその他のチュートリアルについては、Vue.jsシリーズページを使用してWebサイトを開発する方法を確認してください。

モバイルバージョンを終了