WidgetKit如何在widget视图加载前执行API调用获取待展示数据
实现Widget视图加载前完成API调用的方案
核心逻辑非常简单:把API调用的时序提前到视图渲染逻辑触发之前,等接口返回数据之后再初始化/挂载Widget视图,不要等视图挂载完成后再发起请求。以下是不同场景的具体实现方式:
原生JS实现
- 先执行
fetch/XMLHttpRequest请求拉取接口数据 - 拿到数据之后,再动态创建Widget DOM节点,填充数据后再插入到页面文档流
代码示例:
// 第一步先发起API请求 fetch('你的接口地址') .then(res => res.json()) .then(data => { // 拿到数据后再创建Widget节点 const widget = document.createElement('div') widget.className = 'custom-widget' // 直接把数据填充到节点 widget.textContent = `展示内容:${data.需要展示的字段}` // 插入到页面指定位置,此时Widget视图才完成加载 document.querySelector('#widget挂载容器').appendChild(widget) }) .catch(err => { // 异常兼容:接口报错时插入错误提示 const widget = document.createElement('div') widget.textContent = '数据加载失败' document.querySelector('#widget挂载容器').appendChild(widget) })
React框架实现
有两种常用方案可选:
- 父组件提前发起请求,用条件渲染控制Widget的渲染时机
代码示例:
import { useState, useEffect } from 'react' import CustomWidget from './CustomWidget' function ParentComponent() { const [widgetData, setWidgetData] = useState(null) const [isLoading, setIsLoading] = useState(true) // 父组件初始化阶段就触发请求 useEffect(() => { const fetchData = async () => { const res = await fetch('你的接口地址') const data = await res.json() setWidgetData(data) setIsLoading(false) } fetchData() }, []) if (isLoading) return <div>加载中...</div> // 拿到数据后才渲染Widget组件,此时Widget加载时已经持有数据 return <CustomWidget data={widgetData} /> }
- 独立Widget组件可以用Suspense + 异步组件的方式,把API请求逻辑放在组件加载前执行
Vue框架实现
- 如果Widget在路由页面内,可以直接在路由
beforeEnter守卫里提前拉取数据,存储到pinia/vuex或者路由参数中,再进入页面渲染 - 父组件初始化阶段发请求,条件渲染Widget
代码示例:
<script setup> import { ref, onBeforeMount } from 'vue' import CustomWidget from './CustomWidget.vue' const widgetData = ref(null) const isLoading = ref(true) // 组件挂载前就发起请求 onBeforeMount(async () => { const res = await fetch('你的接口地址') widgetData.value = await res.json() isLoading.value = false }) </script> <template> <div v-if="isLoading">加载中...</div> <CustomWidget v-else :data="widgetData" /> </template>
原生端Widget通用逻辑
如果是安卓App Widget、iOS小组件这类原生系统Widget,统一逻辑也是在Widget生命周期初始化阶段(安卓的onUpdate触发前、iOS的getTimeline回调中)先执行网络请求,拿到数据后再配置Widget的视图渲染参数。
内容的提问来源于stack exchange,提问作者Erik Auranaune
相关产品推荐
相关产品推荐

