メインコンテンツまでスキップ

NuxtJs Graphql

Hxb-Nuxt-Graphql

Get Started

Initialize

Create an application nuxtjs:

yarn create nuxt-app hxb-nuxtjs-grahql
  • When prompted to pick a preset, you can simply select like this:
    ? Project name: hexabase-nuxtjs-graphql
    ? Programming language: TypeScript
    ? Package manager: Yarn
    ? UI framework: None
    ? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection): Axios - Promise based HTTP client
    ? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection): >( ) ESLint
    ? Testing framework: None
    ? Rendering mode: Single Page App
    ? Deployment target: Static (Static/Jamstack hosting)
    ? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection):>( ) jsconfig.json (Recommended for VS Code if you're not using typescript)
    ? What is your GitHub username? nguyenpd-lts
    ? Version control system: Git

-Install package

  • Using optional yarn package
      yarn add @apollo/client @nuxtjs/apollo graphql-tag @nuxtjs/eslint-module nuxt-property-decorator
    yarn add -D eslint babel-eslint eslint-plugin-nuxt nuxt-cli-plugin-nuxt-next
  • File package.json like this:
     {
    "name": "hxb-nuxtjs-graphql",
    "version": "1.0.0",
    "private": true,
    "scripts": {
    "dev": "nuxt --port=3002",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate"
    },
    "dependencies": {
    "@apollo/client": "^3.5.5",
    "@nuxtjs/apollo": "^4.0.1-rc.5",
    "@nuxtjs/eslint-module": "^3.0.2",
    "core-js": "^3.15.1",
    "graphql-tag": "^2.12.6",
    "nuxt": "^2.15.7",
    "nuxt-property-decorator": "^2.9.1"
    },
    "devDependencies": {
    "@nuxt/types": "^2.15.7",
    "@nuxt/typescript-build": "^2.1.0",
    "@typescript-eslint/parser": "^5.6.0",
    "babel-eslint": "^10.1.0",
    "eslint": "^8.4.1",
    "eslint-loader": "^4.0.2",
    "eslint-plugin-nuxt": "^3.1.0"
    }
    }

-Config to using typescript and Connect nuxt with grahpql through apollo

  • Change file nuxt.config.js like this:

    modules: [
    '@nuxtjs/apollo',
    ],
    apollo: {
    clientConfigs: {
    default: '~/apollo/apollo-config.js'
    }
    },
    build: {
    extend (config, ctx) {
    if (ctx.dev && ctx.isClient) {
    config.module.rules.push({
    enforce: 'pre',
    test: /\.(js|vue)$/,
    loader: 'eslint-loader',
    exclude: /(node_modules)/
    })
    }
    }
    },
  • Create file .eslintrc.js like this:

    module.exports = {
    root: true,
    parser: 'babel-eslint',
    env: {
    browser: true,
    node: true
    },
    extends: 'standard',
    plugins: [
    'html'
    ],
    rules: {},
    globals: {}
    }
  • Create folder apollo create file apolo-config.json like this:

      import {
    ApolloLink,
    InMemoryCache,
    from,
    HttpLink,
    } from "@apollo/client/core";

    export default function (context) {
    const token = localStorage.getItem('token');

    const additiveLink = from([
    new ApolloLink((operation, forward) => {
    operation.setContext(({ headers }) => ({
    headers: {
    ...headers,
    authorization: token ? `Bearer ${token}` : null
    }
    }));
    return forward(operation);
    }),
    new HttpLink({ uri: "https://hxb-graph.hexabase.com/graphql" })
    ]);

    return {
    link: additiveLink,
    cache: new InMemoryCache(),
    defaultHttpLink: false,
    };
    }

-Example Query/Mutation Graphql with Hexabase:

-Create UI:

  • Create header information with file AppHeader.vue into folder components:

    <template>
    <header>
    <a class="flex justify-center pt-8 sm:pt-0" href="https://apidoc.hexabase.com/" target="_blank">
    <img alt="hexabase logo" src="~/static/hexabase.png">
    </a>
    <h1>Hexabase Nuxtjs Graphql</h1>
    <nav>
    <router-link exact to="/" class='link'>Index</router-link>
    <router-link exact to="/workspaces" class='link'>Workspaces</router-link>
    </nav>
    </header>
    </template>

    <script lang="ts">
    export default {
    name: 'AppHeader'
    }
    </script>

    <style scoped>
    header {
    padding: 24px 32px;
    margin-bottom: 32px;
    text-align: center;
    }
    h1 {
    font-weight: 100;
    }
    nav {
    max-width: 650px;
    margin: 0 auto;
    }
    .link {
    font-size: 18px;
    margin-right: 16px;
    }
    .nuxt-link-active {
    font-weight: bold;
    text-decoration: underline;
    }
    </style>
  • We will import component AppHeader into file default.vue at folder layouts:

    <template>
    <div>
    <app-header/>
    <main>
    <nuxt/>
    </main>
    </div>
    </template>

    <script>
    import AppHeader from '../components/AppHeader'
    export default {
    components: { AppHeader }
    }
    </script>

    <style>
    body {
    font-family: 'Source Sans Pro', sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    margin: 0;
    font-size: 16px;
    line-height: 1.5;
    }
    main {
    max-width: 650px;
    margin: 32px auto;
    padding: 0 24px;
    }
    a {
    color: deepskyblue;
    text-decoration: none;
    }
    article {
    margin: 0 auto;
    max-width: 650px;
    }
    </style>
  • At folder pages:

    • create file index.vue:
    <template>
    <div>
    <h1>Wellcome to Hexabase Nuxtjs Graphql</h1>
    </div>
    </template>
    • create file workspaces.vue:
    <template>
    <div>
    <h1>Workspaces</h1>
    </div>
    </template>

-Create graphql:

  • Create folder graphql and then create file workspaces.ts:

    • import package and create sentence query and mutation
    import gql from 'graphql-tag'

    export const WORKSPACES = gql`
    query Workspaces {
    workspaces {
    workspaces {
    workspace_name
    workspace_id
    },
    current_workspace_id
    }
    }`

    export const ADD_WORKSPACE = gql`
    mutation createWorkspace($createWorkSpaceInput: CreateWorkSpaceInput!) {
    createWorkspace(createWorkSpaceInput: $createWorkSpaceInput) {
    w_id
    }
    }`;

-To do with query/mutation nuxt graphql:

  • At template file workspaces.vue:

    • In template tag:
    <div>
    <div class="form-body">
    Mutation create workspaces
    <div class="input-field">
    <input type="text" v-model="addworkspaces.name" placeholder="enter the name" />
    <button @click="addWorkspace" >ADD Workspace</button>
    </div>
    <div v-if="workspaceAdd">
    Add workspace success:
    <p>workspace id:{{workspaceAdd}}</p>
    </div>
    </div>
    <div v-if="loading">
    <h2>LOADING...</h2>
    </div>
    <div v-else-if="error">{{error}}</div>
    <div class="workpaces-list" v-else-if="workspaces">
    <div name="list" tag="ul">
    <h2>Workspaces</h2>
    <ul>
    <li>
    <div class="description">
    <p> <span> current workspace id: </span>{{workspaces.current_workspace_id}}</p>
    </div>
    </li>
    <li v-for="workspace in workspaces.workspaces" :key="workspace.id">
    <div class="description">
    <p>{{workspace}}</p>
    </div>
    </li>
    </ul>
    </div>
    </div>
    </div>
    • Then import Query/Mutation get workspaces:
    <script>
    import {WORKSPACES, ADD_WORKSPACE} from '~/graphql/workspace'
    export default {
    name: 'WORKSPACES',
    data() {
    return {
    workspaces: [],
    addworkspaces: {
    name: ''
    },
    workspaceAdd: ''
    };
    },
    apollo: {
    $loadingKey: 'loading',
    workspaces: {
    query: WORKSPACES
    },
    },
    methods: {
    addWorkspace() {
    this.$apollo
    .mutate({
    mutation: ADD_WORKSPACE,
    variables: {
    createWorkSpaceInput:{
    name: this.addworkspaces.name
    }
    }
    })
    .then(response => {
    this.workspaceAdd = response.data.createWorkspace.w_id
    })
    .catch(er => {
    console.log(er);
    });
    }
    }
    }
    </script>
    • Create style for UI:
    <style>
    header {
    text-align: center;
    }
    header .order {
    margin-top: 20px;
    }
    button {
    margin: 0 10px;
    color: #1195c9;
    border: 3px solid #1195c9;
    background: #d5f0ff;
    padding: 8px 16px;
    border-radius: 4px;
    cursor: pointer;
    font-weight: bold;
    }
    header .title{
    /* display: flex; */
    justify-content: center;
    }
    header img {
    width: 100%;
    max-width: 250px;
    margin-right: 20px;
    }
    </style>

-Run project:

  yarn dev

Example: Hexabase NuxtJs Graphql