crossviewer-vue3
v1.0.2
Published
Vue 3 component for CrossViewer document viewer
Maintainers
Readme
Vue 3 CrossViewer
Namo CrossViewer의 Vue 3 지원 버전입니다.
소개
crossviewer-vue3는 Namo CrossViewer 문서 뷰어를 Vue 3 애플리케이션에서 쉽게 사용할 수 있도록 제공하는 컴포넌트 래퍼입니다. CrossViewer 컴포넌트와 useCrossViewer 컴포저블을 통해 문서 뷰어를 간편하게 통합할 수 있습니다.
Vue Support
vue 모듈이 설치되지 않았다면, 설치단계에서 vue 관련 의존 모듈 미설치에 관한 경고가 발생하게 됩니다. vue 설치 방법은 다음과 같습니다.
> npm install vue --savecrossviewer-vue3 패키지는 vue 3.3 버전 이상에서 지원됩니다.
TypeScript Support
crossviewer-vue3 패키지는 타입스크립트를 지원합니다. 다음 타입들을 제공합니다:
CrossViewerProps,CrossViewerHandle,CrossViewerEventCallbacksUseCrossViewerReturn,ViewerConfigOpenPayload,ErrorPayload,PageChangedPayload,SizeChangedPayload,PageThumbnailPayload
설치
Vue 3 환경에서 뷰어 컴포넌트를 생성하기 위해, crossviewer-vue3 패키지를 아래의 방법과 같이 설치할 수 있습니다.
> npm install crossviewer-vue3 --save--save 옵션을 활용하여 향후 의존 모듈을 재설치할 때에도 자동으로 설치하도록 권장합니다. 설치 후 package.json 파일에 다음과 같이 crossviewer-vue3 모듈이 추가됩니다.
{
"dependencies": {
"crossviewer-vue3": "^1.x.x"
}
}CrossViewer 스크립트 설정
크로스뷰어 스크립트는 별도로 제공되며 crossviewer-vue3에는 크로스뷰어 스크립트 파일이 포함되어 있지 않습니다.
크로스뷰어에 방문하여 크로스뷰어 제품 체험판을 받아볼 수 있습니다.
제공된 크로스뷰어 스크립트는 설치할 프로젝트 폴더의 public 경로 안으로 설치할 수 있습니다.
Copy to the Vue public subdirectory.
ex) /example/basic/public/crossviewer기본 경로
crossviewer-vue3는 스크립트 및 설정 파일에 대해 다음과 같은 기본 경로를 사용합니다. 크로스뷰어 스크립트를 public/crossviewer 경로에 설치했다면 별도의 경로 설정 없이 바로 사용할 수 있습니다.
| props | 기본값 |
|-------|--------|
| crossviewerScriptUrl | /crossviewer/js/crossviewer.js |
| engineScriptUrl | /crossviewer/lib/crepas-viewer.min.js |
| configUrl | /crossviewer/config/config.json |
| viewerInfoUrl | /crossviewer/config/viewerInfo.json |
참고:
engineScriptUrl에 필요한clientId파라미터는viewerInfoUrl에서 지정한viewerInfo.json파일에서 자동으로 읽어와 엔진 스크립트 URL에 추가됩니다.
기본 경로와 다른 위치에 스크립트를 설치한 경우, 해당 props를 통해 경로를 직접 지정할 수 있습니다:
<CrossViewer
crossviewer-script-url="/custom/path/crossviewer.js"
engine-script-url="/custom/path/crepas-viewer.min.js"
config-url="/custom/path/config.json"
viewer-info-url="/custom/path/viewerInfo.json"
/>사용법 - CrossViewer 컴포넌트
설치가 완료되었다면, CrossViewer를 임포트하여 사용할 수 있습니다.
<script setup lang="ts">
import { ref } from 'vue';
import { CrossViewer } from 'crossviewer-vue3';
import type {
CrossViewerHandle,
OpenPayload,
ErrorPayload,
PageChangedPayload,
} from 'crossviewer-vue3';
const viewerRef = ref<CrossViewerHandle | null>(null);
const status = ref('뷰어 로딩 중...');
const pageInfo = ref('');
function onOpen(payload: OpenPayload) {
status.value = payload.result > 0
? `문서 열림 (${payload.totalPages}페이지)`
: '문서 열기 실패';
}
function onOpenCompleted() {
status.value += ' - 렌더링 완료';
}
function onError(payload: ErrorPayload) {
status.value = `에러: ${payload.message}`;
}
function onPageChanged(info: PageChangedPayload) {
pageInfo.value = `${info.page} / ${info.totalPages}`;
}
function onZoomChanged(scale: number) {
console.log('zoom:', scale);
}
</script>
<template>
<div style="width: 100%; height: 100%">
<CrossViewer
ref="viewerRef"
lang="kor"
:style="{ width: '100%', height: '100%' }"
@open="onOpen"
@open-completed="onOpenCompleted"
@error="onError"
@page-changed="onPageChanged"
@zoom-changed="onZoomChanged"
/>
</div>
</template>이벤트는 Vue emit(
@open) 방식과 props(:onOpen) 방식 모두 지원합니다.
사용법 - useCrossViewer 컴포저블
useCrossViewer 컴포저블을 사용하면 뷰어의 ref, 준비 상태, 에러 상태를 간편하게 관리할 수 있습니다.
<script setup lang="ts">
import { useCrossViewer } from 'crossviewer-vue3';
const { viewerRef, isReady, error } = useCrossViewer({
containerId: 'my-viewer',
lang: 'kor',
onPageChanged: (info) => console.log(info),
});
function handleOpenUrl() {
viewerRef.value?.open.url('/documents/sample.pdf');
}
</script>
<template>
<div>
<p v-if="error">에러: {{ error.message }}</p>
<p v-if="!isReady">뷰어 준비 중...</p>
<div id="my-viewer" style="width: 100%; height: 600px" />
<button :disabled="!isReady" @click="handleOpenUrl">
문서 열기
</button>
</div>
</template>Props
CrossViewerProps
| 속성 | 타입 | 필수 | 설명 |
|------|------|------|------|
| crossviewerScriptUrl | string | - | crossviewer.js 번들 경로 (스크립트 태그로 로드) |
| engineScriptUrl | string | - | crepas-viewer.min.js WASM 엔진 스크립트 경로 |
| instanceName | string | - | 멀티 인스턴스 구분용 이름 |
| class | string | - | 컨테이너 div class |
| style | CSSProperties \| string | - | 컨테이너 div style |
| lang | string | - | 언어 설정 ('kor', 'enu', 'jpn', 'chs', 'cht', 'vit', 'ind', 'fra', 'auto') |
| theme | string | - | 테마 ('light', 'dark') |
| documentType | string | - | 문서 타입 |
| panel | object | - | 패널 설정 (useThumbnailPanel, initialThumbailPanel) |
| searchEnabled | boolean | - | 텍스트 검색 활성화 |
| downloadEnabled | boolean | - | 다운로드 활성화 |
| printEnabled | boolean | - | 인쇄 활성화 |
| initialScaleValue | Record<string, string> | - | 초기 줌 레벨 |
| scaleIncrement | number | - | 줌 증가 단위 |
| allowedFileExtensions | string[] | - | 허용 파일 확장자 목록 |
| allowFileUrlOpen | boolean | - | URL을 통한 파일 열기 허용 |
| fileStreamUrl | string | - | 파일 스트림 URL |
| configUrl | string | - | 설정 파일 경로 |
| instanceConfigUrl | string | - | 인스턴스 설정 파일 경로 |
| mobileConfigUrl | string | - | 모바일 설정 파일 경로 |
| mobileInstanceConfigUrl | string | - | 모바일 인스턴스 설정 파일 경로 |
| viewerInfoUrl | string | - | 뷰어 정보 파일 경로 |
| urlParams | Record<string, string> | - | URL 파라미터 |
| pageTransitionDirection | string | - | 페이지 전환 방향 ('vertical', 'horizontal') |
이벤트 콜백
CrossViewerEventCallbacks
Vue의 @event 디렉티브(emit 방식) 또는 :onXxx props 방식 모두 지원합니다.
| 콜백 Prop | Emit | 파라미터 | 설명 |
|-----------|------|----------|------|
| onOpen | @open | (payload: OpenPayload) => void | 문서 열기 결과 (성공/실패, 페이지 수) |
| onOpenCompleted | @open-completed | () => void | 문서 렌더링 완전 완료 (썸네일 포함) |
| onError | @error | (payload: ErrorPayload) => void | 뷰어 에러 발생 |
| onPageChanged | @page-changed | (payload: PageChangedPayload) => void | 페이지 이동 |
| onZoomChanged | @zoom-changed | (scale: number) => void | 줌 레벨 변경 |
| onStateChange | @state-change | (state: unknown) => void | 뷰어 전체 상태 변경 |
| onFindText | @find-text | (status: number) => void | 텍스트 검색 결과 상태 |
| onSizeChanged | @size-changed | (payload: SizeChangedPayload) => void | 캔버스 크기 변경 |
| onPageThumbnail | @page-thumbnail | (payload: PageThumbnailPayload) => void | 썸네일 렌더링 완료 |
이벤트 페이로드 타입
| 타입 | 필드 | 설명 |
|------|------|------|
| OpenPayload | result: number, page?: number, totalPages?: number | 문서 열기 결과 정보 |
| ErrorPayload | message: string | 에러 메시지 |
| PageChangedPayload | page: number, totalPages: number | 현재 페이지 및 전체 페이지 수 |
| SizeChangedPayload | width: number, height: number | 캔버스 크기 |
| PageThumbnailPayload | page: number, width: number, height: number | 썸네일 페이지 및 크기 |
Ref Handle API
CrossViewerHandle은 템플릿 ref를 통해 뷰어 인스턴스를 제어할 수 있는 API를 제공합니다.
| 메서드 | 시그니처 | 설명 |
|--------|----------|------|
| open.url | (url: string) => Promise<boolean> | URL을 통해 문서 열기 |
| open.stream | (fileId: string) => Promise<boolean> | 파일 ID로 스트림 문서 열기 |
| open.streamURL | (url: string) => Promise<boolean> | URL로 스트림 문서 열기 |
| destroy | () => void | 뷰어 인스턴스 정리 |
| showLoading | (show: boolean) => void | 로딩 표시 제어 |
| showError | (args: { message: string }) => void | 에러 메시지 표시 |
| getInstance | () => unknown \| null | 내부 CrossViewer 인스턴스 직접 접근 (escape hatch) |
<script setup lang="ts">
import { ref } from 'vue';
import { CrossViewer } from 'crossviewer-vue3';
import type { CrossViewerHandle } from 'crossviewer-vue3';
const viewerRef = ref<CrossViewerHandle | null>(null);
// URL로 문서 열기
await viewerRef.value?.open.url('/documents/sample.pdf');
// 스트림으로 문서 열기
await viewerRef.value?.open.stream('file-id-123');
// 로딩 표시
viewerRef.value?.showLoading(true);
// 인스턴스 정리
viewerRef.value?.destroy();
</script>Documentation and Example
crossviewer-vue3의 사용 예제와 가이드를 제공합니다.
/example/README.md| 예제 | 경로 | 설명 |
|------|------|------|
| basic | /example/basic | JavaScript 기본 사용 예제 |
| basic-typescript | /example/basic-typescript | TypeScript 기본 사용 예제 |
| component-events-emit | /example/component-events-emit | Vue emit(@event) 방식 이벤트 예제 |
| component-events-ref | /example/component-events-ref | ref를 통한 이벤트 제어 예제 |
| composable-events | /example/composable-events | useCrossViewer 컴포저블 사용 예제 |
| router | /example/router | Vue Router 연동 예제 |
주의 사항
설정 변경 시 key 속성 사용
lang, theme 등 설정 props는 마운트 시점에만 적용됩니다. 런타임에 설정을 변경하려면 :key 속성을 변경하여 컴포넌트를 다시 마운트하세요.
<script setup lang="ts">
import { ref } from 'vue';
const lang = ref<'kor' | 'enu'>('kor');
</script>
<template>
<CrossViewer
:key="lang"
:lang="lang"
<!-- ...기타 props -->
/>
</template>라이선스
크로스뷰어의 자세한 옵션은 Namo CrossEditor를 참고하시기 바랍니다.
