Vue、GraphQL、およびApolloクライアントを使用してブログを構築する方法
序章
この記事では、GraphQLサーバーを利用するブログを作成します。 ApolloクライアントとVueを使用してブログアプリを構築します。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Node.jsはローカルにインストールされます。これは、Node.jsのインストール方法とローカル開発環境の作成に従って実行できます。
- MySQLがローカルにインストールされ、実行されています。これは、MySQLのインストール方法に従って実行できます。
このチュートリアルは、JavaScriptの知識と、VueおよびGraphQLにある程度精通していることを前提としています。
このチュートリアルは、Nodev14.4.0で検証されました。 npm
v6.14.5、MySQL v14.14、 @adonisjs/cli
v4.0.12、 @vue/cli
v4.4.6、 vue
v2.5.2、 graphql
v15.1.0、および apollo-client
v2.6.10。
GraphQLサーバーの作成
GraphQLサーバーを入手して、チュートリアルを進めることができます。
リポジトリのクローンを作成したら、GraphQLサーバーのプロジェクトディレクトリに移動します。
- cd adonis-graphql-server
必要なパッケージをインストールします。
- npm install
コピー .env.example
に .env
:
- cp .env.example .env
編集します .env
必要に応じてファイルを作成し、データベース情報が実行中のMySQLデータベースの適切な資格情報を提供するようにします。 DB_USER
と DB_PASSWORD
変更が必要な場合があります。
アドニスのキーを生成します。
- npx @adonisjs/cli key:generate
データベース構成を移行します。
- npx @adonisjs/cli migration:run
CORSの有効化
GraphQLサーバーはAdonisJSで構築されました。 AdonisJSは、APIでクロスオリジンリソースシェアリング(CORS)を処理するために使用できるパッケージを提供します。 AdonisJSではデフォルトでCORSがオフになっているため、有効にする必要があります。
AdonisJSアプリでCORSを有効にするために、 origin
に true
の config/cors.js
以下のように:
origin: true
クローン化されたGraphQLサーバーではCORSがすでに有効になっていますが、言及する価値があります。
GraphQLサーバーの起動
ブログアプリはGraphQLサーバーを利用するため、サーバーを起動して、チュートリアルの残りの部分でサーバーを実行し続ける必要があります。
開始するには、GraphQLサーバーのプロジェクトディレクトリにいることを確認し、以下のコマンドを実行します。
- npx @adonisjs/cli serve --dev
これにより、GraphQLサーバーが起動し、実行を継続します。
チュートリアルの残りの部分では、GraphQLサーバーが既に起動されており、実行されていることを前提としています。
それが済んだら、ブログアプリの作成を始めましょう。
ステップ1—Vueアプリを作成する
まず、VueCLIを使用して新しいVueアプリを作成します。
- npx -p @vue/cli -p @vue/cli-init vue init webpack graphql-blog-app
注:最新のVueプロジェクトは以下を利用できます:
- npx @vue/cli create graphql-blog-app
プロジェクトに関する質問が表示されます。 行われた選択のいくつかを次に示します。 このチュートリアルでは、インストールすることが重要になります vue-router
:
? Project name graphql-blog-app
? Project description A Vue.js project
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm
これにより、名前が付いた新しいVueアプリが作成されます graphql-blog-app
依存関係をインストールします。
新しく作成されたディレクトリに移動します。
- cd graphql-blog-app
アプリケーションは、端末で次のコマンドを実行することにより、いつでもブラウザで実行および表示できます。
- npm start
ステップ2—パッケージのインストール
アプリを作成したら、GraphQLブログアプリの構築に必要なパッケージのインストールに進むことができます。
- npm install --save vue-apollo graphql apollo-client apollo-link apollo-link-context apollo-link-http apollo-cache-inmemory graphql-tag
各パッケージを簡単に見ていきましょう。
vue-apollo
:VueJS用のApollo/GraphQL統合。 プラグインの最新バージョンをインストールして、Apolloクライアント2.0に付属するすべての優れた機能を使用できるようにします。graphql
:JavaScript用のGraphQLのリファレンス実装。apollo-client
:すべてのサーバーまたはUIフレームワーク用のフル機能の本番環境対応のキャッシングGraphQLクライアント。apollo-link
:GraphQLリクエストの制御フローを変更し、GraphQL結果をフェッチするための標準インターフェース。apollo-link-context
:操作のコンテキストを設定するために使用されます。これは、チェーンのさらに下流にある他のリンクによって使用されます。apollo-link-http
:HTTPフェッチを使用してネットワーク経由でGraphQLの結果を取得するために使用されます。apollo-cache-inmemory
:ApolloClient2.0のキャッシュ実装。graphql-tag
:GraphQLクエリを解析するJavaScriptテンプレートリテラルタグ。
ステップ3—VueApolloを設定する
次に、使用するパッケージを配置しましょう。 まず、 ApolloClient
インスタンスをインストールし、 VueApollo
プラグイン。 開ける src/main.js
以下のコードを追加します。
// ...
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import VueApollo from 'vue-apollo'
const httpLink = new HttpLink({
// URL to graphql server, you should use an absolute URL here
uri: 'http://localhost:3333/graphql'
})
// create the apollo client
const apolloClient = new ApolloClient({
link: httpLink,
cache: new InMemoryCache()
})
// install the vue plugin
Vue.use(VueApollo)
の新しいインスタンスを作成します httpLink
URL(http://localhost:3333/graphql
)私たちのGraphQLサーバーの。 次に、を使用してApolloクライアントを作成します httpLink
上で作成し、メモリ内キャッシュが必要であることを指定します。 最後に、VueApolloプラグインをインストールします。
次に、を作成しましょう apolloProvider
ルートコンポーネントで指定するオブジェクト:
// ...
const apolloProvider = new VueApollo({
defaultClient: apolloClient
})
// update Vue instance by adding `apolloProvider`
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
apolloProvider,
template: '<App/>',
components: { App }
})
を使用してVueApolloプラグインの新しいインスタンスを作成します apolloClient
デフォルトのクライアントとして作成されました。 最後に、 apolloProvider
Vueルーターを使用するのと同じ方法で、Vueインスタンスにオブジェクトを追加します。
ステップ4—ブルマを追加する
このチュートリアルでは、 BullmaCSSを使用します。 それでは、に追加しましょう。 開ける index.html
以下のように更新します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>GraphQL Blog App</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.1/css/bulma.min.css">
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
このコンテンツ配信ネットワーク(CDN)でBulmaを参照します。
ステップ5—未使用のコードを削除する
このチュートリアルでは使用しないVueアプリを作成したときに、いくつかのファイルとコードが付属していました。 それらがアプリに干渉しないように、それらを削除しましょう。
を削除します HelloWorld
コンポーネントとそのすべての参照をから削除します src/router/index.js
.
ステップ6—プライマリレイアウトを作成する
ブログは、ページ全体で一般的なレイアウトを使用します。 その場合、すべてのページが使用するレイアウトを定義しましょう。 これを行うには、 src/App.vue
以下のように更新します。
<template>
<div id="app">
<nav class="navbar is-primary" role="navigation" aria-label="main navigation">
<div class="container">
<div class="navbar-brand">
<router-link class="navbar-item" to="/">Blog App</router-link>
<button class="button navbar-burger">
<span></span>
<span></span>
<span></span>
</button>
</div>
</div>
</nav>
<router-view/>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
すべてのページが使用するヘッダーを追加します。
ステップ7—ユーザーサインアップページの作成
ユーザーはブログアプリにサインアップできるはずです。 作成します SignUp
それを処理するコンポーネント。 だから、内 src/components
新しいを作成します Admin
フォルダ。 管理者関連のすべてのコンポーネントは、このフォルダー内に作成されます。
作成する前に SignUp
コンポーネントでは、すべてのGraphQLクエリとミューテーションを保持する専用ファイルを作成しましょう。 このファイルを直接内部に作成します src
. 作成する graphql.js
内部のファイル src
以下のコードを貼り付けます。
import gql from 'graphql-tag'
export const SIGNUP_MUTATION = gql`
mutation SignupMutation($username: String!, $email: String!, $password: String!) {
createUser(
username: $username,
email: $email,
password: $password
) {
id
username
email
}
}
`
これは、GraphQLサーバーでの新しいユーザーの作成を処理するGraphQLミューテーションです。 ユーザーのユーザー名、電子メール、およびパスワードを受け取ります。 これらの変数はから渡されます SignUp
成分。
次に、を作成しましょう SignUp
成分。 以内 Admin
フォルダ、作成 SignUp.vue
以下のコードをファイルして貼り付けます。
<template>
<section class="section">
<div class="columns">
<div class="column is-4 is-offset-4">
<h2 class="title has-text-centered">Signup</h2>
<form method="POST" @submit.prevent="signup">
<div class="field">
<label class="label">Username</label>
<p class="control">
<input
type="text"
class="input"
v-model="username"
/>
</p>
</div>
<div class="field">
<label class="label">E-Mail Address</label>
<p class="control">
<input
type="email"
class="input"
v-model="email"
/>
</p>
</div>
<div class="field">
<label class="label">Password</label>
<p class="control">
<input
type="password"
class="input"
v-model="password"
/>
</p>
</div>
<p class="control">
<button class="button is-primary is-fullwidth is-uppercase">SignUp</button>
</p>
</form>
</div>
</div>
</section>
</template>
<script>
import { SIGNUP_MUTATION } from '@/graphql'
export default {
name: 'SignUp',
data () {
return {
username: '',
email: '',
password: ''
}
},
methods: {
signup () {
this.$apollo
.mutate({
mutation: SIGNUP_MUTATION,
variables: {
username: this.username,
email: this.email,
password: this.password
}
})
.then(response => {
// redirect to login page
this.$router.replace('/login')
})
}
}
}
</script>
このコンポーネントは、ユーザーがサインアップするためのフォームをレンダリングします。 フォームが送信されると、 signup
メソッドが呼び出されます。 以内 signup
方法、私たちは利用します mutate
で利用可能な方法 this.$apollo
(Vue Apolloプラグインから)。 を使用します SIGNUP_MUTATION
以前に作成された突然変異は、必要な変数を渡します。 サインアッププロセスが成功すると(つまり、ユーザーが作成されると)、ユーザーをログインページ(まもなく作成します)にリダイレクトします。
サインアップルートの追加
開ける src/router/index.js
、以下のコードを追加します。
// ...
import SignUp from '@/components/Admin/SignUp'
// ...
export default new Router({
routes: [
// add these inside the `routes` array
{
path: '/signup',
name: 'SignUp',
component: SignUp
}
]
})
今私たちが訪問するとき /signup
ルート、下の画像のようにサインアップフォームが表示されます。
ステップ8—ユーザーログインページの作成
ユーザーがログインする機能を追加しましょう。 ユーザーのサインアップで行ったのと同じように、最初にGraphQLミューテーションを作成しましょう。 以下のコードをに追加します src/graphql.js
:
export const LOGIN_MUTATION = gql`
mutation LoginMutation($email: String!, $password: String!) {
login(
email: $email,
password: $password
)
}
`
このGraphQLミューテーションは、GraphQLサーバーへのユーザーログインを処理します。 ユーザーのメールアドレスとパスワードを受け取ります。
次に、 Admin
フォルダ、作成 LogIn.vue
以下のコードをファイルして貼り付けます。
<template>
<section class="section">
<div class="columns">
<div class="column is-4 is-offset-4">
<h2 class="title has-text-centered">Login</h2>
<form method="POST" @submit.prevent="login">
<div class="field">
<label class="label">E-Mail Address</label>
<p class="control">
<input
type="email"
class="input"
v-model="email"
/>
</p>
</div>
<div class="field">
<label class="label">Password</label>
<p class="control">
<input
type="password"
class="input"
v-model="password"
/>
</p>
</div>
<p class="control">
<button class="button is-primary is-fullwidth is-uppercase">Login</button>
</p>
</form>
</div>
</div>
</section>
</template>
<script>
import { LOGIN_MUTATION } from '@/graphql'
export default {
name: 'LogIn',
data () {
return {
email: '',
password: ''
}
},
methods: {
login () {
this.$apollo
.mutate({
mutation: LOGIN_MUTATION,
variables: {
email: this.email,
password: this.password
}
})
.then(response => {
// save user token to localstorage
localStorage.setItem('blog-app-token', response.data.login)
// redirect user
this.$router.replace('/admin/posts')
})
}
}
}
</script>
このコンポーネントは、ユーザーがログインするための簡単なフォームをレンダリングします。 フォームが送信されると、 login
メソッドが呼び出されます。 以内 login
方法、私たちは利用します mutate
方法。 を使用します LOGIN_MUTATION
以前に作成された突然変異は、必要な変数を渡します。 ログインプロセスが成功したら、GraphQLサーバーから取得したトークンをlocalStorageに保存し、ユーザーをリダイレクトします。
ログインルートの追加
開ける src/router/index.js
、以下のコードを追加します。
// ...
import LogIn from '@/components/Admin/LogIn'
// ...
export default new Router({
routes: [
// ...
// add these inside the `routes` array
{
path: '/login',
name: 'LogIn',
component: LogIn
}
]
})
今私たちが訪問するとき /login
ルート、下の画像のようにログインフォームが表示されます。
ステップ9—メニューコンポーネントの作成
ブログの管理者向けの部分を具体化する前に、 Menu
サイドバーのナビゲーションメニューとして機能するコンポーネント。 以内 Admin
フォルダ、作成 Menu.vue
以下のコードをファイルして貼り付けます。
<template>
<aside class="menu">
<p class="menu-label">Post</p>
<ul class="menu-list">
<li>
<router-link to="/admin/posts/new">New Post</router-link>
</li>
<li>
<router-link to="/admin/posts">Posts</router-link>
</li>
</ul>
<p class="menu-label">User</p>
<ul class="menu-list">
<li>
<router-link to="/admin/users">Users</router-link>
</li>
</ul>
</aside>
</template>
これにより、ブログアプリの一部の管理セクションへのリンクがレンダリングされます。
ステップ10—ユーザーリストページの作成
管理セクションでは、作成されたユーザーのリストを表示できるようにする必要があります。 そのために、 Users
成分。 しかし、最初に、作成されたすべてのユーザーをフェッチするGraphQLクエリを作成しましょう。 以下のコードをに追加します src/graphql.js
:
export const ALL_USERS_QUERY = gql`
query AllUsersQuery {
allUsers {
id
username
email
}
}
`
このGraphQLクエリは、GraphQLサーバーからすべてのユーザーをフェッチします。
次に、を作成しましょう Users
成分。 以内 Admin
フォルダ、作成 Users.vue
以下のコードをファイルして貼り付けます。
<template>
<section class="section">
<div class="container">
<div class="columns">
<div class="column is-3">
<Menu/>
</div>
<div class="column is-9">
<h2 class="title">Users</h2>
<table class="table is-striped is-narrow is-hoverable is-fullwidth">
<thead>
<tr>
<th>Username</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody>
<tr
v-for="user in allUsers"
:key="user.id">
<td>{{ user.username }}</td>
<td>{{ user.email }}</td>
<td>
<router-link :to="`/admin/users/${user.id}`">View</router-link>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
</template>
<script>
import Menu from '@/components/Admin/Menu'
import { ALL_USERS_QUERY } from '@/graphql'
export default {
name: 'Users',
components: {
Menu
},
data () {
return {
allUsers: []
}
},
apollo: {
// fetch all users
allUsers: {
query: ALL_USERS_QUERY
}
}
}
</script>
私たちは利用します Menu
以前に作成されたコンポーネント。 次に、GraphQLサーバーからデータを取得したときに入力されるデータを定義します。 以内 apollo
オブジェクトの場合、GraphQLクエリを追加してすべてのユーザーをフェッチします。 これはを利用します ALL_USERS_QUERY
上で作成しました。 データの名前(allUsers
この場合)は、GraphQLクエリで使用されているものと同じ名前である必要があります(allUsers
この場合)。 一度 allUsers
GraphQLサーバーからのデータが入力されている場合、ユーザーの配列をループすることにより、テーブルにユーザーを表示します。 また、各ユーザーの詳細を表示するためのリンクを追加します。
ユーザールートの追加
開ける src/router/index.js
、以下のコードを追加します。
// ...
import Users from '@/components/Admin/Users'
// ...
export default new Router({
routes: [
// ...
// add these inside the `routes` array
{
path: '/admin/users',
name: 'Users',
component: Users
}
]
})
今私たちが訪問するとき /admin/users
ルート、下の画像のようにユーザーのリストが表示されます。
ステップ11—ユーザー詳細ページの作成
最後のセクションでは、ユーザーの詳細を表示するためのリンクを追加します。 それでは、実装しましょう。 以下のコードをに追加します src/graphql.js
:
export const USER_QUERY = gql`
query UserQuery($id: Int!) {
user(id: $id) {
id
username
email
posts {
id
}
}
}
`
このGraphQLクエリは、GraphQLサーバーからIDでユーザーをフェッチします。 ユーザーのIDを引数として取ります。 ユーザーIDはから渡されます UserDetails
成分。
次に、を作成しましょう UserDetails
成分。 以内 Admin
フォルダ、作成 UserDetails.vue
以下のコードをファイルして貼り付けます。
<template>
<section class="section">
<div class="container">
<div class="columns">
<div class="column is-3">
<Menu/>
</div>
<div class="column is-9">
<h2 class="title">User Details</h2>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Username</label>
</div>
<div class="field-body">
<div class="field">
<p class="control">
<input class="input is-static" :value="user.username" readonly />
</p>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Email Address</label>
</div>
<div class="field-body">
<div class="field">
<p class="control">
<input class="input is-static" :value="user.email" readonly />
</p>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Number of posts</label>
</div>
<div class="field-body">
<div class="field">
<p class="control">
<input class="input is-static" :value="user.posts.length" readonly />
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<script>
import Menu from '@/components/Admin/Menu'
import { USER_QUERY } from '@/graphql'
export default {
name: 'UserDetails',
components: {
Menu
},
data () {
return {
user: '',
id: this.$route.params.id
}
},
apollo: {
// fetch user by ID
user: {
query: USER_QUERY,
variables () {
return {
id: this.id
}
}
}
}
}
</script>
指定したユーザーのユーザー名、メールアドレス、作成された投稿数を表示します。 The USER_QUERY
詳細を表示するユーザーのIDを受け入れます。 ユーザーIDは、ルートパラメータから取得されます。 つまり、与えられた /admin/users/12
、12は特定のユーザーのIDです。 このIDをクエリに渡す方法が必要です。 これを行うには、反応パラメータを使用して、 variables
ユーザーIDを含むオブジェクトを返す関数。
ユーザー詳細ルートの追加
開ける src/router/index.js
、以下のコードを追加します。 このルートは、以前のすべてのルートより下にある必要があります。
// ...
import UserDetails from '@/components/Admin/UserDetails'
// ...
export default new Router({
routes: [
// ...
// add these inside the `routes` array
{
path: '/admin/users/:id',
name: 'UserDetails',
component: UserDetails,
props: true
}
]
})
これで、特定のユーザーの詳細を表示できるようになります。
ステップ12—ユーザーの承認
認証されたユーザーのみが新しい投稿を追加できます。 だから、私たちは合格する方法が必要です Authorization
ユーザートークンと、ユーザーが実際に新しい投稿を追加できることを示す新しい投稿を追加するリクエストを含むヘッダー。 と apollo-link-context
、これは簡単に実行できます。 開ける src/main.js
以下のコードを追加します。
// ...
import { setContext } from 'apollo-link-context'
// ...
const authLink = setContext((_, { headers }) => {
// get the authentication token from localstorage if it exists
const token = localStorage.getItem('blog-app-token')
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : null
}
}
})
// ...
// update apollo client as below
const apolloClient = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
})
まず、インポートします apollo-link-context
. 次に、それを使用して作成します authLink
これは、ローカルストレージからユーザートークンを取得し、Authorizationヘッダーを含むヘッダーを返します。 最後に、 authLink
Apolloクライアントで。
これで、Authorizationヘッダーが、GraphQLサーバーに対して行われたすべてのリクエストとともに送信されます。
ステップ13—新しい投稿ページを作成する
投稿はブログの中心です。 ユーザーは新しい投稿を追加できるはずです。 繰り返しになりますが、最初にブログに新しい投稿を追加するためのGraphQLミューテーションを作成します。 以下のコードをに追加します src/graphql.js
:
export const ADD_POST_MUTATION = gql`
mutation AddPostMutation($title: String!, $content: String!) {
addPost(
title: $title,
content: $content
) {
id
slug
title
content
user {
id
username
email
}
}
}
`
このミューテーションは、GraphQLサーバーに追加する投稿のタイトルとコンテンツを取得します。
次に、を作成します AddPost
内のコンポーネント Admin
フォルダを作成し、以下のコードをその中に貼り付けます。
<template>
<section class="section">
<div class="container">
<div class="columns">
<div class="column is-3">
<Menu/>
</div>
<div class="column is-9">
<h2 class="title">Add Post</h2>
<form method="post" @submit.prevent="addPost">
<div class="field">
<label class="label">Title</label>
<p class="control">
<input
class="input"
v-model="title"
placeholder="Post title"
/>
</p>
</div>
<div class="field">
<label class="label">Content</label>
<p class="control">
<textarea
class="textarea"
rows="10"
v-model="content"
placeholder="Post content"
></textarea>
</p>
</div>
<p class="control">
<button class="button is-primary">Add Post</button>
</p>
</form>
</div>
</div>
</div>
</section>
</template>
<script>
import Menu from '@/components/Admin/Menu'
import { ADD_POST_MUTATION, ALL_POSTS_QUERY } from '@/graphql'
export default {
name: 'AddPost',
components: {
Menu
},
data () {
return {
title: '',
content: ''
}
},
methods: {
addPost () {
this.$apollo
.mutate({
mutation: ADD_POST_MUTATION,
variables: {
title: this.title,
content: this.content
},
update: (store, { data: { addPost } }) => {
// read data from cache for this query
const data = store.readQuery({ query: ALL_POSTS_QUERY })
// add new post from the mutation to existing posts
data.allPosts.push(addPost)
// write data back to the cache
store.writeQuery({ query: ALL_POSTS_QUERY, data })
}
})
.then(response => {
// redirect to all posts
this.$router.replace('/admin/posts')
})
}
}
}
</script>
このコンポーネントは、新しい投稿を追加するためのフォームをレンダリングします。 それは使用します ADD_POST_MUTATION
それに必要な変数を渡します。 Apolloクライアントは(この場合はメモリ内に)クエリを実行するため、ミューテーションアクションを実行するたびにキャッシュを更新する方法が必要です。 あることに注意してください update
新しく追加された投稿をキャッシュに追加してストアを更新するために使用する関数。 まず、クエリに一致するキャッシュからデータをフェッチします(ALL_POSTS_QUERY
)、新しい投稿をに追加します allPosts
配列。 最後に、新しいデータをキャッシュに書き戻します。 投稿が正常に追加されると、投稿のリストにリダイレクトされます(これはまもなく作成されます)。
投稿ルートの追加
開ける src/router/index.js
、以下のコードを追加します。
// ...
import AddPost from '@/components/Admin/AddPost'
// ...
export default new Router({
routes: [
// ...
// add these inside the `routes` array
{
path: '/admin/posts/new',
name: 'AddPost',
component: AddPost
}
]
})
ユーザーは今すぐ新しい投稿を追加できるはずです:
ステップ14—すべての投稿を表示する
まず、以下のコードを追加してGraphQLクエリを作成します。 src/graphql.js
:
export const ALL_POSTS_QUERY = gql`
query AllPostsQuery {
allPosts {
id
title
slug
user {
username
}
}
}
`
このGraphQLクエリは、GraphQLサーバーからすべての投稿をフェッチします。
次に、 Posts
内のコンポーネント Admin
フォルダを作成し、以下のコードをその中に貼り付けます。
<template>
<section class="section">
<div class="container">
<div class="columns">
<div class="column is-3">
<Menu/>
</div>
<div class="column is-9">
<h2 class="title">Posts</h2>
<table class="table is-striped is-narrow is-hoverable is-fullwidth">
<thead>
<tr>
<th>Title</th>
<th>User</th>
<th></th>
</tr>
</thead>
<tbody>
<tr
v-for="post in allPosts"
:key="post.id"
>
<td>{{ post.title }}</td>
<td>{{ post.user.username }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
</template>
<script>
import Menu from '@/components/Admin/Menu'
import { ALL_POSTS_QUERY } from '@/graphql'
export default {
name: 'Posts',
components: {
Menu
},
data () {
return {
allPosts: []
}
},
apollo: {
// fetch all posts
allPosts: {
query: ALL_POSTS_QUERY
}
}
}
</script>
私たちは利用します Menu
以前に作成されたコンポーネント。 次に、GraphQLサーバーからデータを取得したときに入力されるデータを定義します。 以内 apollo
オブジェクトの場合、GraphQLクエリを追加してすべてのユーザーをフェッチします。 これはを利用します ALL_USERS_QUERY
上で作成しました。 データの名前(allUsers
この場合)は、GraphQLクエリで使用されているものと同じ名前である必要があります(allUsers
この場合)。 一度 allUsers
GraphQLサーバーからのデータが入力されている場合、ユーザーの配列をループすることにより、テーブルにユーザーを表示します。 また、各ユーザーの詳細を表示するためのリンクを追加します。
投稿ルートの追加
開ける src/router/index.js
、以下のコードを追加します。
// ...
import Posts from '@/components/Admin/Posts'
// ...
export default new Router({
routes: [
// ...
// add these inside the `routes` array
{
path: '/admin/posts',
name: 'Posts',
component: Posts
}
]
})
今私たちが訪問するとき /admin/posts
ルート、下の画像のように投稿のリストが表示されます。
ステップ15—ブログホームページの作成
ブログのホームページには、投稿の表示セクションと同じように作成されたすべての投稿のリストが表示されます。 実際、ホームページは投稿の表示に使用されるものとまったく同じGraphQLを使用します。 異なるのはホームページのマークアップのみです。 作成する Home
内部のコンポーネント src/components
以下のコードを追加します。
<template>
<section class="section">
<div class="columns">
<div class="column is-6 is-offset-3">
<h1 class="title">Latest Posts</h1>
<h3
v-for="post in allPosts"
:key="post.id"
class="title is-5"
>
<router-link :to="post.slug">
{{ post.title }}
</router-link>
</h3>
</div>
</div>
</section>
</template>
<script>
import { ALL_POSTS_QUERY } from '@/graphql'
export default {
name: 'Home',
data () {
return {
allPosts: []
}
},
apollo: {
// fetch all posts
allPosts: {
query: ALL_POSTS_QUERY
}
}
}
</script>
ご覧のとおり、JavaScriptセクションは Posts
成分。 ちょうど異なるマークアップ。 投稿配列をループして、スラッグにリンクされた各投稿のタイトルを表示します。
ホームルートの追加
開ける src/router/index.js
、以下のコードを追加します。
// ...
import Home from '@/components/Home'
// ...
export default new Router({
routes: [
// ...
// add these inside the `routes` array
{
path: '/',
name: 'Home',
component: Home
}
]
})
訪問 /
ルート、下の画像のようにブログのホームページが表示されます。
ステップ16—単一の投稿ページを作成する
最後に追加するのは、特定の投稿を表示する機能です。 以下のコードをに追加します src/graphql.js
:
export const POST_QUERY = gql`
query PostQuery($slug: String!) {
post(slug: $slug) {
id
title
slug
content
user {
id
username
email
}
}
}
`
このクエリは、スラッグによって投稿をフェッチします。 引数としてフェッチされるのは投稿のスラッグです。
次に、 SinglePost
内部のコンポーネント src/components
以下のコードを追加します。
<template>
<section class="section">
<div class="columns">
<div class="column is-6 is-offset-3">
<router-link class="button is-link is-small" to="/">Back Home</router-link>
<h1 class="title">
{{ post.title }}
</h1>
<div class="content">
{{ post.content }}
</div>
</div>
</div>
</section>
</template>
<script>
import { POST_QUERY } from '@/graphql'
export default {
name: 'SinglePost',
data () {
return {
post: '',
slug: this.$route.params.slug
}
},
apollo: {
// fetch post by slug
post: {
query: POST_QUERY,
variables () {
return {
slug: this.slug
}
}
}
}
}
</script>
投稿のタイトルとその内容、およびホームページに戻るためのリンクを表示します。 JavaScriptセクションは、ユーザーの詳細を表示する際に使用される実装に従います。 この場合、ルートパラメータからポストスラッグを取得します。
ビューポストルートの追加
開ける src/router/index.js
、以下のコードを追加します。
// ...
import SinglePost from '@/components/SinglePost'
// ...
export default new Router({
routes: [
// ...
// add these inside the `routes` array
{
path: '/:slug',
name: 'SinglePost',
component: SinglePost,
props: true
}
]
})
注:このルートは、routes配列の最後のルートである必要があります。
これで、1つの投稿を表示できるようになります。
結論
このチュートリアルでは、GraphQL、Apolloクライアント、およびVueJSを使用してブログアプリを構築する方法を見てきました。 また、フロントエンドアプリをGraphQLサーバーに接続する方法も確認しました。
このチュートリアルの完全なコードは、GitHubで入手できます。