前端GraphQL【免费下载链接】apollo Apollo/GraphQL integration for VueJS项目地址https://gitcode.com/gh_mirrors/apollo2/apollo点击查看免费下载useFragment是vue/apollo-composable提供的核心组合式函数之一它把 Apollo Client 缓存中已缓存的实体数据以 Fragment 的形式投影为 Vue 响应式状态并随着缓存变化自动更新。本文基于 useFragment 官方类型文档结合其底层实现源码 useFragment.ts 与配套指南 Fragments 文档系统讲解它的类型系统、全部配置项、返回值语义、数组读取、事件钩子与底层工作原理让你能够在组件中直接复用缓存数据而无需重复发起网络请求。一、useFragment 是什么从缓存读取数据而非从网络在 GraphQL 应用中同一个实体例如User往往被多个组件以不同的字段集合展示。与其让每个组件各自发起查询更合理的做法是让父组件的查询一次取回数据并写入 Apollo 缓存子组件通过useFragment从缓存中读取自己需要的字段子集const { current } useFragment({ fragment: gqlfragment UserFields on User { id name }, from: { __typename: User, id: 1 }, })从 functions/useFragment.md 的官方描述看它的核心能力是从 Apollo 缓存读取 fragment 数据并以 Vue 响应式 ref 的形式暴露持续监视缓存当缓存中对应实体发生变化时自动更新同时支持单个实体与实体数组两种读取方式。需要特别强调的是useFragment只对缓存能识别的实体生效。缓存通过cache.identify()为每个实体生成唯一缓存 ID通常由__typename加主键字段id组成无法识别的数据无法使用本函数。这一点在源码 useFragment.ts 的文档注释中被明确标记为 danger 级别的注意项。与 useQuery 的分工useQuery负责取数——从网络或缓存获取查询结果useFragment负责复用——直接读取缓存中已有的、被其它查询写入的实体数据。二者的返回结构高度相似都提供current、result等但useFragment不会触发网络请求因此非常适合在组件树中传递数据时保持单一数据源Single Source of Truth。二、类型全景Options、Result 与 CurrentuseFragment的类型体系位于 namespaces/useFragment/index.md包含两个类型别名与三个接口类型类别作用FromValueType Alias缓存标识可被缓存识别的实体对象、引用或字符串 IDReactiveVariablesParameterType Aliasvariables选项的响应式形态OptionsInterface配置项fragment、from、variables 等ResultInterface返回值响应式状态与事件钩子CurrentInterface当前状态的可辨识联合discriminated unionFromValue如何指定从哪读type FromValue object | string | null这是缓存标识类型的文档化表示。从源码 useFragment.ts 的定义看实际类型要更精确——StoreObject含__typename/id的对象、Reference如{ __ref: User:1 }、FragmentTypeTData、字符串 ID 或null。按照 Fragments 指南from选项接受四种形态对象{ __typename: User, id: 1 }——最常见的形态引用对象{ __ref: User:1 }——Apollo 缓存内部引用字符串 IDUser:1——直接给出缓存 ID数组[ { __typename: User, id: 1 }, ... ]——一次读取多个实体见下文数组读取。from还支持MaybeRefOrGetter即可以传入 ref、getter 函数或普通值例如from: () user这样基于 props 动态计算数据源示例见 fragments.md。ReactiveVariablesParameter响应式变量当 fragment 声明了带变量的字段时variables选项可以有两种写法ReactiveVariablesParameter.md// 写法一整个变量对象由 ref/getter 包裹 const variables reactive({ id: 1 }) useFragment({ fragment, from, variables }) // 写法二对象中每个变量单独对应 ref/getter const id ref(1) useFragment({ fragment, from, variables: { id } }) // 写法三配合 props 或任意响应式值 const { id } defineProps{ id: number }() useFragment({ fragment, from, variables: () ({ id }) })底层实现会对第二种写法逐键解包在 useFragment.ts 中variables被包装为一个computed对Object.entries(vars)的每个值再调用toValue最终汇聚成普通变量对象传给 Apollo。这意味着无论你以何种方式声明响应式变量fragment 都会随其变化而重新读取。Current可辨识联合带来的类型收窄Current接口是useFragment状态的核心Current.md属性类型含义resultobject \| object[]fragment 查询完成后的结果对象resultStatecomplete \| partial结果完整性描述completebooleanfragment 数据是否完整missing?MissingTree当complete为 false 时缺失字段的错误树resultState的两种取值语义在文档与源码注释中一致partial缓存只能满足部分字段result不完整。注意文档明确指出这仅在 Apollo 的returnPartialData为true时才可能出现completeresult是完全满足的查询结果数据来自缓存或网络。由于current是可辨识联合TypeScript 能根据resultState自动收窄result的类型——这正是文档推荐优先使用current而非单独解构result的原因fragments.md。三、Options 配置项详解Options 接口将配置项分为三个分组以下是完整清单1. Fragment 组配置项类型说明fragmentMaybeRefOrGetterDocumentNode必填。GraphQL fragment 文档通常由gql标签生成fragmentName?MaybeRefOrGetterstring可选。当文档内包含多个 fragment 时指定使用哪一个variables?MaybeRefOrGetterReactiveVariablesParameter可选。fragment 的变量类型见上文2. Data Source 组配置项类型说明fromMaybeRefOrGetterFromValue \| FromValue[]必填。缓存可识别的实体单实体或实体数组3. Configuration 组配置项类型默认值说明clientId?string—使用哪个具名 Apollo client多 client 场景optimistic?booleantrue是否读取乐观缓存optimistic cache数据从源码实现看optimistic的默认值为true并会透传给底层的watchFragmentuseFragment.ts。clientId则通过useApolloClient()内部的resolveClient(clientId)解析出对应的 client 实例useFragment.ts多 client 的配置方式可参考 multiple-clients.md。四、Result 返回值响应式状态与事件调用useFragment后得到 Result 对象包含以下成员1. Operation data 组返回值类型说明currentReadonlyRefCurrent当前完整状态可辨识联合推荐优先使用resultReadonlyRefobject \| object[]fragment 查找完成后的结果resultStateReadonlyRefcomplete \| partial结果完整性completeReadonlyRefboolean数据是否完整missingReadonlyRefMissingTree缺失字段树complete为 false 时才有意义2. Events 组返回值类型说明onNextStateEventHookOnCurrentfragment 数据变化时触发的事件钩子模板中的典型用法script setup langts import { useFragment } from vue/apollo-composable const USER_FRAGMENT gql fragment UserFields on User { id name email } const props defineProps{ user: { __typename: User, id: string } }() const { current } useFragment({ fragment: USER_FRAGMENT, from: () props.user, }) /script template div v-ifcurrent.resultState complete {{ current.result.name }} ({{ current.result.email }}) /div /template注意模板中的current是 ref在模板里会被自动解包因此直接写current.resultState即可在script setup的逻辑代码中则需要current.value。事件钩子命令式监听数据变化当你需要以命令式方式响应 fragment 数据变化例如联动副作用时可使用onNextStatefragments.mdconst { onNextState } useFragment({ fragment: USER_FIELDS, from: props.user, }) onNextState((state) { console.log(Fragment data changed:, state) })该钩子由 VueUse 的createEventHook实现useFragment.ts每次缓存更新触发订阅回调并传入最新的Current状态。五、数组读取一次处理多个实体当from传入实体数组时fragments.mdconst { users } defineProps{ users: Array{ __typename: User, id: string } }() const { current } useFragment({ fragment: USER_FRAGMENT, from: () users, })数组模式的关键语义current.result是数组其中每一项与from中对应下标位置的实体一一对应resultState只有所有项都 complete时才为complete只要有一项不完整即为partial。从源码看数组与单实体在内部被统一处理cacheIds计算属性在Array.isArray(fromValue)时对每一项调用resolveFromToId得到 ID 数组然后交给 Apollo 的watchFragmentuseFragment.ts。底层watchFragment同时接受单个 ID 与 ID 数组这也是文档注释中像 React 版本一样统一处理单值与数组useFragment.ts所指的实现细节。另外当from为null或尚未就绪时实现会返回冻结的空占位状态单实体为{ result: {}, resultState: partial, complete: false }数组为{ result: [], resultState: partial, complete: false }useFragment.ts避免消费端解构空值时出错。六、底层原理从选项到 watchFragment 的完整链路useFragment的实现位于 packages/vue-apollo-composable/src/useFragment.ts核心是useFragmentImpl函数。它的工作流可以概括为六个阶段输入归一化用toRef将MaybeRefOrGetter形态的 options 统一为 refL308-L310Client 解析通过useApolloClient()的resolveClient(clientId)获取 client进而取得cacheL312-L318选项解析from、fragment、fragmentName、variables全部包装为computed任一响应式依赖变化都会触发重新计算L320-L339缓存 ID 解析cacheIds对from的值调用resolveFromToId——字符串直接返回对象则交给cache.identify(from)生成缓存 ID无法识别时返回nullL275-L285watchFragment 选项组装把 fragment、ID、optimistic ?? true、可选fragmentName/variables组装成传给 Apollocache.watchFragment的稳定配置L360-L366订阅与清理用watch监听 observable变化时先退订旧订阅、立即同步初始结果再订阅后续更新组件作用域销毁onScopeDispose时统一退订防止泄漏L394-L420。其中值得注意的适配细节Apollo 的WatchFragmentResult字段名是data/dataState而useFragment对外暴露的是result/resultState二者由toCurrent辅助函数完成重命名映射useFragment.ts。另外该函数有 7 个重载overloads依据from的形态单值、数组、含 null、全 null 等精确推导返回的ResultTData类型useFragment.ts这也是它类型安全的关键来源。七、实战场景与进阶建议在列表组件与详情组件间共享数据父组件查询列表并写入缓存子组件用useFragment直接读取避免重复请求!-- UserProfile.vue -- script langts import { gql } from apollo/client export const USER_AVATAR_FRAGMENT gql fragment UserAvatarFields on User { id name avatarUrl } /script script setup langts import { useQuery } from vue/apollo-composable import { USER_AVATAR_FRAGMENT } from ./UserAvatar.vue const GET_USER_PROFILE gql query GetUserProfile($id: ID!) { user(id: $id) { id bio ...UserAvatarFields } } ${USER_AVATAR_FRAGMENT} const { current } useQuery(GET_USER_PROFILE, { variables: { id: 1 } }) /script!-- UserAvatar.vue -- script setup langts import { useFragment } from vue/apollo-composable import { USER_AVATAR_FRAGMENT } from ./UserAvatar.vue // 由父组件定义并传递 const props defineProps{ user: { __typename: User, id: string } }() const { current } useFragment({ fragment: USER_AVATAR_FRAGMENT, from: () props.user, }) /script这种片段fragment随组件就近定义的模式即文档所称的 fragment 组件化colocation配合 GraphQL Codegen 可自动合并各处 fragment 定义并生成类型安全的TypedDocumentNode详见 data/fragments.md 与 data/typescript.md。与数据掩码Data Masking配合useFragment的FromValue类型包含FragmentTypeTData这与 Apollo 的数据掩码机制data-masking.md直接兼容启用掩码后组件拿到的result只包含它自己声明的字段useFragment恰好是这类最小字段集消费场景的标准入口。使用注意事项缓存可识别性是前提确保实体的__typename与主键字段通常是id存在于缓存中否则cache.identify()返回null无法读取from为 null 时的占位结果此时complete恒为false、resultState为partial模板中应配合v-ifcurrent.complete之类的判断渲染多 client 场景通过clientId指定数据源未指定时使用默认 client不要与 GraphQL Codegen client preset 的graphql函数同时使用 fragment registrypreset 生成的预编译文档已内联 fragment 定义fragments.md。八、进一步阅读Fragments 完整指南定义、组合、组件化与 fragment registryData Masking用 fragment 隔离组件的字段访问Caching 概览缓存如何存储与识别实体TypeScriptGraphQL Codegen 配置与类型增强Multiple Clients多 Apollo client 场景下的clientId用法赞分享前端GraphQL【免费下载链接】apollo Apollo/GraphQL integration for VueJS项目地址https://gitcode.com/gh_mirrors/apollo2/apollo点击查看免费下载相关推荐Relay Hooks 精解useFragment 如何从 Relay Store 读取 Fragment 数据Relay Hooks 精解useFragment 如何从 Relay Store 读取 Fragment 数据 useFragment 是 Relay 在前端开发工具Linux 下 False Disassembly反汇编欺骗原理与实战基于 ctf-wiki 的代码隐藏技术解析Linux 下 False Disassembly反汇编欺骗原理与实战基于 ctf wiki 的代码隐藏技术解析 本文以 ctf wiki 仓库中 doc前端GraphQLyuzu Switch 模拟器教程从 NSP 文件到画面一共 4 步yuzu Switch 模拟器教程从 NSP 文件到画面一共 4 步 yuzu 是一款开源免费的 Switch 模拟器能在你的电脑上直接跑 NSP、XCI虚拟化桌面应用图形学上一篇3分钟掌握pdown下载器百度网盘免登录高速下载终极指南下一篇FitGirl Repack Launcher你的游戏下载管家让找游戏变得简单有趣创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考