feat: 条形码组件

This commit is contained in:
WANGFAN\wangf 2025-01-09 20:34:07 +08:00
parent 19a0f12336
commit e7402da940
6 changed files with 229 additions and 138 deletions

27
src/components.d.ts vendored
View File

@ -5,19 +5,20 @@
// Read more: https://github.com/vuejs/core/pull/3399
export {}
declare module 'vue' {
declare module "vue" {
export interface GlobalComponents {
CodeView: typeof import('./components/code-view/index.vue')['default']
ExternalLinkPage: typeof import('./components/external-link-page/index.vue')['default']
FillPage: typeof import('./components/fill-page/index.vue')['default']
InternalLinkPage: typeof import('./components/internal-link-page/index.vue')['default']
LangProvider: typeof import('./components/lang-provider/index.vue')['default']
MainTransition: typeof import('./components/main-transition/index.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SelectIcon: typeof import('./components/select-icon/index.vue')['default']
SvgAndIcon: typeof import('./components/svg-and-icon/index.vue')['default']
SvgIcon: typeof import('./components/svg-icon/index.vue')['default']
VerifyCode: typeof import('./components/verify-code/index.vue')['default']
CodeView: (typeof import("./components/code-view/index.vue"))["default"];
DrawBarcode: (typeof import("./components/draw-barcode/index.vue"))["default"];
ExternalLinkPage: (typeof import("./components/external-link-page/index.vue"))["default"];
FillPage: (typeof import("./components/fill-page/index.vue"))["default"];
InternalLinkPage: (typeof import("./components/internal-link-page/index.vue"))["default"];
LangProvider: (typeof import("./components/lang-provider/index.vue"))["default"];
MainTransition: (typeof import("./components/main-transition/index.vue"))["default"];
RouterLink: (typeof import("vue-router"))["RouterLink"];
RouterView: (typeof import("vue-router"))["RouterView"];
SelectIcon: (typeof import("./components/select-icon/index.vue"))["default"];
SvgAndIcon: (typeof import("./components/svg-and-icon/index.vue"))["default"];
SvgIcon: (typeof import("./components/svg-icon/index.vue"))["default"];
VerifyCode: (typeof import("./components/verify-code/index.vue"))["default"];
}
}

View File

@ -0,0 +1,32 @@
<template>
<component :is="tag" ref="nodes" />
</template>
<script setup lang="ts">
import JsBarcode from "jsbarcode";
const props = defineProps({
// svgimgcanvas
tag: {
type: String,
default: "svg"
},
//
text: {
type: String,
default: ""
},
//
// https://github.com/lindell/JsBarcode/wiki/Options
options: {
type: Object,
default() {
return {};
}
}
});
const nodes = ref();
onMounted(() => {
JsBarcode(nodes.value, props.text, props.options);
});
</script>

View File

@ -26,7 +26,6 @@ let { isFooter } = storeToRefs(themeStore);
<style lang="scss" scoped>
.layout {
height: 100vh;
border: 1px solid red;
}
.layout-right {
display: grid;

View File

@ -1,98 +1,98 @@
import NProgress from "@/config/nprogress";
import pinia from "@/store/index";
import { createRouter, createWebHashHistory } from "vue-router";
import { staticRoutes, notFoundAndNoPower } from "@/router/route.ts";
import { currentlyRoute } from "@/router/route-output";
import { storeToRefs } from "pinia";
import { useUserInfoStore } from "@/store/modules/user-info";
import { useRoutesConfigStore } from "@/store/modules/route-config";
import { useRoutingMethod } from "@/hooks/useRoutingMethod";
import { loadingPage } from "@/utils/loading-page";
/**
* vue的路由示例
* @method createRouter(options: RouterOptions): Router
* @link https://next.router.vuejs.org/zh/api/#createrouter
*/
const router = createRouter({
history: createWebHashHistory(),
/**
* addRoute动态添加
* 1staticRoutes登录页
* 2notFoundAndNoPower 404401 No match found for location with path 'xxx'
* 2 notFoundAndNoPower 404401
* notFoundAndNoPower 404401
* notFoundAndNoPower layout容器展示
*/
routes: [...staticRoutes, ...notFoundAndNoPower]
});
/**
*
* 1token
* 2token
* 3tokenhome页
* 4token
*
* routeTree不能持久化缓存
* addRoute动态添加的路由失效
*/
router.beforeEach(async (to, from, next) => {
NProgress.start(); // 开启进度条
const store = useUserInfoStore(pinia);
const { token } = storeToRefs(store);
console.log("去", to, "来自", from);
// next()内部加了path等于跳转指定路由会再次触发router.beforeEach内部无参数等于放行不会触发router.beforeEach
if (to.path === "/login" && !token.value) {
// 1、去登录页无token放行
next();
} else if (!token.value) {
// 2、没有token直接重定向到登录页
next("/login");
} else if (to.path === "/login" && token.value) {
// 3、去登录页有token直接重定向到home页
next("/home");
// 项目内的跳转,处理跳转路由高亮
currentlyRoute(to.name as string);
} else {
// 4、去非登录页有token校验是否动态添加过路由添加过则放行未添加则执行路由初始化
const routeStore = useRoutesConfigStore(pinia);
const { routeTree } = storeToRefs(routeStore);
// 获取外链路由的处理函数
// 所有的路由正常放行,只不过额外判断是否是外链,如果是,则打开新窗口跳转外链
// 外链的页面依旧正常打开只不过不会参与缓存与tabs显示符合路由跳转的直觉
const { openExternalLinks } = useRoutingMethod();
// 如果缓存的路由是0则说明未动态添加路由先添加再跳转
// 解决刷新页面404的问题
if (routeTree.value.length == 0) {
loadingPage.start();
await routeStore.initSetRouter();
// 处理外链跳转
openExternalLinks(to);
// 处理完重新跳转
next({ path: to.path, query: to.query });
} else {
// 处理外链跳转
openExternalLinks(to);
// 动态路由添加过走这里,直接放行
next();
// 项目内的跳转,处理跳转路由高亮
currentlyRoute(to.name as string);
}
}
});
// 路由跳转错误
router.onError((error: any) => {
NProgress.done();
console.warn("路由错误", error.message);
});
// 路由加载后
router.afterEach(() => {
NProgress.done();
});
export default router;
import NProgress from "@/config/nprogress";
import pinia from "@/store/index";
import { createRouter, createWebHashHistory } from "vue-router";
import { staticRoutes, notFoundAndNoPower } from "@/router/route.ts";
import { currentlyRoute } from "@/router/route-output";
import { storeToRefs } from "pinia";
import { useUserInfoStore } from "@/store/modules/user-info";
import { useRoutesConfigStore } from "@/store/modules/route-config";
import { useRoutingMethod } from "@/hooks/useRoutingMethod";
import { loadingPage } from "@/utils/loading-page";
/**
* vue的路由示例
* @method createRouter(options: RouterOptions): Router
* @link https://next.router.vuejs.org/zh/api/#createrouter
*/
const router = createRouter({
history: createWebHashHistory(),
/**
* addRoute动态添加
* 1staticRoutes登录页
* 2notFoundAndNoPower 404401 No match found for location with path 'xxx'
* 2 notFoundAndNoPower 404401
* notFoundAndNoPower 404401
* notFoundAndNoPower layout容器展示
*/
routes: [...staticRoutes, ...notFoundAndNoPower]
});
/**
*
* 1token
* 2token
* 3tokenhome页
* 4token
*
* routeTree不能持久化缓存
* addRoute动态添加的路由失效
*/
router.beforeEach(async (to, _, next) => {
NProgress.start(); // 开启进度条
const store = useUserInfoStore(pinia);
const { token } = storeToRefs(store);
// console.log("去", to, "来自", from);
// next()内部加了path等于跳转指定路由会再次触发router.beforeEach内部无参数等于放行不会触发router.beforeEach
if (to.path === "/login" && !token.value) {
// 1、去登录页无token放行
next();
} else if (!token.value) {
// 2、没有token直接重定向到登录页
next("/login");
} else if (to.path === "/login" && token.value) {
// 3、去登录页有token直接重定向到home页
next("/home");
// 项目内的跳转,处理跳转路由高亮
currentlyRoute(to.name as string);
} else {
// 4、去非登录页有token校验是否动态添加过路由添加过则放行未添加则执行路由初始化
const routeStore = useRoutesConfigStore(pinia);
const { routeTree } = storeToRefs(routeStore);
// 获取外链路由的处理函数
// 所有的路由正常放行,只不过额外判断是否是外链,如果是,则打开新窗口跳转外链
// 外链的页面依旧正常打开只不过不会参与缓存与tabs显示符合路由跳转的直觉
const { openExternalLinks } = useRoutingMethod();
// 如果缓存的路由是0则说明未动态添加路由先添加再跳转
// 解决刷新页面404的问题
if (routeTree.value.length == 0) {
loadingPage.start();
await routeStore.initSetRouter();
// 处理外链跳转
openExternalLinks(to);
// 处理完重新跳转
next({ path: to.path, query: to.query });
} else {
// 处理外链跳转
openExternalLinks(to);
// 动态路由添加过走这里,直接放行
next();
// 项目内的跳转,处理跳转路由高亮
currentlyRoute(to.name as string);
}
}
});
// 路由跳转错误
router.onError((error: any) => {
NProgress.done();
console.warn("路由错误", error.message);
});
// 路由加载后
router.afterEach(() => {
NProgress.done();
});
export default router;

View File

@ -1,12 +1,14 @@
// 设置滚动条的样式
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
// 基于 WebKit 内核的浏览器
// 设置滚动条的样式圆角背景颜色
::-webkit-scrollbar-thumb {
width: 6px;
height: 6px;
background-color: $color-border-3;
border-radius: 6px;
}
@ -14,16 +16,19 @@
// 设置滚动条hover样式圆角背景颜色
::-webkit-scrollbar-thumb:hover {
width: 6px;
height: 6px;
background-color: $color-border-4;
}
// 设置IE/Edge浏览器滚动条的样式与webkit内核浏览器样式相同
::-ms-scrollbar-thumb {
width: 6px;
height: 6px;
background-color: $color-border-3;
border-radius: 6px;
}
::-ms-scrollbar-thumb:hover {
width: 6px;
height: 6px;
background-color: $color-border-4;
}

View File

@ -1,36 +1,90 @@
<template>
<div class="snow-page">
<div class="snow-inner">
<svg id="imgcode"></svg>
<div class="code-box">
<a-card v-for="item in codeList" :key="item.id" :title="item.docs" :style="{ width: '400px' }" hoverable>
<div class="card-content">
<draw-barcode :text="item.text" :options="item.options" />
</div>
</a-card>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import JsBarcode from "jsbarcode";
const createCode = () => {
JsBarcode("#imgcode", "123", {
format: "CODE39", //使
width: 3, //
height: 100, //
displayValue: true, //
text: "456", //
fontOptions: "bold italic", //使
font: "fantasy", //
textAlign: "left", //
textPosition: "top", //
textMargin: 5, //
fontSize: 15, //
background: "#eee", //
lineColor: "#2196f3", //
margin: 15 //
});
};
onMounted(() => {
createCode();
});
const codeList = ref([
{
id: 1,
text: "SnowAdmin",
docs: "CODE128-默认条形码",
options: {
format: "CODE128",
height: 100
}
},
{
id: 2,
text: "SnowAdmin",
docs: "自定义高度和颜色",
options: {
format: "CODE128",
height: 50,
background: "#f7f8fa",
lineColor: "#2962ff"
}
},
{
id: 3,
text: "SnowAdmin",
docs: "设置字体和倾斜",
options: {
format: "CODE128",
height: 100,
font: "fantasy",
fontOptions: "italic"
}
},
{
id: 4,
text: "SnowAdmin",
docs: "CODE39-商品条形码",
options: {
format: "CODE39",
height: 100
}
},
{
id: 5,
text: "6971318501227",
docs: "EAN13-商品条形码",
options: {
format: "EAN13",
height: 100
}
},
{
id: 6,
text: "123456789999",
docs: "UPC-商品条形码",
options: {
format: "UPC",
height: 100
}
}
]);
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.code-box {
display: flex;
flex-wrap: wrap;
gap: $margin;
.card-content {
display: flex;
align-items: center;
justify-content: center;
height: 120px;
}
}
</style>