iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 18
0
Modern Web

NestJs 讀書筆記系列 第 18

VueJs - Vue Apollo Subscriptions

  • 分享至 

  • xImage
  •  

Vue Apollo Subscriptions

設置

我們是基於 websocket 的訂閱模式,所以需要做一些配置

$ yarn add apollo-link-ws apollo-utilities

可以根據官網給的範例直接做配置

// New Imports
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { split } from 'apollo-link'
import { WebSocketLink } from 'apollo-link-ws'
import { getMainDefinition } from 'apollo-utilities'

export function createProvider (options = {}) {
  const httpLink = new HttpLink({
    // You should use an absolute URL here
    uri: 'http://localhost:4000/graphql',
  })
  
  // Create the subscription websocket link
  const wsLink = new WebSocketLink({
    uri: 'ws://localhost:4000/graphql',
    options: {
      reconnect: true,
      timeout: 30000
    },
  })

  // using the ability to split links, you can send data to each link
  // depending on what kind of operation is being sent
  const link = split(
    // split based on operation type
    ({ query }) => {
      const definition = getMainDefinition(query)
      return definition.kind === 'OperationDefinition' &&
        definition.operation === 'subscription'
    },
    wsLink,
    httpLink
  )

  // Create the apollo client
  const apolloClient = new ApolloClient({
    link,
    cache: new InMemoryCache(),
    connectToDevTools: true,
  })

  // Create vue apollo provider
  const apolloProvider = new VueApollo({
    defaultClient: apolloClient,
    defaultOptions: {
      $query: {
        // fetchPolicy: 'cache-and-network',
      },
    },
    errorHandler (error) {
      // eslint-disable-next-line no-console
      console.log('%cError', 'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;', error.message)
    },
  })

  return apolloProvider
}

開始編寫 Schema
我們的流程是,當新增一筆 comment 後,所有訂閱者都能收到 comment
所以這邊我們會有一個 mutation 以及 subscription,由 mutation 觸發 subscription 進行廣播。

export const COMMENT_ADDED = gql`
subscription commentAdded ($title: String!){
    commentAdded(title: $title) {
      title
      comment
    }
  }
`

export const ADD_COMMENT = gql`
    mutation addComment ($title: String!, $comment: String!){
        addComment(title: $title, comment: $comment) {
            comment
        }
    } 
`

Simple subscription

使用簡單的訂閱模式 $subscribe ,可以直接取得結果
如果想更新 apollo 查詢結果,可以使用另一種模式 Smart Subscriptions ,他提供了 subscribeToMore ,可讓查詢的 API 取得訂閱的結果,直接更新查詢結果並回傳

methods: {
    async addComment() {
        const response = await this.$apollo.mutate({
            mutation: ADD_COMMENT,
            variables: {
                title: "title",
                comment: this.comment
            }
        })
    }
},
apollo: {
    authors: {
        query: AUTHORS
    },
    $subscribe: {
        commentAdded: {
            query: COMMENT_ADDED,
            variables: {
                title: "title"
            },
            result ({ data }) {
                this.comments.push(data.commentAdded);
            },
        }
    }
}

給予一個輸入框可以輸入 comment ,以及一個按鈕觸發事件

<template>
    <div>
        <v-text-field v-model="comment"></v-text-field>
        <v-btn @click="addComment">addComment</v-btn>
        <div v-for="item in comments" :key="item.id">
            {{item.comment}}
        </div>
    </div>
</template>

完成後就能來進行測試,打開兩個瀏覽器

當其中一邊送出 comment 後,兩個瀏覽器都能收到 comment
左邊輸入文字,右邊也能收到,這就是 Subscription 功能

生活中常用的案例就是聊天系統,讀者可以將頁面完善,做一個簡易型的聊天室!


上一篇
VueJs - Vue Apollo Mutations
下一篇
VueJs - Vue Apollo Component
系列文
NestJs 讀書筆記31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言