mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-11-09 13:53:38 +08:00
refactor: use setup refactor
This commit is contained in:
@@ -1,3 +1,52 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, Ref } from "vue";
|
||||
import { useRoute, useRouter, RouteLocationMatched } from "vue-router";
|
||||
|
||||
const levelList: Ref<RouteLocationMatched[]> = ref([]);
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const isDashboard = (route: RouteLocationMatched): boolean | string => {
|
||||
const name = route && (route.name as string);
|
||||
if (!name) {
|
||||
return false;
|
||||
}
|
||||
return name.trim().toLocaleLowerCase() === "welcome".toLocaleLowerCase();
|
||||
};
|
||||
|
||||
const getBreadcrumb = (): void => {
|
||||
let matched = route.matched.filter(item => item.meta && item.meta.title);
|
||||
const first = matched[0];
|
||||
if (!isDashboard(first)) {
|
||||
matched = [
|
||||
{
|
||||
path: "/welcome",
|
||||
meta: { title: "message.hshome" }
|
||||
} as unknown as RouteLocationMatched
|
||||
].concat(matched);
|
||||
}
|
||||
levelList.value = matched.filter(
|
||||
item => item.meta && item.meta.title && item.meta.breadcrumb !== false
|
||||
);
|
||||
};
|
||||
|
||||
getBreadcrumb();
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => getBreadcrumb()
|
||||
);
|
||||
|
||||
const handleLink = (item: RouteLocationMatched): any => {
|
||||
const { redirect, path } = item;
|
||||
if (redirect) {
|
||||
router.push(redirect.toString());
|
||||
return;
|
||||
}
|
||||
router.push(path);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-breadcrumb class="app-breadcrumb" separator="/">
|
||||
<transition-group appear name="breadcrumb">
|
||||
@@ -15,62 +64,6 @@
|
||||
</el-breadcrumb>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { ref, defineComponent, watch, Ref } from "vue";
|
||||
import { useRoute, useRouter, RouteLocationMatched } from "vue-router";
|
||||
|
||||
export default defineComponent({
|
||||
name: "ReBreadCrumb",
|
||||
setup() {
|
||||
const levelList: Ref<RouteLocationMatched[]> = ref([]);
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const isDashboard = (route: RouteLocationMatched): boolean | string => {
|
||||
const name = route && (route.name as string);
|
||||
if (!name) {
|
||||
return false;
|
||||
}
|
||||
return name.trim().toLocaleLowerCase() === "welcome".toLocaleLowerCase();
|
||||
};
|
||||
|
||||
const getBreadcrumb = (): void => {
|
||||
let matched = route.matched.filter(item => item.meta && item.meta.title);
|
||||
const first = matched[0];
|
||||
if (!isDashboard(first)) {
|
||||
matched = [
|
||||
{
|
||||
path: "/welcome",
|
||||
meta: { title: "message.hshome" }
|
||||
} as unknown as RouteLocationMatched
|
||||
].concat(matched);
|
||||
}
|
||||
levelList.value = matched.filter(
|
||||
item => item.meta && item.meta.title && item.meta.breadcrumb !== false
|
||||
);
|
||||
};
|
||||
|
||||
getBreadcrumb();
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => getBreadcrumb()
|
||||
);
|
||||
|
||||
const handleLink = (item: RouteLocationMatched): any => {
|
||||
const { redirect, path } = item;
|
||||
if (redirect) {
|
||||
router.push(redirect.toString());
|
||||
return;
|
||||
}
|
||||
router.push(path);
|
||||
};
|
||||
|
||||
return { levelList, handleLink };
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-breadcrumb.el-breadcrumb {
|
||||
display: inline-block;
|
||||
|
||||
@@ -1,3 +1,109 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, unref, nextTick, onUnmounted } from "vue";
|
||||
import { templateRef } from "@vueuse/core";
|
||||
import flippers from "./Filpper";
|
||||
|
||||
let timer = ref(null);
|
||||
let flipObjs = ref([]);
|
||||
|
||||
const flipperHour1 = templateRef<HTMLElement | null>("flipperHour1", null);
|
||||
const flipperHour2 = templateRef<HTMLElement | null>("flipperHour2", null);
|
||||
const flipperMinute1 = templateRef<HTMLElement | null>("flipperMinute1", null);
|
||||
const flipperMinute2 = templateRef<HTMLElement | null>("flipperMinute2", null);
|
||||
const flipperSecond1 = templateRef<HTMLElement | null>("flipperSecond1", null);
|
||||
const flipperSecond2 = templateRef<HTMLElement | null>("flipperSecond2", null);
|
||||
|
||||
// 初始化数字
|
||||
const init = () => {
|
||||
let now = new Date();
|
||||
let nowTimeStr = formatDate(new Date(now.getTime()), "hhiiss");
|
||||
for (let i = 0; i < flipObjs.value.length; i++) {
|
||||
flipObjs?.value[i]?.setFront(nowTimeStr[i]);
|
||||
}
|
||||
};
|
||||
|
||||
// 开始计时
|
||||
const run = () => {
|
||||
timer.value = setInterval(() => {
|
||||
// 获取当前时间
|
||||
let now = new Date();
|
||||
let nowTimeStr = formatDate(new Date(now.getTime() - 1000), "hhiiss");
|
||||
let nextTimeStr = formatDate(now, "hhiiss");
|
||||
for (let i = 0; i < flipObjs.value.length; i++) {
|
||||
if (nowTimeStr[i] === nextTimeStr[i]) {
|
||||
continue;
|
||||
}
|
||||
flipObjs?.value[i]?.flipDown(nowTimeStr[i], nextTimeStr[i]);
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
// 正则格式化日期
|
||||
const formatDate = (date: Date, dateFormat: string) => {
|
||||
/* 单独格式化年份,根据y的字符数量输出年份
|
||||
* 例如:yyyy => 2019
|
||||
yy => 19
|
||||
y => 9
|
||||
*/
|
||||
if (/(y+)/.test(dateFormat)) {
|
||||
dateFormat = dateFormat.replace(
|
||||
RegExp.$1,
|
||||
(date.getFullYear() + "").substr(4 - RegExp.$1.length)
|
||||
);
|
||||
}
|
||||
// 格式化月、日、时、分、秒
|
||||
let o = {
|
||||
"m+": date.getMonth() + 1,
|
||||
"d+": date.getDate(),
|
||||
"h+": date.getHours(),
|
||||
"i+": date.getMinutes(),
|
||||
"s+": date.getSeconds()
|
||||
};
|
||||
for (let k in o) {
|
||||
if (new RegExp(`(${k})`).test(dateFormat)) {
|
||||
// 取出对应的值
|
||||
let str = o[k] + "";
|
||||
/* 根据设置的格式,输出对应的字符
|
||||
* 例如: 早上8时,hh => 08,h => 8
|
||||
* 但是,当数字>=10时,无论格式为一位还是多位,不做截取,这是与年份格式化不一致的地方
|
||||
* 例如: 下午15时,hh => 15, h => 15
|
||||
*/
|
||||
dateFormat = dateFormat.replace(
|
||||
RegExp.$1,
|
||||
RegExp.$1.length === 1 ? str : padLeftZero(str)
|
||||
);
|
||||
}
|
||||
}
|
||||
return dateFormat;
|
||||
};
|
||||
|
||||
// 日期时间补零
|
||||
const padLeftZero = (str: string | any[]) => {
|
||||
return ("00" + str).substr(str.length);
|
||||
};
|
||||
|
||||
nextTick(() => {
|
||||
flipObjs.value = [
|
||||
unref(flipperHour1),
|
||||
unref(flipperHour2),
|
||||
unref(flipperMinute1),
|
||||
unref(flipperMinute2),
|
||||
unref(flipperSecond1),
|
||||
unref(flipperSecond2)
|
||||
];
|
||||
|
||||
init();
|
||||
run();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer.value) {
|
||||
clearInterval(timer.value);
|
||||
timer.value = null;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flip-clock">
|
||||
<flippers ref="flipperHour1" />
|
||||
@@ -11,147 +117,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { ref, unref, nextTick, onUnmounted } from "vue";
|
||||
import flippers from "./Filpper";
|
||||
|
||||
import { templateRef } from "@vueuse/core";
|
||||
export default {
|
||||
name: "Flop",
|
||||
components: {
|
||||
flippers
|
||||
},
|
||||
setup() {
|
||||
let timer = ref(null);
|
||||
let flipObjs = ref([]);
|
||||
|
||||
const flipperHour1 = templateRef<HTMLElement | null>("flipperHour1", null);
|
||||
const flipperHour2 = templateRef<HTMLElement | null>("flipperHour2", null);
|
||||
const flipperMinute1 = templateRef<HTMLElement | null>(
|
||||
"flipperMinute1",
|
||||
null
|
||||
);
|
||||
const flipperMinute2 = templateRef<HTMLElement | null>(
|
||||
"flipperMinute2",
|
||||
null
|
||||
);
|
||||
const flipperSecond1 = templateRef<HTMLElement | null>(
|
||||
"flipperSecond1",
|
||||
null
|
||||
);
|
||||
const flipperSecond2 = templateRef<HTMLElement | null>(
|
||||
"flipperSecond2",
|
||||
null
|
||||
);
|
||||
|
||||
// 初始化数字
|
||||
const init = () => {
|
||||
let now = new Date();
|
||||
let nowTimeStr = formatDate(new Date(now.getTime()), "hhiiss");
|
||||
for (let i = 0; i < flipObjs.value.length; i++) {
|
||||
flipObjs?.value[i]?.setFront(nowTimeStr[i]);
|
||||
}
|
||||
};
|
||||
|
||||
// 开始计时
|
||||
const run = () => {
|
||||
timer.value = setInterval(() => {
|
||||
// 获取当前时间
|
||||
let now = new Date();
|
||||
let nowTimeStr = formatDate(new Date(now.getTime() - 1000), "hhiiss");
|
||||
let nextTimeStr = formatDate(now, "hhiiss");
|
||||
for (let i = 0; i < flipObjs.value.length; i++) {
|
||||
if (nowTimeStr[i] === nextTimeStr[i]) {
|
||||
continue;
|
||||
}
|
||||
flipObjs?.value[i]?.flipDown(nowTimeStr[i], nextTimeStr[i]);
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
// 正则格式化日期
|
||||
const formatDate = (date: Date, dateFormat: string) => {
|
||||
/* 单独格式化年份,根据y的字符数量输出年份
|
||||
* 例如:yyyy => 2019
|
||||
yy => 19
|
||||
y => 9
|
||||
*/
|
||||
if (/(y+)/.test(dateFormat)) {
|
||||
dateFormat = dateFormat.replace(
|
||||
RegExp.$1,
|
||||
(date.getFullYear() + "").substr(4 - RegExp.$1.length)
|
||||
);
|
||||
}
|
||||
// 格式化月、日、时、分、秒
|
||||
let o = {
|
||||
"m+": date.getMonth() + 1,
|
||||
"d+": date.getDate(),
|
||||
"h+": date.getHours(),
|
||||
"i+": date.getMinutes(),
|
||||
"s+": date.getSeconds()
|
||||
};
|
||||
for (let k in o) {
|
||||
if (new RegExp(`(${k})`).test(dateFormat)) {
|
||||
// 取出对应的值
|
||||
let str = o[k] + "";
|
||||
/* 根据设置的格式,输出对应的字符
|
||||
* 例如: 早上8时,hh => 08,h => 8
|
||||
* 但是,当数字>=10时,无论格式为一位还是多位,不做截取,这是与年份格式化不一致的地方
|
||||
* 例如: 下午15时,hh => 15, h => 15
|
||||
*/
|
||||
dateFormat = dateFormat.replace(
|
||||
RegExp.$1,
|
||||
RegExp.$1.length === 1 ? str : padLeftZero(str)
|
||||
);
|
||||
}
|
||||
}
|
||||
return dateFormat;
|
||||
};
|
||||
|
||||
// 日期时间补零
|
||||
const padLeftZero = (str: string | any[]) => {
|
||||
return ("00" + str).substr(str.length);
|
||||
};
|
||||
|
||||
nextTick(() => {
|
||||
flipObjs.value = [
|
||||
unref(flipperHour1),
|
||||
unref(flipperHour2),
|
||||
unref(flipperMinute1),
|
||||
unref(flipperMinute2),
|
||||
unref(flipperSecond1),
|
||||
unref(flipperSecond2)
|
||||
];
|
||||
|
||||
init();
|
||||
run();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer.value) {
|
||||
clearInterval(timer.value);
|
||||
timer.value = null;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
timer,
|
||||
flipObjs,
|
||||
init,
|
||||
run,
|
||||
formatDate,
|
||||
padLeftZero,
|
||||
flipperHour1,
|
||||
flipperHour2,
|
||||
flipperMinute1,
|
||||
flipperMinute2,
|
||||
flipperSecond1,
|
||||
flipperSecond2
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.flip-clock .m-flipper {
|
||||
margin: 0 3px;
|
||||
|
||||
@@ -1,3 +1,92 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, unref, onMounted } from "vue";
|
||||
import { templateRef } from "@vueuse/core";
|
||||
import { LogicFlow } from "@logicflow/core";
|
||||
|
||||
interface Props {
|
||||
lf: LogicFlow;
|
||||
catTurboData?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
lf: null
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "catData"): void;
|
||||
}>();
|
||||
|
||||
const controlButton3 = templateRef<HTMLElement | any>("controlButton3", null);
|
||||
const controlButton4 = templateRef<HTMLElement | any>("controlButton4", null);
|
||||
|
||||
let focusIndex = ref<Number>(-1);
|
||||
let titleLists = ref([
|
||||
{
|
||||
icon: "icon-zoom-out-hs",
|
||||
text: "缩小",
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
icon: "icon-enlarge-hs",
|
||||
text: "放大",
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
icon: "icon-full-screen-hs",
|
||||
text: "适应",
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
icon: "icon-previous-hs",
|
||||
text: "上一步",
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
icon: "icon-next-step-hs",
|
||||
text: "下一步",
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
icon: "icon-download-hs",
|
||||
text: "下载图片",
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
icon: "icon-watch-hs",
|
||||
text: "查看数据",
|
||||
disabled: false
|
||||
}
|
||||
]);
|
||||
|
||||
const onControl = (item, key) => {
|
||||
["zoom", "zoom", "resetZoom", "undo", "redo", "getSnapshot"].forEach(
|
||||
(v, i) => {
|
||||
let domControl = props.lf;
|
||||
if (key === 1) {
|
||||
domControl.zoom(true);
|
||||
}
|
||||
if (key === 6) {
|
||||
emit("catData");
|
||||
}
|
||||
if (key === i) {
|
||||
domControl[v]();
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const onEnter = key => {
|
||||
focusIndex.value = key;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
props.lf.on("history:change", ({ data: { undoAble, redoAble } }) => {
|
||||
unref(titleLists)[3].disabled = unref(controlButton3).disabled = !undoAble;
|
||||
unref(titleLists)[4].disabled = unref(controlButton4).disabled = !redoAble;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="control-container">
|
||||
<!-- 功能按钮 -->
|
||||
@@ -26,106 +115,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, unref, onMounted } from "vue";
|
||||
import { templateRef } from "@vueuse/core";
|
||||
|
||||
export default defineComponent({
|
||||
name: "Control",
|
||||
props: {
|
||||
lf: null,
|
||||
catTurboData: Boolean
|
||||
},
|
||||
emits: ["catData"],
|
||||
setup(props, { emit }) {
|
||||
const controlButton3 = templateRef<HTMLElement | any>(
|
||||
"controlButton3",
|
||||
null
|
||||
);
|
||||
const controlButton4 = templateRef<HTMLElement | any>(
|
||||
"controlButton4",
|
||||
null
|
||||
);
|
||||
|
||||
let focusIndex = ref(-1);
|
||||
let titleLists = ref([
|
||||
{
|
||||
icon: "icon-zoom-out-hs",
|
||||
text: "缩小",
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
icon: "icon-enlarge-hs",
|
||||
text: "放大",
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
icon: "icon-full-screen-hs",
|
||||
text: "适应",
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
icon: "icon-previous-hs",
|
||||
text: "上一步",
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
icon: "icon-next-step-hs",
|
||||
text: "下一步",
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
icon: "icon-download-hs",
|
||||
text: "下载图片",
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
icon: "icon-watch-hs",
|
||||
text: "查看数据",
|
||||
disabled: false
|
||||
}
|
||||
]);
|
||||
|
||||
const onControl = (item, key) => {
|
||||
["zoom", "zoom", "resetZoom", "undo", "redo", "getSnapshot"].forEach(
|
||||
(v, i) => {
|
||||
let domControl = props.lf;
|
||||
if (key === 1) {
|
||||
domControl.zoom(true);
|
||||
}
|
||||
if (key === 6) {
|
||||
emit("catData");
|
||||
}
|
||||
if (key === i) {
|
||||
domControl[v]();
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const onEnter = key => {
|
||||
focusIndex.value = key;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
props.lf.on("history:change", ({ data: { undoAble, redoAble } }) => {
|
||||
unref(titleLists)[3].disabled = unref(controlButton3).disabled =
|
||||
!undoAble;
|
||||
unref(titleLists)[4].disabled = unref(controlButton4).disabled =
|
||||
!redoAble;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
focusIndex,
|
||||
titleLists,
|
||||
onControl,
|
||||
onEnter
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@import "./assets/iconfont/iconfont.css";
|
||||
|
||||
|
||||
@@ -1,23 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import VueJsonPretty from "vue-json-pretty";
|
||||
import "vue-json-pretty/lib/styles.css";
|
||||
|
||||
const props = defineProps({
|
||||
graphData: Object
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<vue-json-pretty
|
||||
:path="'res'"
|
||||
:deep="3"
|
||||
:showLength="true"
|
||||
:data="graphData"
|
||||
:data="props.graphData"
|
||||
></vue-json-pretty>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import VueJsonPretty from "vue-json-pretty";
|
||||
import "vue-json-pretty/lib/styles.css";
|
||||
import { defineComponent } from "vue";
|
||||
export default defineComponent({
|
||||
name: "DataDialog",
|
||||
props: {
|
||||
graphData: Object
|
||||
},
|
||||
components: {
|
||||
VueJsonPretty
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,9 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, unref } from "vue";
|
||||
import { LogicFlow } from "@logicflow/core";
|
||||
|
||||
interface Props {
|
||||
lf: LogicFlow;
|
||||
nodeList: ForDataType<undefined>;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
lf: null,
|
||||
nodeList: null
|
||||
});
|
||||
|
||||
let properties = ref({
|
||||
a: "efrwe",
|
||||
b: "wewe"
|
||||
});
|
||||
|
||||
const nodeDragNode = item => {
|
||||
props.lf.dnd.startDrag({
|
||||
type: item.type,
|
||||
properties: unref(properties)
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 左侧bpmn元素选择器 -->
|
||||
<div class="node-panel">
|
||||
<div
|
||||
class="node-item"
|
||||
v-for="item in nodeList"
|
||||
v-for="item in props.nodeList"
|
||||
:key="item.text"
|
||||
@mousedown="nodeDragNode(item)"
|
||||
>
|
||||
@@ -18,43 +45,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, unref } from "vue";
|
||||
export default defineComponent({
|
||||
name: "NodePanel",
|
||||
props: {
|
||||
lf: Object,
|
||||
nodeList: Array
|
||||
},
|
||||
setup(props) {
|
||||
let node = ref({
|
||||
type: "rect",
|
||||
property: {
|
||||
a: "efrwe",
|
||||
b: "wewe"
|
||||
}
|
||||
});
|
||||
let properties = ref({
|
||||
a: "efrwe",
|
||||
b: "wewe"
|
||||
});
|
||||
|
||||
const nodeDragNode = item => {
|
||||
props.lf.dnd.startDrag({
|
||||
type: item.type,
|
||||
properties: unref(properties)
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
node,
|
||||
properties,
|
||||
nodeDragNode
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.node-panel {
|
||||
position: absolute;
|
||||
|
||||
@@ -1,8 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
export interface Props {
|
||||
isActive: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
isActive: false
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "toggleClick"): void;
|
||||
}>();
|
||||
|
||||
const toggleClick = () => {
|
||||
emit("toggleClick");
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div style="padding: 0 15px" @click="toggleClick">
|
||||
<div :class="classes.container" @click="toggleClick">
|
||||
<svg
|
||||
:class="{ 'is-active': isActive }"
|
||||
class="hamburger"
|
||||
:class="props.isActive ? 'is-active' : ''"
|
||||
viewBox="0 0 1024 1024"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="64"
|
||||
@@ -15,26 +33,11 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
export default defineComponent({
|
||||
name: "HamBurger",
|
||||
props: {
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
emits: ["toggleClick"],
|
||||
setup(props, ctx) {
|
||||
const toggleClick = () => {
|
||||
ctx.emit("toggleClick");
|
||||
};
|
||||
|
||||
return { toggleClick };
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style module="classes" scoped>
|
||||
.container {
|
||||
padding: 0 15px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
.hamburger {
|
||||
@@ -44,7 +47,7 @@ export default defineComponent({
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.hamburger.is-active {
|
||||
.is-active {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,3 +1,97 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, PropType, getCurrentInstance, watch, nextTick, toRef } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import { initRouter } from "/@/router";
|
||||
import { storageSession } from "/@/utils/storage";
|
||||
|
||||
export interface ContextProps {
|
||||
userName: string;
|
||||
passWord: string;
|
||||
verify: number | null;
|
||||
svg: any;
|
||||
telephone?: number;
|
||||
dynamicText?: string;
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
ruleForm: {
|
||||
type: Object as PropType<ContextProps>
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "onBehavior", evt: Object): void;
|
||||
(e: "refreshVerify"): void;
|
||||
}>();
|
||||
|
||||
const instance = getCurrentInstance();
|
||||
|
||||
const model = toRef(props, "ruleForm");
|
||||
let tips = ref<string>("注册");
|
||||
let tipsFalse = ref<string>("登录");
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
watch(
|
||||
route,
|
||||
async ({ path }): Promise<void> => {
|
||||
await nextTick();
|
||||
path.includes("register")
|
||||
? (tips.value = "登录") && (tipsFalse.value = "注册")
|
||||
: (tips.value = "注册") && (tipsFalse.value = "登录");
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const rules: Object = ref({
|
||||
userName: [{ required: true, message: "请输入用户名", trigger: "blur" }],
|
||||
passWord: [
|
||||
{ required: true, message: "请输入密码", trigger: "blur" },
|
||||
{ min: 6, message: "密码长度必须不小于6位", trigger: "blur" }
|
||||
],
|
||||
verify: [
|
||||
{ required: true, message: "请输入验证码", trigger: "blur" },
|
||||
{ type: "number", message: "验证码必须是数字类型", trigger: "blur" }
|
||||
]
|
||||
});
|
||||
|
||||
// 点击登录或注册
|
||||
const onBehavior = (evt: Object): void => {
|
||||
instance.refs.ruleForm.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
emit("onBehavior", evt);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 刷新验证码
|
||||
const refreshVerify = (): void => {
|
||||
emit("refreshVerify");
|
||||
};
|
||||
|
||||
// 表单重置
|
||||
const resetForm = (): void => {
|
||||
instance.refs.ruleForm.resetFields();
|
||||
};
|
||||
|
||||
// 登录、注册页面切换
|
||||
const changPage = (): void => {
|
||||
tips.value === "注册" ? router.push("/register") : router.push("/login");
|
||||
};
|
||||
|
||||
const noSecret = (): void => {
|
||||
storageSession.setItem("info", {
|
||||
username: "admin",
|
||||
accessToken: "eyJhbGciOiJIUzUxMiJ9.test"
|
||||
});
|
||||
initRouter("admin").then(() => {});
|
||||
router.push("/");
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="info">
|
||||
<el-form :model="model" :rules="rules" ref="ruleForm" class="rule-form">
|
||||
@@ -47,123 +141,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
ref,
|
||||
defineComponent,
|
||||
PropType,
|
||||
getCurrentInstance,
|
||||
watch,
|
||||
nextTick,
|
||||
toRef
|
||||
} from "vue";
|
||||
import { storageSession } from "/@/utils/storage";
|
||||
|
||||
export interface ContextProps {
|
||||
userName: string;
|
||||
passWord: string;
|
||||
verify: number | null;
|
||||
svg: any;
|
||||
telephone?: number;
|
||||
dynamicText?: string;
|
||||
}
|
||||
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
|
||||
import { initRouter } from "/@/router";
|
||||
|
||||
export default defineComponent({
|
||||
name: "Info",
|
||||
props: {
|
||||
ruleForm: {
|
||||
type: Object as PropType<ContextProps>,
|
||||
require: true
|
||||
}
|
||||
},
|
||||
emits: ["onBehavior", "refreshVerify"],
|
||||
setup(props, ctx) {
|
||||
const instance = getCurrentInstance();
|
||||
|
||||
const model = toRef(props, "ruleForm");
|
||||
let tips = ref("注册");
|
||||
let tipsFalse = ref("登录");
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
watch(
|
||||
route,
|
||||
async ({ path }): Promise<void> => {
|
||||
await nextTick();
|
||||
path.includes("register")
|
||||
? (tips.value = "登录") && (tipsFalse.value = "注册")
|
||||
: (tips.value = "注册") && (tipsFalse.value = "登录");
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const rules: Object = ref({
|
||||
userName: [{ required: true, message: "请输入用户名", trigger: "blur" }],
|
||||
passWord: [
|
||||
{ required: true, message: "请输入密码", trigger: "blur" },
|
||||
{ min: 6, message: "密码长度必须不小于6位", trigger: "blur" }
|
||||
],
|
||||
verify: [
|
||||
{ required: true, message: "请输入验证码", trigger: "blur" },
|
||||
{ type: "number", message: "验证码必须是数字类型", trigger: "blur" }
|
||||
]
|
||||
});
|
||||
|
||||
// 点击登录或注册
|
||||
const onBehavior = (evt: Object): void => {
|
||||
instance.refs.ruleForm.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
ctx.emit("onBehavior", evt);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 刷新验证码
|
||||
const refreshVerify = (): void => {
|
||||
ctx.emit("refreshVerify");
|
||||
};
|
||||
|
||||
// 表单重置
|
||||
const resetForm = (): void => {
|
||||
instance.refs.ruleForm.resetFields();
|
||||
};
|
||||
|
||||
// 登录、注册页面切换
|
||||
const changPage = (): void => {
|
||||
tips.value === "注册" ? router.push("/register") : router.push("/login");
|
||||
};
|
||||
|
||||
const noSecret = (): void => {
|
||||
storageSession.setItem("info", {
|
||||
username: "admin",
|
||||
accessToken: "eyJhbGciOiJIUzUxMiJ9.test"
|
||||
});
|
||||
initRouter("admin").then(() => {});
|
||||
router.push("/");
|
||||
};
|
||||
|
||||
return {
|
||||
model,
|
||||
rules,
|
||||
tips,
|
||||
tipsFalse,
|
||||
resetForm,
|
||||
onBehavior,
|
||||
refreshVerify,
|
||||
changPage,
|
||||
noSecret
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.info {
|
||||
width: 30vw;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { App } from "vue";
|
||||
import amap from "./src/Amap.vue";
|
||||
import baiduMap from "./src/BaiduMap.vue";
|
||||
|
||||
export const Amap = Object.assign(amap, {
|
||||
install(app: App) {
|
||||
@@ -8,13 +7,6 @@ export const Amap = Object.assign(amap, {
|
||||
}
|
||||
});
|
||||
|
||||
export const BaiduMap = Object.assign(baiduMap, {
|
||||
install(app: App) {
|
||||
app.component(baiduMap.name, baiduMap);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
Amap,
|
||||
BaiduMap
|
||||
Amap
|
||||
};
|
||||
|
||||
@@ -1,45 +1,17 @@
|
||||
<template>
|
||||
<div
|
||||
id="mapview"
|
||||
ref="mapview"
|
||||
v-loading="loading"
|
||||
element-loading-text="地图加载中"
|
||||
element-loading-spinner="el-icon-loading"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import AMapLoader from "@amap/amap-jsapi-loader";
|
||||
import {
|
||||
reactive,
|
||||
toRefs,
|
||||
defineComponent,
|
||||
onBeforeMount,
|
||||
getCurrentInstance
|
||||
} from "vue";
|
||||
|
||||
import { reactive, getCurrentInstance, onBeforeMount, onUnmounted } from "vue";
|
||||
import { mapJson } from "/@/api/mock";
|
||||
import { deviceDetection } from "/@/utils/deviceDetection";
|
||||
|
||||
import greenCar from "/@/assets/green.png";
|
||||
|
||||
let MarkerCluster;
|
||||
|
||||
export interface MapConfigureInter {
|
||||
// eslint-disable-next-line no-undef
|
||||
on: Fn;
|
||||
// eslint-disable-next-line no-undef
|
||||
destroy?: Fn;
|
||||
// eslint-disable-next-line no-undef
|
||||
clearEvents?: Fn;
|
||||
// eslint-disable-next-line no-undef
|
||||
addControl?: Fn;
|
||||
// eslint-disable-next-line no-undef
|
||||
setCenter?: Fn;
|
||||
// eslint-disable-next-line no-undef
|
||||
setZoom?: Fn;
|
||||
// eslint-disable-next-line no-undef
|
||||
plugin?: Fn;
|
||||
}
|
||||
|
||||
@@ -47,116 +19,119 @@ export interface mapInter {
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: "Amap",
|
||||
setup() {
|
||||
const instance = getCurrentInstance();
|
||||
let map: MapConfigureInter;
|
||||
let MarkerCluster;
|
||||
let map: MapConfigureInter;
|
||||
|
||||
const mapSet: mapInter = reactive({
|
||||
loading: deviceDetection() ? false : true
|
||||
const instance = getCurrentInstance();
|
||||
|
||||
const mapSet: mapInter = reactive({
|
||||
loading: deviceDetection() ? false : true
|
||||
});
|
||||
|
||||
// 地图创建完成(动画关闭)
|
||||
const complete = (): void => {
|
||||
if (map) {
|
||||
map.on("complete", () => {
|
||||
mapSet.loading = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 地图创建完成(动画关闭)
|
||||
const complete = (): void => {
|
||||
if (map) {
|
||||
map.on("complete", () => {
|
||||
mapSet.loading = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
onBeforeMount(() => {
|
||||
if (!instance) return;
|
||||
let { MapConfigure } = instance.appContext.config.globalProperties.$config;
|
||||
let { options } = MapConfigure;
|
||||
|
||||
// 销毁地图实例
|
||||
const destroyMap = (): void => {
|
||||
if (map) {
|
||||
map.destroy() && map.clearEvents("click");
|
||||
}
|
||||
};
|
||||
AMapLoader.load({
|
||||
key: MapConfigure.amapKey,
|
||||
version: "2.0",
|
||||
plugins: ["AMap.MarkerCluster"]
|
||||
})
|
||||
.then(AMap => {
|
||||
// 创建地图实例
|
||||
map = new AMap.Map(instance.refs.mapview, options);
|
||||
|
||||
onBeforeMount(() => {
|
||||
if (!instance) return;
|
||||
let { MapConfigure } =
|
||||
instance.appContext.config.globalProperties.$config;
|
||||
let { options } = MapConfigure;
|
||||
//地图中添加地图操作ToolBar插件
|
||||
map.plugin(["AMap.ToolBar", "AMap.MapType"], () => {
|
||||
map.addControl(new AMap.ToolBar());
|
||||
//地图类型切换
|
||||
map.addControl(
|
||||
new AMap.MapType({
|
||||
defaultType: 0
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
AMapLoader.load({
|
||||
key: MapConfigure.amapKey,
|
||||
version: "2.0",
|
||||
plugins: ["AMap.MarkerCluster"]
|
||||
})
|
||||
.then(AMap => {
|
||||
// 创建地图实例
|
||||
map = new AMap.Map(instance.refs.mapview, options);
|
||||
|
||||
//地图中添加地图操作ToolBar插件
|
||||
map.plugin(["AMap.ToolBar", "AMap.MapType"], () => {
|
||||
map.addControl(new AMap.ToolBar());
|
||||
//地图类型切换
|
||||
map.addControl(
|
||||
new AMap.MapType({
|
||||
defaultType: 0
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
MarkerCluster = new AMap.MarkerCluster(map, [], {
|
||||
gridSize: 80, // 聚合网格像素大小
|
||||
maxZoom: 14,
|
||||
renderMarker(ctx) {
|
||||
let { marker, data } = ctx;
|
||||
if (Array.isArray(data) && data[0]) {
|
||||
var { driver, plateNumber, orientation } = data[0];
|
||||
var content = `<img style="transform: scale(1) rotate(${
|
||||
360 - Number(orientation)
|
||||
}deg);" src='${greenCar}' />`;
|
||||
marker.setContent(content);
|
||||
marker.setLabel({
|
||||
direction: "bottom",
|
||||
offset: new AMap.Pixel(-4, 0), //设置文本标注偏移量
|
||||
content: `<div> ${plateNumber}(${driver})</div>` //设置文本标注内容
|
||||
});
|
||||
marker.setOffset(new AMap.Pixel(-18, -10));
|
||||
marker.on("click", ({ lnglat }) => {
|
||||
map.setZoom(13); //设置地图层级
|
||||
map.setCenter(lnglat);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 获取模拟车辆信息
|
||||
mapJson()
|
||||
.then(res => {
|
||||
let points: object = res.info.map((v: any) => {
|
||||
return {
|
||||
lnglat: [v.lng, v.lat],
|
||||
...v
|
||||
};
|
||||
});
|
||||
if (MarkerCluster) MarkerCluster.setData(points);
|
||||
})
|
||||
.catch(err => {
|
||||
console.log("err:", err);
|
||||
MarkerCluster = new AMap.MarkerCluster(map, [], {
|
||||
// 聚合网格像素大小
|
||||
gridSize: 80,
|
||||
maxZoom: 14,
|
||||
renderMarker(ctx) {
|
||||
let { marker, data } = ctx;
|
||||
if (Array.isArray(data) && data[0]) {
|
||||
var { driver, plateNumber, orientation } = data[0];
|
||||
var content = `<img style="transform: scale(1) rotate(${
|
||||
360 - Number(orientation)
|
||||
}deg);" src='${greenCar}' />`;
|
||||
marker.setContent(content);
|
||||
marker.setLabel({
|
||||
direction: "bottom",
|
||||
//设置文本标注偏移量
|
||||
offset: new AMap.Pixel(-4, 0),
|
||||
//设置文本标注内容
|
||||
content: `<div> ${plateNumber}(${driver})</div>`
|
||||
});
|
||||
marker.setOffset(new AMap.Pixel(-18, -10));
|
||||
marker.on("click", ({ lnglat }) => {
|
||||
map.setZoom(13); //设置地图层级
|
||||
map.setCenter(lnglat);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
complete();
|
||||
// 获取模拟车辆信息
|
||||
mapJson()
|
||||
.then(res => {
|
||||
let points: object = res.info.map((v: any) => {
|
||||
return {
|
||||
lnglat: [v.lng, v.lat],
|
||||
...v
|
||||
};
|
||||
});
|
||||
if (MarkerCluster) MarkerCluster.setData(points);
|
||||
})
|
||||
.catch(() => {
|
||||
mapSet.loading = false;
|
||||
throw "地图加载失败,请重新加载";
|
||||
.catch(err => {
|
||||
console.log("err:", err);
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
...toRefs(mapSet),
|
||||
complete,
|
||||
destroyMap,
|
||||
greenCar
|
||||
};
|
||||
complete();
|
||||
})
|
||||
.catch(() => {
|
||||
mapSet.loading = false;
|
||||
throw "地图加载失败,请重新加载";
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (map) {
|
||||
// 销毁地图实例
|
||||
map.destroy() && map.clearEvents("click");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
id="mapview"
|
||||
ref="mapview"
|
||||
v-loading="mapSet.loading"
|
||||
element-loading-text="地图加载中"
|
||||
element-loading-spinner="el-icon-loading"
|
||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#mapview {
|
||||
height: 100%;
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "BaiduMap",
|
||||
setup() {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
* @desc AnimationFrame简单兼容hack
|
||||
*/
|
||||
export const animationFrame = () => {
|
||||
window.cancelAnimationFrame = (function () {
|
||||
window.cancelAnimationFrame = (() => {
|
||||
return (
|
||||
window.cancelAnimationFrame ||
|
||||
window.webkitCancelAnimationFrame ||
|
||||
|
||||
Reference in New Issue
Block a user