# React · Vue

> @82label/core 를 React·Vue 에서 쓰는 예제.

Source: https://82label.app/docs/frameworks/

`print()` 는 그냥 함수라 어느 프레임워크에서도 그대로 부르면 됩니다. React·Vue 전용 패키지는 준비 중이고, 아래처럼 코어만으로 충분합니다.

## React

```js
import { useState } from 'react';
import { print } from '@82label/core';
import template from './labels/product.json';

export function PrintLabelButton({ items }) {
  const [busy, setBusy] = useState(false);
  const onClick = async () => {
    setBusy(true);
    try {
      const rows = items.map((it) => ({ name: it.name, price: it.price, sku: it.sku }));
      const r = await print(template, rows);
      if (r.status === 'pending_permission') alert('출력 프로그램에서 이 사이트를 허용해 주세요.');
    } finally {
      setBusy(false);
    }
  };
  return <button onClick={onClick} disabled={busy}>라벨 인쇄</button>;
}
```

## 미리보기 (React)

```js
import { renderToSVG } from '@82label/core';

export function LabelPreview({ template, row }) {
  // renderToSVG 는 모든 값을 이스케이프하므로 그대로 넣어도 안전합니다
  return <div dangerouslySetInnerHTML={{ __html: renderToSVG(template, row) }} />;
}
```

## Vue

```vue
<script setup>
import { ref } from 'vue';
import { print } from '@82label/core';
import template from './labels/product.json';

const props = defineProps({ items: Array });
const busy = ref(false);

async function onPrint() {
  busy.value = true;
  try {
    await print(template, props.items.map((it) => ({ name: it.name, price: it.price, sku: it.sku })));
  } finally {
    busy.value = false;
  }
}
</script>

<template>
  <button :disabled="busy" @click="onPrint">라벨 인쇄</button>
</template>
```

## 웹 컴포넌트로

`<label-82>` 는 표준 웹 컴포넌트라 React 19·Vue 3 에서 태그로 써도 됩니다. Vue 는 `compilerOptions.isCustomElement` 에 `label-82` 를 알려 주세요.

```js
import { defineLabelElement } from '@82label/core';
import '@82label/core/styles.css';
defineLabelElement();

// React 19
<label-82 template="lbl_a1b2c3d4e5" data={JSON.stringify(rows)} button="인쇄" />
```

> SSR(Next.js, Nuxt)에서는 `print()` 를 브라우저 이벤트 안에서만 부르세요. `renderToSVG` 는 서버에서도 됩니다.
