Vue Graphql
Hxb-Vue-graphql
Get Started
Initialize
Create an application Vue:
vue create vue-graphql-hxb
- When prompted to pick a preset, you can simply select like this:
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Linter
? Choose a version of Vue.js that you want to start the project with 3.x
? Pick a linter / formatter config: Basic
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? (y/N) n - Then option choice Yarn
-Install package
Using optional yarn package
yarn add react graphql apollo-boost vue-class-component vue-property-decorator @apollo/client @vue/apollo-composable
yarn add -D eslint babel-eslint eslint-plugin-vue vue-cli-plugin-vue-next @vue/eslint-config-typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin typescript @vue/cli-plugin-babel @vue/cli-plugin-eslint @vue/cli-plugin-typescript @vue/cli-serviceFile
package.json
like this:{
"name": "vue-graphql",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@apollo/client": "^3.4.17",
"@vue/apollo-composable": "^4.0.0-alpha.15",
"apollo-boost": "^0.4.9",
"core-js": "^3.6.5",
"graphql": "^16.0.1",
"react": "^17.0.2",
"vue": "^3.0.0-beta.1",
"vue-class-component": "^7.2.3",
"vue-property-decorator": "^9.1.2"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-typescript": "^4.5.15",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0-beta.1",
"@vue/eslint-config-typescript": "^7.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0-alpha.0",
"typescript": "~4.1.5",
"vue-cli-plugin-vue-next": "~0.1.4"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/typescript"
],
"parserOptions": {
"parser": "@typescript-eslint/parser"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
-Config to using typescript and Connect Vue with grahpql through apollo
Create file
.eslintrc.js
like this:module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/typescript/recommended'
],
parserOptions: {
ecmaVersion: 2020
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}Create file
tsconfig.json
like this:{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}In
main.ts
import package@apollo/client
:import { createApp, h, provide } from "vue";
import {
ApolloClient,
ApolloLink,
InMemoryCache,
from,
HttpLink,
} from "@apollo/client/core";
import { DefaultApolloClient } from "@vue/apollo-composable";
import App from "./App.vue";In
main.ts
add authentication token and connect touri
api andcache
fields:const token = localStorage.getItem('token');
const additiveLink = from([
new ApolloLink((operation, forward) => {
operation.setContext(({ headers }: any) => ({
headers: {
...headers,
authorization: token ? `Bearer ${token}` : null
}
}));
return forward(operation);
}),
new HttpLink({ uri: "https://hxb-graph.hexabase.com/graphql" })
]);
const apolloClient = new ApolloClient({
link: additiveLink,
cache: new InMemoryCache()
});In
main.ts
wrap vue app withprovide
const app = createApp({
setup() {
provide(DefaultApolloClient, apolloClient)
},
render: () => h(App)
});
app.mount("#app");In
shims-vue.d.ts
to config ReturnType like this:declare module '*.vue' {
import type { defineComponent } from 'vue'
const component: ReturnType<typeof defineComponent>;
export default component
}creaet file
shims-tsx.d.ts
like this:import Vue, { VNode } from 'vue'
declare global {
namespace JSX {
// tslint:disable no-empty-interface
interface Element extends VNode {}
// tslint:disable no-empty-interface
interface ElementClass extends Vue {}
interface IntrinsicElements {
[elem: string]: any
}
}
}
-Example Query/Mutation Graphql with Hexabase:
-Create UI:
At template In file
main.ts
create button choice optional is workspaces and check condition show Workspaces component:<div class="app">
<header>
<div class="title">
<img alt="hexabase logo" src="./assets/hexabase.png">
</div>
<div class="order">
<button @click="handleClick('workspaces')">Workspaces</button>
<button @click="handleClick('applicationdatastore')">ApplicationDatastore</button>
</div>
</header>
<Workspaces v-if="choice =='workspaces'" />Then import Workspace component and handle button:
import { defineComponent, ref } from 'vue';
import Workspaces from './components/Workspace.vue'
export default defineComponent({
name: 'App',
components: { Workspaces },
setup() {
let choice = ref<string>('')
const handleClick = (term: string) => {
choice.value = term
}
return { choice, handleClick }
}
});
</script>Add style like this:
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;
}
-Create graphql:
Create folder graphql and then create file
workspaces.ts
:- import package and create sentence query and mutation
import { gql } from "@apollo/client/core";
export const GET_WORKSPACES = gql` query {
workspaces {
workspaces {
workspace_name
workspace_id
},
current_workspace_id
}
}`
export const ADD_WORKSPACE = gql`
mutation createWorkspace($createWorkSpaceInput: CreateWorkSpaceInput!) {
createWorkspace(createWorkSpaceInput: $createWorkSpaceInput) {
w_id
}
}`;Create folder model and then create file
workspace.ts
:- Create type then export these:
export type WorkSpacesInfo = {
workspace_id: string,
workspace_name: string,
}
export type WorkSpaces = {
workspaces: [WorkSpacesInfo],
current_workspace_id: string,
}
export type WId = {
w_id: string,
}
export type Name = {
name: string,
}
-To do with query/mutation Vue graphql:
In template tag:
<div class="form-body">
Mutation create workspaces
<div class="input-field">
<input type="text" v-model="name" placeholder="enter the name" />
<button @click="addWorkspace">ADD Workspace</button>
</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">
<transition-group name="list" tag="ul">
<h2>Workspaces</h2>
<li>
<div class="description">
<p> <span> current workspace id: </span>{{workspaces.workspaces?.current_workspace_id}}</p>
</div>
</li>
<li v-for="workspace in workspaces.workspaces?.workspaces" :key="workspace.id">
<div class="description">
<p>{{workspace}}</p>
</div>
</li>
</transition-group>
</div>Import package and execute query/mutation:
import { defineComponent, ref } from 'vue'
import { useQuery, useResult, useMutation } from "@vue/apollo-composable";
import {WorkSpaces, WId } from '../model/workspaces'
import {GET_WORKSPACES, ADD_WORKSPACE} from '../graphql/workspaces'
export default defineComponent({
data() {
return {
name:''
}
},
methods: {
addWorkspace: function() {
this.createWorkspace({ createWorkSpaceInput: {
name: this.name
} });
}
},
setup() {
const { result, loading, error } = useQuery<{workspaces: WorkSpaces}>(GET_WORKSPACES);
const workspaces = useResult( result, [], data => data );
const {
loading: m_loading,
error: m_error,
mutate: createWorkspace
} = useMutation(ADD_WORKSPACE, {
update: (cache, { data: {createWorkspace} }) => {
const data: any = cache.readQuery({ query: GET_WORKSPACES });
}
});
return {
workspaces,
result,
loading: loading || m_loading,
error: error || m_error,
createWorkspace,
};
},
})Create style for UI:
.workpaces-list {
max-width: 960px;
margin: 40px auto;
}
.workpaces-list ul {
padding: 0
}
.workpaces-list li {
list-style-type: none;
background: white;
border-radius: 4px;
}
.workpaces-list h2 {
margin: 0 0 10px;
text-transform: capitalize;
}
.salary {
display: flex;
}
.salary img {
width: 30px;
}
.salary p {
color: #17bf66;
font-weight: bold;
margin: 10px 4px;
}
.list-move {
transition: all 1s;
}
.form-body {
width: 100%;
max-width: 700px;
margin: 0 auto;
text-align: center;
margin-top: 10px;
margin-bottom: 5px;
}
.input-field {
width: 700 px;
margin: 0 auto;
}
.input-field input {
height: 29px;
}
-Run project:
yarn serve
-Link example Hexabase Vue Graphql github:
Example: Hexabase Vue Graphql