在封裝過程中,我思考如何讓這個工具變得更靈活,支援多種條碼格式,同時考慮到使用者可能遇到的錯誤處理情況。我加入了自定義配置選項,讓開發者能調整掃描靈敏度和生成條碼的樣式。
首先,我們根據昨天撰寫的文件來撰寫 useBarCode
的型別。主要用於定義函式的參數型別和回傳值,讓開發者能在 TypeScript 中更方便地使用這個函式。
import { Ref } from 'vue';
import JsBarcode from 'jsbarcode';
export interface UseBarCodeOptions {
format?: JsBarcode.Format; // 條碼格式,如 CODE128, EAN, UPC
width?: number; // 條碼的寬度
height?: number; // 條碼的高度
displayValue?: boolean; // 是否顯示條碼下面的文字
text?: string; // 條碼顯示的文本
fontOptions?: string; // 字體選項(如 "bold", "italic")
font?: string; // 字體類型
textAlign?: 'left' | 'center' | 'right'; // 條碼文本的對齊方式
textPosition?: 'top' | 'bottom'; // 條碼文本顯示的位置
lineColor?: string; // 條碼的顏色
background?: string; // 條碼的背景顏色
margin?: number; // 條碼周圍的外邊距
}
export declare function useBarCode(
text: MaybeRefOrGetter<string>,
options?: UseBarCodeOptions
): {
barCodeUrl: Ref<string | null>;
};
接下來是 useBarCode
的原始碼部分。我們將使用 JsBarcode
生成條碼,並利用 Vue 的 Composition API 實現響應式管理。
import { computed } from 'vue';
import { toValue } from '@vueuse/core'; // 使用 toValue 來解析 MaybeRefOrGetter
import JsBarcode from 'jsbarcode';
interface UseBarCodeOptions {
format?: string;
width?: number;
height?: number;
displayValue?: boolean;
text?: string;
fontOptions?: string;
font?: string;
textAlign?: 'left' | 'center' | 'right';
textPosition?: 'top' | 'bottom';
lineColor?: string;
background?: string;
margin?: number;
}
export function useBarCode(
text: MaybeRefOrGetter<string>,
options?: UseBarCodeOptions
) {
// 函數用於生成條碼的 Data URL
const generateBarcode = (barcodeText: string): string | null => {
const svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
try {
JsBarcode(svgElement, barcodeText, {
format: options?.format || 'CODE128',
width: options?.width || 2,
height: options?.height || 100,
displayValue: options?.displayValue ?? true,
text: options?.text,
fontOptions: options?.fontOptions || '',
font: options?.font || 'monospace',
textAlign: options?.textAlign || 'center',
textPosition: options?.textPosition || 'bottom',
lineColor: options?.lineColor || '#000000',
background: options?.background || '#ffffff',
margin: options?.margin || 10,
});
// 將 SVG 元素轉換為字符串
const svgString = new XMLSerializer().serializeToString(svgElement);
// 將 SVG 字符串轉換為 Base64 格式的 Data URL
return `data:image/svg+xml;base64,${btoa(svgString)}`;
} catch (error) {
console.error('Error generating barcode:', error);
return null;
}
};
// 使用 computed 來生成條碼 URL
const barCodeUrl = computed(() => {
const barcodeText = toValue(text);
if (!barcodeText) {
return null; // 如果沒有有效的文本,返回 null
}
return generateBarcode(barcodeText);
});
return {
barCodeUrl,
};
}
UseBarCodeOptions
介面,用於描述可選的條碼配置參數。useBarCode
接收一個字符串或 MaybeRefOrGetter
作為文本參數,並返回一個包含條碼 URL (barCodeUrl
) 的對象,這個 URL 是基於 Base64 的 SVG 格式的 Data URL,適合直接用於顯示條碼圖像。computed
和 ref
),來管理條碼生成的響應式邏輯,並使用 VueUse 的 toValue
來處理 MaybeRefOrGetter
的輸入。JsBarcode
用於生成條碼,並且使用 SVG 作為輸出格式,這樣可以保持高解析度並且便於縮放操作。最終生成的 SVG 會被轉換為 Base64 格式的 Data URL,方便在 <img>
標籤中直接使用。generateBarcode
函數:
JsBarcode
生成條碼。可以通過用戶提供的選項來自定義條碼的外觀(如寬度、高度、顏色等)。computed
生成 barCodeUrl
:
computed
將條碼 URL 的生成邏輯封裝起來,當 text
發生變化時,computed
會自動重新計算並生成新的條碼 URL。computed
保證條碼生成的結果是基於 text
的變化自動更新的,並且有緩存機制,可以提升性能。這些改進使得 useBarCode
更加靈活和易用:
<img>
中展示。computed
而不是 watch
來追蹤變化和自動更新,使得代碼變得更加簡潔、集中和易於理解。computed
的緩存機制也使得條碼生成的計算更加高效。toValue
可以更靈活地處理 MaybeRefOrGetter
類型的輸入,使得代碼對於各種輸入類型具有更高的兼容性,符合 VueUse 的最佳實踐。這個源代碼可以直接在你的 Vue 應用中使用。useBarCode
會自動根據文本的變化生成新的條碼,並返回 Base64 的 URL,方便直接用於 <img>
標籤顯示。
<template>
<div>
<input v-model="text" placeholder="輸入要生成的條碼" />
<img v-if="barCodeUrl" :src="barCodeUrl" alt="條碼" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useBarCode } from './useBarCode';
const text = ref('1234567890');
const { barCodeUrl } = useBarCode(text);
</script>
既然是模仿 VueUse 工具,明天就來寫文件解析吧~