Vue + GraphQL初试
- 基本用法
- GraphQL概述
- GraphQL基本语法特性
- GraphQL类型系统
- GraphQL类型系统内置基础类型
- GraphQL类型系统内置修饰符
- GraphQL工作原理
- GraphQL执行过程
- Vue工程接入GraphQL
基本用法(如何去用)
package.json
"dependencies": {
"apollo-server-koa": "^1.3.6",
"graphql": "^0.13.2",
"graphql-import": "^0.6.0",
"graphql-tools": "^3.0.2",
"koa": "^2.5.1",
"koa-bodyparser": "^4.2.1",
"koa-router": "^7.4.0",
"koa-websocket": "^5.0.1"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.7.0"
}
复制代码
server.js
import koa from 'koa'
import koaRouter from 'koa-router'
import koaBody from 'koa-bodyparser'
import websocketify from 'koa-websocket'
import { graphqlKoa, graphiqlKoa } from 'apollo-server-koa'
import { makeExecutableSchema } from 'graphql-tools'
const app = websocketify(new koa())
const router = new koaRouter()
const PORT = 3000
// fake data
const moments = [
{
user: {
id: 1000,
name: '锐雯',
avatar: 'http://imgsrc.baidu.com/imgad/pic/item/42a98226cffc1e17d31927154090f603738de974.jpg'
},
main: {
content: '这是一条朋友圈',
pics: [
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1529219875063&di=bc0bcc78ae800c1c21c198f52697f515&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F4a36acaf2edda3ccd53548ea0be93901203f9223.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1529219893624&di=8d9e418df27e1fdb6afb1d993801a980&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F3801213fb80e7beca9004ec5252eb9389b506b38.jpg'
]
},
comments: [
{
user: {
id: 233122,
name: '亚索'
},
reply: '面对疾风吧'
}
]
}
]
const typeDefs = `
type Query {
moments: [Moment]
}
type Mutation {
addComment(
entity: Add_Comment
) : Comment
}
type Moment {
user: User
main: Main
comments: [Comment]
}
type User {
id: Int
name: String
avatar: String
}
type Comment {
user: User
reply: String
}
type Main {
content: String
pics: [String]
}
input Add_User {
id: Int
name: String
}
input Add_Comment {
user: Add_User
reply: String
}
# 定义graphqlf服务哪个是RootQuery以及RootMutation
schema {
query: Query
mutation: Mutation
}
`
const resolvers = {
Query: {
moments () {
return moments
}
},
Mutation: {
addComment (_, { entity }, unknown, context) {
console.log(entity)
moments[0].comments.push(entity)
return entity
}
}
}
const schema = makeExecutableSchema({
typeDefs,
resolvers
})
// koaBody is needed just for POST.
router.post('/graphql', koaBody(), graphqlKoa({ schema: schema }))
// router.get('/graphql', graphqlKoa({ schema: schema }))
router.get('/graphiql', graphiqlKoa({ endpointURL: '/graphql' }))
async function responseMiddleware(ctx, next) {
ctx.set('Access-Control-Allow-Origin', 'http://localhost:8080')
ctx.set('Access-Control-Allow-Methods', 'POST,OPTIONS')
ctx.set('Access-Control-Allow-Headers', 'authorization,content-type')
// ctx.set('Access-Control-Allow-Credentials', 'true')
await next()
}
app.use(responseMiddleware)
app.use(router.routes())
app.use(router.allowedMethods())
app.ws.use(responseMiddleware)
app.ws.use(router.routes())
app.ws.use(router.allowedMethods())
app.listen(PORT)
复制代码
GraphQL概述
GraphQL基本语法特性
包括有fields,alias,arguments,fragments,variables,directives,inline fragments
- field
GraphQL类型系统
主要由RootQuery + RootMutation两种入口类型(操作)加上RootValue(resolvers)构成GraphQL Schema。(此处用graphql-tools是为了将所有的类型定义在一个字符串中,后续会移到一个.graphql文件中,然后用graphql-import导入)
GraphQL类型系统内置基础类型
标量类型(Scalar Types)
Int
: 有符号的32位整数Float
: 有符号双精度浮点值String
: UTF-8字符序列Boolean
: true or falseID
:ID 标量类型表示一个唯一标识符(类似一种UUID),通常用以重新获取对象或者作为缓存中的键。ID 类型使用和 String 一样的方式序列化。
枚举类型(Enumeration Types)
是一种特殊的标量类型
enum Episode {
NEWHOPE
EMPIRE
JEDI
}
复制代码
- 数组类型(Array Types)
用方括号[]
标记列表
- 接口类型(Interface Types)
是一种抽象类型,与java的interface机制类似。
- 联合类型(Union Types)
{
search(text: "an") {
... on Human {
name
height
}
... on Droid {
name
primaryFunction
}
... on Starship {
name
length
}
}
}
复制代码
- 输入类型(Input Types)
与之前提到的所有Types对立,这是一种也是唯一一种输入类型,其主要用于mutations
时传递整个对象
的case,它没有参数。
内置修饰符
!
: 表示非空。如下
query DroidById($id: ID!) {
droid(id: $id) {
name
}
}
复制代码
GraphQL工作原理
GraphQL中每个查询字段是返回子类型的父类型函数。每个类型的字段对应由一个resolver
函数支持,当字段被执行时,响应的resolver
被调用并return结果。
如果字段产生结果为标量类型
值,比如字符串或数字,则执行完成。否则递归
执行对应解析器直至结果为标量类型
值。
GraphQL基本数据流
每个GraphQL服务端应用的顶层必定会有一个入口点
,通常为Root或者Query类型,接着执行该字段预设的解析器
(同步或异步),而每个字段被解析的结果被放置在键值映射中,字段名(或别名)作为键,解析器的值作为值,这个过程从查询字段的底部叶子节点
开始返回,直到Query类型的起始节点
,最后生成镜像查询结果
返回给客户端
Vue工程接入GraphQL
安装vue-cli3.x
npm i -g @vue/cli
复制代码
初始化工程
vue create [project-name]
复制代码
引入apollo插件
cd [project-name]
vue add apollo
复制代码
FriendCircle.vue
<template>
<div>
<div v-for="(item, index) in moments" :key="index">
{{item}}
</div>
<input type="text" v-model="comment.reply" placeholder="请输入要回复的内容">
<button @click="addComment">回复</button>
</div>
</template>
<script>
import gql from 'graphql-tag'
const QUERY_LIST = gql`
query {
moments {
user {
id
name
avatar
}
main {
content
pics
}
comments {
user {
id
name
}
reply
}
}
}
`
export default {
data () {
return {
moments: [],
comment: {
user: {
id: (Math.random() * 10000).toFixed(0),
name: '费德提克'
},
reply: ''
}
}
},
apollo: {
moments: {
query: QUERY_LIST
}
},
methods: {
addComment () {
this.$apollo.mutate({
mutation: gql`
mutation addComment($comment: Add_Comment) {
addComment(entity: $comment) {
user {
id
name
}
reply
}
}
`,
variables: {
comment: this.comment
},
update: (store, { data: { addComment } }) => {
// Read the data from our cache for this query.
const data = store.readQuery({ query: QUERY_LIST })
// set first moment's comment
data.moments[0].comments.push(addComment)
// Write our data back to the cache.
store.writeQuery({ query: QUERY_LIST, data })
}
})
}
}
}
</script>
复制代码
涉及的知识点有Root_Query,Root_Mutation,variables以及store cache
cache
其核心机制包括以下两点
- 对所有(包括嵌套的)非标量类型递归进行缓存,往往通过类型id或_id以及__typename唯一组合标识,然后在一个扁平的数据结构中存储
- 可以设置不同缓存策略:cache-and-network,no-cache,network-only
update回调
this.$apollo.mutate(options) options中有一个update回调,在成功响应数据后触发,并且可以直接读取并操作由apollo-cache-inmemory
生成的store。上述例子中使用此回调同步更新缓存以及UI
注:所有绑定的变量均不可直接修改,内部使用Object.freeze将对象冻结,无法直接增删。
作者:清风0o0
链接:https://juejin.im/post/5b2640bee51d45588d4d68d2
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Vue + GraphQL初试的更多相关文章
- 在vscode中使用eslint+prettier格式化vue项目代码 (转载)
ESlint:javascript代码检测工具,可以配置每次保存时格式化js,但每次保存只格式化一点点,你得连续按住Ctrl+S好几次,才格式化好,自行体会~~ vetur:可以格式化html.标准c ...
- 1-VScode格式化ESlint-方法(最全最好用方法!)
1-VScode格式化ESlint-方法(最全最好用方法!) ESlint:是用来统一JavaScript代码风格的工具,不包含css.html等. 背景: 近来研究前端,然后一直在百度上找VSc ...
- vsCode格式化插件
ESlint:是用来统一JavaScript代码风格的工具,不包含css.html等. 背景 近来研究前端,然后一直在百度上找VScode格式化(ESlint)的插件,结果找了半天都不靠谱.目前没有一 ...
- Vue项目中GraphQL入门学习与应用
1.GraphQL是什么,能干什么? 正如官网所说,GraphQL是一种用于API查询的语言.Facebook 的移动应用从 2012 年就开始使用 GraphQL.GraphQL 规范于 2015 ...
- GraphQL & Apollo & Vue
GraphQL & Apollo & Vue https://www.howtographql.com/vue-apollo/0-introduction/ https://githu ...
- 初试 Vue.js
1.为什么我会想要来弄弄vue这个前端框架呢? 答:前段时间被小程序刷屏了,然后就去弄了一下小程序,嗯挺简单的:头脑一发热后就想到vue2也发布一段时间了,何不也来尝尝vue2.0的味道,最后发现它们 ...
- 初试vue
Vue了解 """ vue框架 vue是前台框架:Angular.React.Vue vue:结合其他框架优点.轻量级.中文API.数据驱动.双向绑定.MVVM设计模式. ...
- Vue.js 基本功能了解
一.写在前面 隔了这么久才来出Vue的第二篇文章,真是堕落了,自己先惩罚下/(ㄒoㄒ)/~~ 回过头看自己第一篇相关文章<初试 Vue.js>(http://www.cnblogs.com ...
- Vue跨门槛系列之实例的阐述
学习.使用中结合vue官网的api和教程极佳! 前前篇文章上有提及到vue的简单介绍,详情请戳这里 (初试 Vue.js) 第一部分: 每个 Vue 应用都是通过 Vue 函数创建一个新的 Vue ...
随机推荐
- 第四章 初始CSS
一.引入样式 1.行内样式表 <h1 style="color: red;font-size: 18px;">10-30</h1> 2.内部样式表(在hea ...
- 关于java中的值传递和引用传递(也就是地址传递)
概念解释: 值传递,传递值,在函数中形参发生的变化不影响实参. 引用传递,传递对象引用,在函数中形参发生的变化影响实参. ======================================= ...
- 内置对象(Math、Date、String、Array、基本包装类型)
一.内置对象 js中三种对象:内置对象.自定义对象.浏览器对象 实例对象是指通过构造函数创建出来,然后实例化的对象(new关键字) 静态对象是指不需要创建,直接调用的对象,可以在整个JS里调用的公共对 ...
- 【luogu3950】部落冲突--树剖
题目背景 在一个叫做Travian的世界里,生活着各个大大小小的部落.其中最为强大的是罗马.高卢和日耳曼.他们之间为了争夺资源和土地,进行了无数次的战斗.期间诞生了众多家喻户晓的英雄人物,也留下了许多 ...
- Lua 常用函数 一
lua_getallocf lua_Alloc lua_getallocf (lua_State *L, void **ud); 返回给定状态机的内存分配器函数.如果 ud 不是 NULL ,Lua ...
- codeforces37C
CF37C Old Berland Language sol:直接暴力模拟下去,长度加了就补0,凑个数就+1,凑不好就puts(“no”) #include <bits/stdc++.h&g ...
- Python3 输入和输出(一)
1.输出格式美化 Python两种输出值的方式: 表达式语句和 print() 函数. 第三种方式是使用文件对象的 write() 方法,标准输出文件可以用 sys.stdout 引用. 如果希望输出 ...
- C# 获取网络文件 批量压缩成 文件流 并下载 压缩包
需要的DLL : ICSharpCode.SharpZipLib.dll JS部分 //下载所有文件的 压缩包 function DownAllFile() { //zip文件名 var zipNam ...
- kvm 学习(二)镜像
Linux下 如何通过命令行使用现有的镜像创建.启动kvm虚拟机 这里假定已经创建好了相应的镜像: eg:我这里制作的镜像名称为zu1-centos7.img # ls zu1-centos7.img ...
- Jenkins 获取 Git 的提交记录(Change Log)
工作中用 Jenkins 做 iOS 和 Android 的持续集成,之前实现的是当 git 有新代码提交的时候,就会自动编译并上传安装包到蒲公英,然后自动发送QQ群通知或者讨论组通知给相关小伙伴,方 ...