Skip to content

useViewer

Managing the viewer based on provide / inject.

  • useViewer Get viewer instance.
  • useViewerProvider Provide viewer instance.

TIP

For more details about provide / inject, please refer to vue document

Usage

useViewerProvider

For parent component, use useViewerProvider to inject Viewer. useViewerProvider receives a callback returned a viewer instance, which can also be async function:

ts
useViewerProvider(() => new Cesium.Viewer(container.value))
ts
useViewerProvider(async () => {
  await fetch('/some/data')
  const viewer = new Cesium.Viewer(container.value)
  // ...
  return viewer
})

The callback function will be called in onMounted hook, therefore, you can safely use DOM references in callback functions.

  • isMounted is one of its return values. Its initial value is always ref(false), and it changes to ref(true) after the Viewer is mounted.
  • viewer is one of its return values. Its initial value is shallowRef(undefined), and it changes to shallowRef(viewer) after the Viewer is mounted. This is an alternative option, and in most cases, you don't need to use it. It's recommended to isolate the business components from the component initializing the Viewer to avoid the complexity of handling whether the Viewer is mounted.
vue
<script setup>
const container = useTemplateRef('container')

const { isMounted } = useViewerProvider(() => {
  const viewer = new Cesium.Viewer(container.value)
  // ...
  return viewer
})
</script>

<template>
  <div ref="container" />
  <!-- 确保子组件创建时,viewer已经完成初始化 -->
  <slot v-if="isMounted" />
</template>

useViewer

For child component, use useViewer to get the viewer instance provided by parent component.

vue
<script setup>
const viewer = useViewer()
console.log(viewer instanceof Cesium.Viewer) // true
</script>

<template>
  <div />
</template>

Error Checking Guide

Errors are typically caused by useViewer, and an error is thrown when useViewer fails to retrieve the viewer instance. Here are some common ways to check the error reasons.

Unable to Retrieve Context

Error Message

[cesium-use] Failed to get viewer because cannot get setup context.

This error message indicates that the setup context was not captured. For composition functions, you should call them within the setup context as outlined in the Vue official documentation.

Here are some common errors:

  • Calling in other lifecycle hooks: Since setup is an independent lifecycle, calling composition functions in other lifecycles will result in errors.
  • Calling within asynchronous tasks: Even if asynchronous tasks are executed within the setup period, since asynchronous tasks are not in the setup's synchronous call stack, calling composition functions within asynchronous tasks will obviously result in errors.

Viewer Not Yet Defined

Error Message

[cesium-use] Failed to get viewer because viewer is undefined now.

This error message indicates that the context has been captured, but the retrieved viewer is empty, indicating that the viewer has not been initialized at this point.

As shown in the example, you can control the generation of components by returning the value isMounted to ensure that child components are rendered after the viewer is initialized.

Handling Errors Manually

useViewer provides several optional parameters for handling unexpected behavior. By default, it throws an error when an error occurs (as explained above), but you can also choose to output error messages to the console or take no action. Refer to the type declarations for more details.

Type Declarations

Details
ts
export type UseViewerParam = "throw-error" | "no-throw-error" | "silent"
/**
 * Get `viewer` from the context.
 *
 * ## example
 * ```js
 * const viewer = useViewer() // strictly check viewer is existence
 * const viewerMaybeUndefined = useViewer('silent')
 * ```
 */
export declare function useViewer(): Viewer
/**
 * Accept a callback which will be called in `onMounted` hook and return a `Cesium.Viewer` instance. It can also be a async function.
 *
 * ## example
 * ```js
 * // normal
 * useViewerProvider(() => new Cesium.Viewer(container.value))
 *
 * // async callback
 * useViewerProvider(async () => {
 *   await fetch('/my/data')
 *   const viewer = new Cesium.Viewer(container.value)
 *   return viewer
 * })
 *
 * // returns
 * const { isMounted, viewer } = useViewerProvider(() => new Cesium.Viewer(container.value))
 * ```
 */
export declare function useViewerProvider(fn: () => Awaitable<Viewer>): {
  isMounted: Ref<boolean, boolean>
  viewer: ShallowRef<Viewer | undefined, Viewer | undefined>
}

Source

source