新闻详情

新闻详情

首页 / 资讯中心 / 详情

Vue + Apollo 全栈 GraphQL 教程总结:用 vue-cli 构建生产级 Hackernews 克隆

发布时间:2026/9/26 19:36:22来源:尧图网络
Vue + Apollo 全栈 GraphQL 教程总结:用 vue-cli 构建生产级 Hackernews 克隆
【免费下载链接】howtographqlThe Fullstack Tutorial for GraphQL项目地址https://gitcode.com/gh_mirrors/ho/howtographql点击查看免费下载本篇总结章节面向「HowToGraphQL」仓库中的 VueJS Apollo 前端教程对应文档 content/frontend/vue-apollo/11-summary.md。它属于该教程的收尾章节系统地回顾了你在前 10 章中完成的全部功能与所学到的技术能力从零搭建 VueJS 前端、用 Apollo Client 消费 GraphQL API、实现链接列表、登录认证、创建与投票、搜索过滤、分页以及基于 GraphQL Subscriptions 的实时更新。读完本文你将获得一份完整的功能清单、技术栈选型依据以及一套可复刻到任意 VueJS 项目中的 Apollo Client 集成方案。教程成果总览在整个 Vue Apollo 教程中你使用VueJS Apollo Clientvue-apollo构建了一个功能完整、面向生产环境的 Hackernews 克隆应用。最终实现的功能包括展示链接列表从 GraphQL API 加载并渲染链接Link记录搜索链接列表通过过滤条件在客户端实时检索用户认证基于邮箱与密码的注册、登录认证用户创建链接只有登录用户才能提交新链接认证用户为链接投票每个用户对每个链接最多投票一次实时更新当其他用户投票或创建新链接时当前页面即时刷新无需手动刷新浏览器。这些功能覆盖了绝大多数真实 GraphQL 前端应用的核心场景也是本教程标题中 Fullstack 的含义前端VueJS Apollo Client与后端Graphcool 提供的 GraphQL API各司其职通过 GraphQL 协议无缝协作。为什么选择 Apollo Client教程背后的技术选型在 0-introduction.md 中教程明确论证了为什么需要 GraphQL 客户端这一核心问题发送查询query与变更mutation、维护本地缓存这类工作是重复且与应用本身无关的应该交给专门的客户端库完成而不是在每个前端项目里自己重写网络层与缓存逻辑。当前主流可选的 GraphQL 客户端主要有两个RelayFacebook 自家开源2015 年与 GraphQL 一同开源的 GraphQL 客户端。它集成了 Facebook 自 2012 年使用 GraphQL 以来的全部经验为性能做了重度优化力求减少网络流量。它的代价是明显的学习曲线——Relay 是一个相当复杂的框架理解其全部组件需要投入时间1.0 版本 Relay Modern 已有所改善。Apollo Client社区驱动的、以易理解、灵活、强大为目标的 GraphQL 客户端。Apollo 的愿景是为每一种主流开发平台提供统一的库当前已有 React、Angular、Ember、Vue 等框架的绑定版本。它开箱即生产可用内置缓存caching、乐观 UIoptimistic UI、订阅subscriptions等实用特性。本教程选择vue-apolloApollo 的 VueJS 绑定正是因为这类开箱即用、功能完备的特性让开发者可以把注意力集中在应用本身的业务逻辑上。教程技术栈与项目脚手架本教程的技术栈如下层次技术作用前端框架VueJS渐进式 JavaScript 框架用于构建用户界面GraphQL 客户端Apollo Clientvue-apollo生产级、带缓存能力的 GraphQL 客户端后端Graphcool提供开箱即用的生产级 GraphQL API 的后端平台前端项目通过vue-cli脚手架工具创建基于 Webpack 模板自动完成全部构建配置具体步骤见 1-getting-started.mdnpm install -g vue-cli vue init webpack hackernews-vue-apollo创建时建议选择 Runtime-only 的 Vue 构建版本、安装 vue-router后续章节会用到路由并可选配置 ESLint 标准规则与单元测试。项目创建后执行npm install与npm run dev即可在http://localhost:8080看到应用运行。说明本教程后端基于Graphcool 的 legacy 版本Graphcool 已停运其能力演进为 Prisma 等现代工具链。教程中的graphcool init、graphcool playground、graphcool push等 CLI 命令均针对该旧版本后端现代项目中可替换为对应的 Prisma / Apollo Server 等方案但前端与 Apollo Client 的集成模式完全通用。Apollo Client 的初始化与核心配置Apollo Client 的初始化位于src/main.js是整个应用所有 GraphQL 请求的入口。核心步骤见 1-getting-started.md// 1. 创建 HttpLink指定 GraphQL API 端点 const httpLink new HttpLink({ uri: __SIMPLE_API_ENDPOINT__ // 替换为实际的 Simple API 端点 }) // 2. 实例化 ApolloClient传入网络链路与内存缓存 const apolloClient new ApolloClient({ link: httpLink, cache: new InMemoryCache(), connectToDevTools: true }) // 3. 安装 Vue 插件并创建 apolloProvider Vue.use(VueApollo) const apolloProvider new VueApollo({ defaultClient: apolloClient, defaultOptions: { $loadingKey: loading } }) // 4. 在根组件上 provide new Vue({ el: #app, provide: apolloProvider.provide(), render: h h(App) })关键点拆解HttpLink负责底层 HTTP 通信只需告知 API 端点即可无需手写任何网络层代码InMemoryCache提供规范化缓存这是后面实现变更后更新 Store功能的基础$loadingKey: loading允许组件通过loading数据属性轻松展示加载状态provide让所有子组件都能通过this.$apollo访问客户端实例。查询Query在组件中加载数据教程中所有 GraphQL 查询与变更都统一集中定义在src/constants/graphql.js并通过gql来自graphql-tag解析为标准查询文档然后导出供组件引用。这是非常值得借鉴的组织方式查询语句与应用逻辑解耦便于维护与复用。以链接列表查询为例见 2-queries-loading-links.mdimport gql from graphql-tag export const ALL_LINKS_QUERY gql query AllLinksQuery { allLinks { id createdAt url description } } 在LinkList组件中通过 Vue 组件上的apollo对象把查询结果绑定到datadata () { return { allLinks: [], loading: 0 } }, apollo: { allLinks: { query: ALL_LINKS_QUERY } }这一模式的本质是vue-apollo在底层替组件完成数据抓取把结果写入组件的data.allLinks并通过loading计数自动管理加载状态模板中用v-ifloading显示 Loading...。这套查询常量 apollo 对象的模式贯穿了整个教程。变更Mutation创建链接与缓存更新发送 mutation 与发送 query 的流程高度相似见 3-mutations-creating-links.md在graphql.js中定义变更常量在组件方法中调用this.$apollo.mutate({ mutation, variables })。// src/constants/graphql.js export const CREATE_LINK_MUTATION gql mutation CreateLinkMutation($description: String!, $url: String!) { createLink(description: $description, url: $url) { id createdAt url description } } // 组件中 createLink () { const { description, url } this.$data this.$apollo.mutate({ mutation: CREATE_LINK_MUTATION, variables: { description, url } }) }一个值得强调的进阶技巧是update回调Apollo 命令式 Store API。因为 Apollo 会优先读取缓存mutation 返回后如果不主动更新缓存UI 不会自动出现新数据。教程在 4-routing.md 中演示了如何手动读写缓存this.$apollo.mutate({ mutation: CREATE_LINK_MUTATION, variables: { description, url }, update: (store, { data: { createLink } }) { const data store.readQuery({ query: ALL_LINKS_QUERY }) data.allLinks.push(createLink) store.writeQuery({ query: ALL_LINKS_QUERY, data }) } }).then(() { this.$router.push({ path: / }) }).catch((error) { console.error(error) })这里readQuery/writeQuery构成了一套读取缓存 → 修改数据 → 写回缓存的闭环写回后 Apollo 会自动触发组件重渲染从而保持 UI 与服务器状态一致。该模式在后续投票功能updateStoreAfterVote中被再次复用。认证Authentication邮箱密码登录与令牌注入认证功能的完整实现链路见 5-authentication.md后端启用 Email-Password 认证Graphcool Console 中开启该 Integration为 API 增加两个 mutationcreateUser与signinUser返回SignInUserPayload包含user与token定义登录/注册 mutation其中注册 mutation 把createUser与signinUser合并为一个请求Graphcool 按从上到下的顺序依次执行实现注册即登录export const CREATE_USER_MUTATION gql mutation CreateUserMutation($name: String!, $email: String!, $password: String!) { createUser( name: $name, authProvider: { email: { email: $email, password: $password } } ) { id } signinUser(email: { email: $email, password: $password }) { token user { id } } } 存储凭证localStorage中分别保存用户 ID 与认证令牌对应的 key 统一放在src/constants/settings.jsexport const GC_USER_ID graphcool-user-id export const GC_AUTH_TOKEN graphcool-auth-token令牌注入所有请求利用 Apollo 的middlewareApolloLink 中间件在httpLink之前插入一层认证链路从localStorage取出 token 并写入每个请求的Authorization: Bearer token请求头const authMiddleware new ApolloLink((operation, forward) { const token localStorage.getItem(GC_AUTH_TOKEN) operation.setContext({ headers: { authorization: token ? Bearer ${token} : null } }) return forward(operation) }) const apolloClient new ApolloClient({ link: authMiddleware.concat(httpLink), cache: new InMemoryCache(), connectToDevTools: true })UI 状态联动在src/main.js的根 Vue 实例data中注入userId来自localStorageAppHeader通过this.$root.$data.userId判断登录状态未登录时隐藏 submit 入口并显示 login 链接登录后显示 logout。认证启用后CREATE_LINK_MUTATION也同步升级为携带$postedById参数并返回postedBy { id name }使每条新链接都能关联创建它的用户。投票Voting关联关系与命令式缓存更新投票功能引入了一个新的Vote类型见 6-more-mutations-and-updating-the-store.md它通过两个关系分别关联User与Linktype Vote model { id: ID! isUnique user: User! relation(name: UsersVotes) link: Link! relation(name: VotesOnLink) }对应地在User类型上增加votes: [Vote!]!在Link类型上增加votes: [Vote!]!然后通过graphcool push把 schema 变更同步到远端。投票的逻辑要点前端先检查当前用户是否已投过票把link.votes中的用户 ID 集合与当前userId比对已投票则直接提示并返回调用this.$apollo.mutate发送CREATE_VOTE_MUTATION在update回调中通过store.readQuery找到被投票的链接把服务器返回的最新votes写回缓存store.writeQuery从而让投票数立即反映在界面上。搜索过滤Filtering基于 filter 参数的智能查询搜索功能展示了 GraphQL 强大的服务端过滤能力见 7-filtering-searching-the-list-of-links.md。查询接受searchText参数并用OR组合两个_contains过滤条件——只要链接的url或description包含搜索词即命中export const ALL_LINKS_SEARCH_QUERY gql query AllLinksSearchQuery($searchText: String!) { allLinks(filter: { OR: [{ url_contains: $searchText }, { description_contains: $searchText }] }) { id url description createdAt postedBy { id name } votes { id user { id } } } } 组件侧的智能查询配置是这个功能的关键apollo: { allLinks: { query: ALL_LINKS_SEARCH_QUERY, variables () { return { searchText: this.searchText } }, skip () { return !this.searchText } } }两个值得注意的细节variables以函数形式提供因此每次this.searchText变化都会触发查询重跑实现边输入边搜索skip函数保证搜索词为空时不发请求避免无意义地拉取全量数据。实时更新Subscriptions基于 WebSocket 的推送订阅Subscription让服务器在特定事件发生时主动向客户端推送数据见 8-subscriptions.md。与之前所有请求-响应交互不同订阅通过WebSocket维持一条持续连接。配置分为两步安装依赖并创建SubscriptionClient把订阅端点与认证令牌交给客户端npm install --save subscriptions-transport-ws0.8.3const wsClient new SubscriptionClient(__SUBSCRIPTION_API_ENDPOINT__, { reconnect: true, connectionParams: { authToken: localStorage.getItem(GC_AUTH_TOKEN) } }) const httpLinkWithSubscriptions addGraphQLSubscriptions( authMiddleware.concat(httpLink), wsClient ) const apolloClient new ApolloClient({ link: httpLinkWithSubscriptions, cache: new InMemoryCache(), connectToDevTools: true })订阅端点的形式一般为wss://subscriptions.graph.cool/v1/project-id非默认区域时需带上区域前缀。在组件中使用subscribeToMore订阅Link类型上的CREATED事件并通过updateQuery其工作方式与 Redux reducer 类似接收上一个状态与服务器推送的数据返回合并后的新状态把新链接插入列表头部apollo: { allLinks: { query: ALL_LINKS_QUERY, subscribeToMore: [{ document: NEW_LINKS_SUBSCRIPTION, updateQuery: (previous, { subscriptionData }) { if (!subscriptionData.data.Link) return const newAllLinks [ subscriptionData.data.Link.node, ...previous.allLinks ] return { ...previous, allLinks: newAllLinks } } }] } }教程同时实现了对新投票Vote类型的CREATED事件的订阅在updateQuery中先定位被投票的链接findIndex再用服务器推送的最新链接数据替换列表中的该项从而实时刷新投票数。最终的体验是另一个用户创建链接或投票时当前页面即时更新无需刷新。分页Paginationfirst / skip 偏移分页分页章节9-pagination.md为ALL_LINKS_QUERY引入了first、skip、orderBy三个参数属于经典的limit-offset 分页export const ALL_LINKS_QUERY gql query AllLinksQuery($first: Int, $skip: Int, $orderBy: LinkOrderBy) { allLinks(first: $first, skip: $skip, orderBy: $orderBy) { id createdAt url description postedBy { id name } votes { id user { id } } } _allLinksMeta { count } } skip定义查询的偏移量offset如传10表示跳过前 10 条first定义返回条数limit如skip: 10, first: 5表示返回列表第 1015 项orderBy用于排序新链接页使用createdAt_DESC最新优先_allLinksMeta.count提供链接总数用于计算是否还有下一页。路由配置上根路径/重定向到/new/1新增/new/:page带页码参数与/top热门链接两条路由。LinkList组件通过this.$route.params.page读取当前页码在variables函数中动态计算skip (page - 1) * LINKS_PER_PAGE每页 5 条定义于 src/constants/settings.js 的LINKS_PER_PAGE。上一页/下一页按钮通过this.$router.push({ path: \/new/${nextPage} })驱动路由切换配合morePages、isFirstPage等计算属性控制按钮显隐。/top页面则利用 lodash 的_.orderBy(this.allLinks, votes.length).reverse() 按票数手动排序展示最热门的链接。部署Deploying用 Surge.sh 发布应用教程的最后一个实操环节10-deploying.md展示了如何用 Surge.sh 快速部署 VueJS 应用# 1. 全局安装 Surge npm install -g surge # 2. 构建生产版本输出到 /dist 目录 npm run build # 3. 进入 dist 目录并启动 surge cd dist surgenpm run build由 vue-cli 的 Webpack 配置驱动会把应用构建为生产产物并输出到/dist在/dist目录下执行surge后按提示登录或创建账户几次回车后终端会返回一个部署完成的 URL粘贴到浏览器即可访问线上应用。这也再次印证了教程产物的生产级定位从开发、测试到发布一条链路走通。总结这套教程教会你的核心能力回顾整个 Vue Apollo 教程你可以带走以下可复用的工程能力标准化的 Apollo Client 集成流程HttpLinkInMemoryCacheVueApolloprovider一套配置贯穿整个应用查询与变更的组织模式所有 GraphQL 文档集中在constants/graphql.js组件通过apollo对象查询与this.$apollo.mutate变更消费 API缓存更新三板斧update回调 readQuery/writeQuery命令式读写缓存让 UI 与服务器状态即时同步认证体系令牌存储于localStorage通过 ApolloLink 中间件注入每个请求配合根实例userId驱动 UI 状态实时能力SubscriptionClientsubscribeToMoreupdateQuery类 Redux reducer 的合并逻辑分页与过滤limit-offset 分页first/skip/orderBy与filter条件查询发布链路npm run build Surge 一键上线。这套查询常量集中管理 apollo 对象声明式取数 mutate/update 命令式更新缓存 订阅实时刷新的组合是 vue-apollo 应用最经典的生产模式可以原样迁移到任何基于 VueJS 与 GraphQL 的新项目中。赞分享【免费下载链接】howtographqlThe Fullstack Tutorial for GraphQL项目地址https://gitcode.com/gh_mirrors/ho/howtographql点击查看免费下载相关推荐How To GraphQ Angular Apollo 全栈教程总览用 GraphQL 客户端构建 Hackernews 克隆应用How To GraphQ Angular Apollo 全栈教程总览用 GraphQL 客户端构建 Hackernews 克隆应用 本文是 How ToHow To GraphQL React Apollo 前端教程用 Apollo Client 构建 Hackernews 克隆应用How To GraphQL React Apollo 前端教程用 Apollo Client 构建 Hackernews 克隆应用 本篇是 How ToHow to GraphQL 教程总结用 React 与 Relay 从零构建生产级 Hacker News 克隆How to GraphQL 教程总结用 React 与 Relay 从零构建生产级 Hacker News 克隆 本文是《How to GraphQL》T上一篇Swagger UI布局引擎打造响应式API文档的终极指南下一篇TensorRT-LLM与Bottle集成轻量级Web推理接口创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Agent记忆不跟工具搬家:三层记忆模型与文件系统落地实践 2026/9/26 20:30:10

Agent记忆不跟工具搬家:三层记忆模型与文件系统落地实践

1. 从“换个工具就失忆”说起:Agent 记忆到底卡在哪用 Claude Code 写了一个礼拜的项目,换到 Codex 上继续,结果它对你之前定的命名规范、目录结构、踩过的坑一无所知,一切从头解释——这个场景我相信只要同时用过两个以上编码 Ag…

阅读更多 →
金融服务聚合平台从0到1:架构设计与核心风控实践 2026/9/26 20:30:10

金融服务聚合平台从0到1:架构设计与核心风控实践

1. 项目定位与整体设计思路1.1 这个项目到底要解决什么问题"financial-services"这个标题乍一看非常宽泛,我接到这个项目需求时,第一反应不是"金融行业有多大",而是"客户到底想让我做什么"。金融服务业态太多—…

阅读更多 →
脑电信号左右手运动想象识别实战:轻量模型+单机部署 2026/9/26 20:30:03

脑电信号左右手运动想象识别实战:轻量模型+单机部署

简介:本资源是一套面向脑机接口(BCI)初学者与进阶研究者的运动想象脑电信号分析完整实践方案,聚焦左右手运动想象任务的特征提取与分类识别。基于BCI Competition 2008 Dataset 2b公开数据集,系统实现单次/多次被试两种…

阅读更多 →
eNSP PRO部署实战:从环境准备到首个拓扑跑通 2026/9/26 20:29:50

eNSP PRO部署实战:从环境准备到首个拓扑跑通

1. 为什么eNSP PRO值得折腾:从老版eNSP的痛点说起如果你在国内网络工程圈待过几年,大概率绕不开华为eNSP这个模拟器。老版eNSP陪伴了无数人考HCIA、HCIP、HCIE,但它的问题也很明显:只支持Windows、依赖VirtualBox、设备镜像老旧、…

阅读更多 →
PHP防伪证书系统实战:防伪码生成与查询部署全攻略 2026/9/26 20:29:50

PHP防伪证书系统实战:防伪码生成与查询部署全攻略

简介:PHP在线生成查询产品防伪证书系统源码,是一套面向中小企业、建站开发者以及电商运营者的完整防伪证书管理方案,内置证书模板管理、防伪码在线生成、真伪查询与后台权限控制等模块,部署在PHP与MySQL环境下即可使用。整个资源包…

阅读更多 →
字符串 split() 处理 \r\n 换行:TaoToken 配置骨架与验证清单 2026/9/26 20:29:44

字符串 split() 处理 \r\n 换行:TaoToken 配置骨架与验证清单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉