mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-04 07:27:41 +08:00
feat: print and perf style
This commit is contained in:
parent
e3fda52801
commit
727c0fe3c0
14
index.html
14
index.html
@ -14,20 +14,16 @@
|
||||
<body>
|
||||
<div id="app">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
body,
|
||||
#app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
font-family: "Reggae One", cursive;
|
||||
}
|
||||
|
||||
.loader,
|
||||
@ -53,6 +49,8 @@
|
||||
transform: translateZ(0);
|
||||
-webkit-animation-delay: -0.16s;
|
||||
animation-delay: -0.16s;
|
||||
top: 0;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
.loader:before,
|
||||
@ -96,7 +94,7 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="loader">Loading...</div>
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
|
@ -76,7 +76,7 @@ const frameRouter = {
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/frame/pure",
|
||||
path: "/iframe/pure",
|
||||
name: "reFramePure",
|
||||
meta: {
|
||||
i18n: true,
|
||||
|
@ -116,7 +116,7 @@
|
||||
"stylelint-order": "^5.0.0",
|
||||
"typescript": "^4.5.5",
|
||||
"unplugin-element-plus": "^0.2.0",
|
||||
"vite": "^2.8.5",
|
||||
"vite": "^2.8.6",
|
||||
"vite-plugin-live-reload": "^2.1.0",
|
||||
"vite-plugin-mock": "^2.9.6",
|
||||
"vite-plugin-remove-console": "^0.0.6",
|
||||
|
5031
pnpm-lock.yaml
generated
5031
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -126,7 +126,7 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-size: 25px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.control-container p {
|
||||
|
@ -24,6 +24,8 @@ import Location from "@iconify-icons/ep/location";
|
||||
import Tickets from "@iconify-icons/ep/tickets";
|
||||
import OfficeBuilding from "@iconify-icons/ep/office-building";
|
||||
import Notebook from "@iconify-icons/ep/notebook";
|
||||
import Rank from "@iconify-icons/ep/rank";
|
||||
import videoPlay from "@iconify-icons/ep/video-play";
|
||||
import Monitor from "@iconify-icons/ep/monitor";
|
||||
addIcon("check", Check);
|
||||
addIcon("menu", Menu);
|
||||
@ -47,6 +49,8 @@ addIcon("location", Location);
|
||||
addIcon("tickets", Tickets);
|
||||
addIcon("office-building", OfficeBuilding);
|
||||
addIcon("notebook", Notebook);
|
||||
addIcon("video-play", videoPlay);
|
||||
addIcon("rank", Rank);
|
||||
addIcon("monitor", Monitor);
|
||||
|
||||
// remixicon
|
||||
|
@ -55,4 +55,8 @@ onMounted(() => {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
@ -8,7 +8,6 @@ import { useAppStoreHook } from "/@/store/modules/app";
|
||||
import { remainingPaths } from "/@/router/modules/index";
|
||||
import { Title } from "../../../public/serverConfig.json";
|
||||
import { useEpThemeStoreHook } from "/@/store/modules/epTheme";
|
||||
import { remainingPaths } from "/@/router/modules/index";
|
||||
|
||||
export function useNav() {
|
||||
const pureApp = useAppStoreHook();
|
||||
|
@ -44,6 +44,12 @@ import {
|
||||
ElCollapse,
|
||||
ElCollapseItem,
|
||||
ElTreeV2,
|
||||
ElTable,
|
||||
ElTableColumn,
|
||||
ElLink,
|
||||
ElColorPicker,
|
||||
ElSelect,
|
||||
ElOption,
|
||||
// 指令
|
||||
ElLoading,
|
||||
ElInfiniteScroll
|
||||
@ -96,7 +102,13 @@ const components = [
|
||||
ElEmpty,
|
||||
ElCollapse,
|
||||
ElCollapseItem,
|
||||
ElTreeV2
|
||||
ElTreeV2,
|
||||
ElTable,
|
||||
ElTableColumn,
|
||||
ElLink,
|
||||
ElColorPicker,
|
||||
ElSelect,
|
||||
ElOption
|
||||
];
|
||||
|
||||
export function useElementPlus(app: App) {
|
||||
|
@ -37,6 +37,7 @@ export default {
|
||||
hsAble: "Able",
|
||||
hsMenuTree: "Menu Tree",
|
||||
hsWatermark: "Water Mark",
|
||||
hsPrint: "Print",
|
||||
hsExternalPage: "External Page",
|
||||
hsPureDocument: "Pure Document",
|
||||
hsEpDocument: "Element Plus Document"
|
||||
|
@ -37,6 +37,7 @@ export default {
|
||||
hsAble: "功能",
|
||||
hsMenuTree: "菜单树结构",
|
||||
hsWatermark: "水印",
|
||||
hsPrint: "打印",
|
||||
hsExternalPage: "外部页面",
|
||||
hsPureDocument: "平台文档",
|
||||
hsEpDocument: "Element Plus文档"
|
||||
|
@ -30,6 +30,15 @@ const ableRouter = {
|
||||
title: $t("menus.hsWatermark"),
|
||||
i18n: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/able/print",
|
||||
name: "rePrint",
|
||||
component: () => import("/@/views/able/print.vue"),
|
||||
meta: {
|
||||
title: $t("menus.hsPrint"),
|
||||
i18n: true
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@ -12,8 +12,8 @@ body {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizelegibility;
|
||||
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
|
||||
Microsoft YaHei, Arial, sans-serif;
|
||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
|
||||
"Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
||||
}
|
||||
|
||||
html {
|
||||
|
226
src/utils/print.ts
Normal file
226
src/utils/print.ts
Normal file
@ -0,0 +1,226 @@
|
||||
interface PrintFunction {
|
||||
extendOptions: Function;
|
||||
getStyle: Function;
|
||||
setDomHeight: Function;
|
||||
toPrint: Function;
|
||||
}
|
||||
|
||||
const Print = function (dom, options?: object): PrintFunction {
|
||||
options = options || {};
|
||||
// @ts-expect-error
|
||||
if (!(this instanceof Print)) return new Print(dom, options);
|
||||
this.conf = {
|
||||
styleStr: "",
|
||||
// Elements that need to dynamically get and set the height
|
||||
setDomHeightArr: [],
|
||||
// Echart dom List
|
||||
echartDomArr: [],
|
||||
// Callback before printing
|
||||
printBeforeFn: null,
|
||||
// Callback after printing
|
||||
printDoneCallBack: null
|
||||
};
|
||||
for (const key in this.conf) {
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
if (key && options.hasOwnProperty(key)) {
|
||||
this.conf[key] = options[key];
|
||||
}
|
||||
}
|
||||
if (typeof dom === "string") {
|
||||
this.dom = document.querySelector(dom);
|
||||
} else {
|
||||
this.dom = this.isDOM(dom) ? dom : dom.$el;
|
||||
}
|
||||
if (this.conf.setDomHeightArr && this.conf.setDomHeightArr.length) {
|
||||
this.setDomHeight(this.conf.setDomHeightArr);
|
||||
}
|
||||
this.init();
|
||||
};
|
||||
|
||||
Print.prototype = {
|
||||
/**
|
||||
* init
|
||||
*/
|
||||
init: function (): void {
|
||||
const content = this.getStyle() + this.getHtml();
|
||||
this.writeIframe(content);
|
||||
},
|
||||
/**
|
||||
* Configuration property extension
|
||||
* @param {Object} obj
|
||||
* @param {Object} obj2
|
||||
*/
|
||||
extendOptions: function <T>(obj, obj2: T): T {
|
||||
for (const k in obj2) {
|
||||
obj[k] = obj2[k];
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
/**
|
||||
Copy all styles of the original page
|
||||
*/
|
||||
getStyle: function (): string {
|
||||
let str = "";
|
||||
const styles: NodeListOf<Element> = document.querySelectorAll("style,link");
|
||||
for (let i = 0; i < styles.length; i++) {
|
||||
str += styles[i].outerHTML;
|
||||
}
|
||||
str += `<style>.no-print{display:none;}${this.conf.styleStr}</style>`;
|
||||
return str;
|
||||
},
|
||||
// form assignment
|
||||
getHtml: function (): Element {
|
||||
const inputs = document.querySelectorAll("input");
|
||||
const selects = document.querySelectorAll("select");
|
||||
const textareas = document.querySelectorAll("textarea");
|
||||
for (let k = 0; k < inputs.length; k++) {
|
||||
if (inputs[k].type == "checkbox" || inputs[k].type == "radio") {
|
||||
if (inputs[k].checked == true) {
|
||||
inputs[k].setAttribute("checked", "checked");
|
||||
} else {
|
||||
inputs[k].removeAttribute("checked");
|
||||
}
|
||||
} else if (inputs[k].type == "text") {
|
||||
inputs[k].setAttribute("value", inputs[k].value);
|
||||
} else {
|
||||
inputs[k].setAttribute("value", inputs[k].value);
|
||||
}
|
||||
}
|
||||
|
||||
for (let k2 = 0; k2 < textareas.length; k2++) {
|
||||
if (textareas[k2].type == "textarea") {
|
||||
textareas[k2].innerHTML = textareas[k2].value;
|
||||
}
|
||||
}
|
||||
|
||||
for (let k3 = 0; k3 < selects.length; k3++) {
|
||||
if (selects[k3].type == "select-one") {
|
||||
const child = selects[k3].children;
|
||||
for (const i in child) {
|
||||
if (child[i].tagName == "OPTION") {
|
||||
// @ts-ignore
|
||||
if (child[i].selected == true) {
|
||||
child[i].setAttribute("selected", "selected");
|
||||
} else {
|
||||
child[i].removeAttribute("selected");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.dom.outerHTML;
|
||||
},
|
||||
/**
|
||||
create iframe
|
||||
*/
|
||||
writeIframe: function (content) {
|
||||
let w: Document | Window;
|
||||
let doc: Document;
|
||||
const iframe: HTMLIFrameElement = document.createElement("iframe");
|
||||
const f: HTMLIFrameElement = document.body.appendChild(iframe);
|
||||
iframe.id = "myIframe";
|
||||
iframe.setAttribute(
|
||||
"style",
|
||||
"position:absolute;width:0;height:0;top:-10px;left:-10px;"
|
||||
);
|
||||
// eslint-disable-next-line prefer-const
|
||||
w = f.contentWindow || f.contentDocument;
|
||||
// eslint-disable-next-line prefer-const
|
||||
doc = f.contentDocument || f.contentWindow.document;
|
||||
doc.open();
|
||||
doc.write(content);
|
||||
doc.close();
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const _this = this;
|
||||
iframe.onload = function (): void {
|
||||
// Before popping, callback
|
||||
if (_this.conf.printBeforeFn) {
|
||||
_this.conf.printBeforeFn({ doc });
|
||||
}
|
||||
|
||||
_this.drawEchartImg(doc).then(() => {
|
||||
_this.toPrint(w);
|
||||
setTimeout(function () {
|
||||
document.body.removeChild(iframe);
|
||||
// After popup, callback
|
||||
if (_this.conf.printDoneCallBack) {
|
||||
_this.conf.printDoneCallBack();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
};
|
||||
},
|
||||
/**
|
||||
* echarts printing
|
||||
* @param {Object} doc iframe window
|
||||
*/
|
||||
drawEchartImg(doc): Promise<void> {
|
||||
return new Promise<void>(resolve => {
|
||||
if (this.conf.echartDomArr && this.conf.echartDomArr.length > 0) {
|
||||
this.conf.echartDomArr.forEach(e => {
|
||||
const dom = doc.querySelector("#" + e.$el.id);
|
||||
const img = new Image();
|
||||
const w = dom.offsetWidth + "px";
|
||||
const H = dom.offsetHeight + "px";
|
||||
|
||||
img.style.width = w;
|
||||
img.style.height = H;
|
||||
img.src = e.imgSrc;
|
||||
dom.innerHTML = "";
|
||||
dom.appendChild(img);
|
||||
});
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
/**
|
||||
Print
|
||||
*/
|
||||
toPrint: function (frameWindow): void {
|
||||
try {
|
||||
setTimeout(function () {
|
||||
frameWindow.focus();
|
||||
try {
|
||||
if (!frameWindow.document.execCommand("print", false, null)) {
|
||||
frameWindow.print();
|
||||
}
|
||||
} catch (e) {
|
||||
frameWindow.print();
|
||||
}
|
||||
frameWindow.close();
|
||||
}, 10);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
},
|
||||
isDOM:
|
||||
typeof HTMLElement === "object"
|
||||
? function (obj) {
|
||||
return obj instanceof HTMLElement;
|
||||
}
|
||||
: function (obj) {
|
||||
return (
|
||||
obj &&
|
||||
typeof obj === "object" &&
|
||||
obj.nodeType === 1 &&
|
||||
typeof obj.nodeName === "string"
|
||||
);
|
||||
},
|
||||
/**
|
||||
* Set the height of the specified dom element by getting the existing height of the dom element and setting
|
||||
* @param {Array} arr
|
||||
*/
|
||||
setDomHeight(arr) {
|
||||
if (arr && arr.length) {
|
||||
arr.forEach(name => {
|
||||
const domArr = document.querySelectorAll(name);
|
||||
domArr.forEach(dom => {
|
||||
dom.style.height = dom.offsetHeight + "px";
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default Print;
|
@ -6,31 +6,78 @@ export default {
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue";
|
||||
import type { ElTreeV2 } from "element-plus";
|
||||
import { transformI18n } from "/@/plugins/i18n";
|
||||
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
|
||||
import { extractPathList, deleteChildren } from "/@/utils/tree";
|
||||
import { usePermissionStoreHook } from "/@/store/modules/permission";
|
||||
import type { TreeNode } from "element-plus/es/components/tree-v2/src/types";
|
||||
|
||||
interface treeNode extends TreeNode {
|
||||
meta: {
|
||||
title: string;
|
||||
i18n: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
const query = ref("");
|
||||
let dataProps = ref({
|
||||
value: "uniqueId",
|
||||
children: "children"
|
||||
});
|
||||
const treeRef = ref<InstanceType<typeof ElTreeV2>>();
|
||||
|
||||
let menusData = computed(() => {
|
||||
return deleteChildren(usePermissionStoreHook().menusTree);
|
||||
});
|
||||
|
||||
let expandedKeys = extractPathList(menusData.value);
|
||||
|
||||
const onQueryChanged = (query: string) => {
|
||||
// @ts-expect-error
|
||||
treeRef.value!.filter(query);
|
||||
};
|
||||
|
||||
const filterMethod = (query: string, node: treeNode) => {
|
||||
return transformI18n(node.meta.title, node.meta.i18n)!.indexOf(query) !== -1;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-tree-v2
|
||||
:data="menusData"
|
||||
:props="dataProps"
|
||||
show-checkbox
|
||||
:height="500"
|
||||
:default-expanded-keys="expandedKeys"
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<span>{{ $t(data.meta.title) }}</span>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium"
|
||||
>菜单树结构(采用element-plus的
|
||||
<el-link
|
||||
href="https://element-plus.gitee.io/zh-CN/component/tree-v2.html"
|
||||
target="_blank"
|
||||
:icon="useRenderIcon('node-tree')"
|
||||
style="font-size: 16px; margin: 0 5px 4px 0"
|
||||
>Tree V2</el-link
|
||||
>组件并支持国际化)</span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</el-tree-v2>
|
||||
<el-input
|
||||
class="mb-4"
|
||||
v-model="query"
|
||||
placeholder="请输入关键字查找"
|
||||
clearable
|
||||
@input="onQueryChanged"
|
||||
></el-input>
|
||||
<el-tree-v2
|
||||
ref="treeRef"
|
||||
:data="menusData"
|
||||
:props="dataProps"
|
||||
show-checkbox
|
||||
:height="500"
|
||||
:filter-method="filterMethod"
|
||||
:default-expanded-keys="expandedKeys"
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<span>{{ $t(data.meta.title) }}</span>
|
||||
</template>
|
||||
</el-tree-v2>
|
||||
</el-card>
|
||||
</template>
|
||||
|
329
src/views/able/print.vue
Normal file
329
src/views/able/print.vue
Normal file
@ -0,0 +1,329 @@
|
||||
<script setup lang="ts">
|
||||
import Print from "/@/utils/print";
|
||||
import { reactive, ref } from "vue";
|
||||
import { VxeTablePropTypes } from "vxe-table";
|
||||
import { ReLine } from "/@/components/ReCharts/index";
|
||||
|
||||
interface User {
|
||||
date: string;
|
||||
name: string;
|
||||
address: string;
|
||||
}
|
||||
|
||||
const demo1 = reactive({
|
||||
tableData: [
|
||||
{
|
||||
id: 10001,
|
||||
name: "Test1",
|
||||
role: "Develop",
|
||||
sex: "Man",
|
||||
age: 28,
|
||||
address: "test abc"
|
||||
},
|
||||
{
|
||||
id: 10002,
|
||||
name: "Test2",
|
||||
role: "Test",
|
||||
sex: "Women",
|
||||
age: 22,
|
||||
address: "Guangzhou"
|
||||
},
|
||||
{
|
||||
id: 10003,
|
||||
name: "Test3",
|
||||
role: "PM",
|
||||
sex: "Man",
|
||||
age: 32,
|
||||
address: "Shanghai"
|
||||
},
|
||||
{
|
||||
id: 10004,
|
||||
name: "Test4",
|
||||
role: "Designer",
|
||||
sex: "Women",
|
||||
age: 24,
|
||||
address: "Shanghai"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const value = ref("1");
|
||||
|
||||
const options = [
|
||||
{
|
||||
value: "1",
|
||||
el: ".el-table",
|
||||
label: "Element-Plus Table"
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
el: ".vxe-table",
|
||||
label: "Vxe Table"
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
el: ".echart",
|
||||
label: "Echart"
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
el: ".img",
|
||||
label: "Image"
|
||||
}
|
||||
];
|
||||
|
||||
function onPrint() {
|
||||
let el = options.filter(v => v.value === value.value)[0]?.el;
|
||||
Print(el).toPrint;
|
||||
}
|
||||
|
||||
const headerCellStyle: VxeTablePropTypes.HeaderCellStyle = ({ column }) => {
|
||||
if (column.property === "name") {
|
||||
return {
|
||||
backgroundColor: "#f60",
|
||||
color: "#ffffff"
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const rowStyle: VxeTablePropTypes.RowStyle = ({ rowIndex }) => {
|
||||
if ([2, 3, 5].includes(rowIndex)) {
|
||||
return {
|
||||
backgroundColor: "red",
|
||||
color: "#ffffff"
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const cellStyle: VxeTablePropTypes.CellStyle = ({ row, column }) => {
|
||||
if (column.property === "sex") {
|
||||
if (row.sex >= "1") {
|
||||
return {
|
||||
backgroundColor: "#187"
|
||||
};
|
||||
} else if (row.age === 26) {
|
||||
return {
|
||||
backgroundColor: "#2db7f5"
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const tableRowClassName = ({ rowIndex }: { row: User; rowIndex: number }) => {
|
||||
if (rowIndex === 1) {
|
||||
return "warning-row";
|
||||
} else if (rowIndex === 3) {
|
||||
return "success-row";
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
const tableData: User[] = [
|
||||
{
|
||||
date: "2016-05-03",
|
||||
name: "Tom",
|
||||
address: "No. 189, Grove St, Los Angeles"
|
||||
},
|
||||
{
|
||||
date: "2016-05-02",
|
||||
name: "Tom",
|
||||
address: "No. 189, Grove St, Los Angeles"
|
||||
},
|
||||
{
|
||||
date: "2016-05-04",
|
||||
name: "Tom",
|
||||
address: "No. 189, Grove St, Los Angeles"
|
||||
},
|
||||
{
|
||||
date: "2016-05-01",
|
||||
name: "Tom",
|
||||
address: "No. 189, Grove St, Los Angeles"
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium">打印功能(报表、图表、图片)</span>
|
||||
<div>
|
||||
<el-select
|
||||
v-model="value"
|
||||
class="m-2"
|
||||
placeholder="Select"
|
||||
size="small"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-button size="small" type="primary" @click="onPrint"
|
||||
>打印</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<el-row :gutter="24">
|
||||
<el-col
|
||||
:xs="22"
|
||||
:sm="22"
|
||||
:md="11"
|
||||
:lg="11"
|
||||
:xl="11"
|
||||
style="margin: 10px; border: 0.01rem solid var(--el-color-primary)"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 200
|
||||
}
|
||||
}"
|
||||
>
|
||||
<p class="font-medium pt-1">Element-Plus Table</p>
|
||||
<el-table
|
||||
class="el-table"
|
||||
:data="tableData"
|
||||
border
|
||||
style="margin: 40px auto; width: 100%"
|
||||
:row-class-name="tableRowClassName"
|
||||
>
|
||||
<el-table-column prop="date" label="Date" width="180" />
|
||||
<el-table-column prop="name" label="Name" width="180" />
|
||||
<el-table-column prop="address" label="Address" />
|
||||
</el-table>
|
||||
</el-col>
|
||||
|
||||
<el-col
|
||||
:xs="22"
|
||||
:sm="22"
|
||||
:md="11"
|
||||
:lg="11"
|
||||
:xl="11"
|
||||
style="margin: 10px; border: 0.01rem solid var(--el-color-primary)"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 200
|
||||
}
|
||||
}"
|
||||
>
|
||||
<p class="font-medium pt-1">Vxe Table</p>
|
||||
<vxe-table
|
||||
class="vxe-table"
|
||||
border
|
||||
style="margin: 40px auto"
|
||||
:header-cell-style="headerCellStyle"
|
||||
:row-style="rowStyle"
|
||||
:cell-style="cellStyle"
|
||||
:data="demo1.tableData"
|
||||
>
|
||||
<vxe-column type="seq" width="60"></vxe-column>
|
||||
<vxe-column field="name" title="Name"></vxe-column>
|
||||
<vxe-column field="sex" title="Sex"></vxe-column>
|
||||
<vxe-column field="age" title="Age"></vxe-column>
|
||||
<vxe-column field="attr1" title="Attr1"></vxe-column>
|
||||
<vxe-column
|
||||
field="address"
|
||||
title="Address"
|
||||
show-overflow
|
||||
></vxe-column>
|
||||
</vxe-table>
|
||||
</el-col>
|
||||
|
||||
<el-col
|
||||
:xs="22"
|
||||
:sm="22"
|
||||
:md="11"
|
||||
:lg="11"
|
||||
:xl="11"
|
||||
style="
|
||||
width: 200px;
|
||||
height: 300px;
|
||||
margin: 10px;
|
||||
border: 0.01rem solid var(--el-color-primary);
|
||||
"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 200
|
||||
}
|
||||
}"
|
||||
>
|
||||
<p class="font-medium pt-1">Echart</p>
|
||||
<ReLine class="echart" style="margin: 0 auto" />
|
||||
</el-col>
|
||||
|
||||
<el-col
|
||||
:xs="22"
|
||||
:sm="22"
|
||||
:md="11"
|
||||
:lg="11"
|
||||
:xl="11"
|
||||
style="
|
||||
width: 200px;
|
||||
height: 300px;
|
||||
margin: 10px;
|
||||
border: 0.01rem solid var(--el-color-primary);
|
||||
"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 200
|
||||
}
|
||||
}"
|
||||
>
|
||||
<p class="font-medium pt-1">Image</p>
|
||||
<img
|
||||
src="../../assets/avatars.jpg"
|
||||
alt="avatars"
|
||||
class="img"
|
||||
style="width: 200px; height: 200px; margin: 50px auto"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-table__row.warning-row) {
|
||||
--el-table-tr-bg-color: var(--el-color-warning-light-9);
|
||||
}
|
||||
|
||||
:deep(.el-table__row.success-row) {
|
||||
--el-table-tr-bg-color: var(--el-color-success-light-9);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
@ -1,13 +1,34 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { useWatermark } from "/@/utils/watermark";
|
||||
|
||||
let color = ref("#409EFF");
|
||||
let value = ref("vue-pure-admin");
|
||||
const { setWatermark, clear } = useWatermark();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-button @click="setWatermark('vue-pure-admin')">创建</el-button>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium">页面水印功能</span>
|
||||
</div>
|
||||
</template>
|
||||
<span>请输入要创建水印的值:</span
|
||||
><el-input
|
||||
class="mb-4 mr-4"
|
||||
style="width: 200px"
|
||||
v-model="value"
|
||||
clearable
|
||||
></el-input>
|
||||
<span>请选择要创建水印的颜色:</span
|
||||
><el-color-picker v-model="color" show-alpha />
|
||||
<br />
|
||||
<el-button @click="setWatermark(value, { fillStyle: color })"
|
||||
>创建</el-button
|
||||
>
|
||||
<el-button @click="clear">清除</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
@ -7,13 +7,19 @@ const url = ref(`${VITE_PUBLIC_PATH}html/button.html`);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<iframe :src="url" frameborder="0" class="iframe"></iframe>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium">通过iframe引入按钮页面</span>
|
||||
</div>
|
||||
</template>
|
||||
<iframe :src="url" frameborder="0" class="iframe"></iframe>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.iframe {
|
||||
width: 98%;
|
||||
height: 90vh;
|
||||
border-radius: 6px;
|
||||
width: 100%;
|
||||
height: 60vh;
|
||||
}
|
||||
</style>
|
||||
|
@ -5,7 +5,12 @@ import menuDynamic from "./menuDynamic.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium">右键菜单组件</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-row :gutter="24">
|
||||
<el-col :xs="24" :sm="10" :md="10" :lg="8" :xl="10">
|
||||
<!-- 基本使用 -->
|
||||
@ -20,5 +25,5 @@ import menuDynamic from "./menuDynamic.vue";
|
||||
<menuDynamic />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
@ -3,35 +3,32 @@ import { ReNormalCountTo, ReboundCountTo } from "/@/components/ReCountTo";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="24">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-card shadow="always">
|
||||
<ReNormalCountTo
|
||||
prefix="$"
|
||||
:duration="1000"
|
||||
:color="'#409EFF'"
|
||||
:fontSize="'2.3em'"
|
||||
:startVal="1"
|
||||
:endVal="1000"
|
||||
/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-card shadow="always">
|
||||
<ul class="flex">
|
||||
<ReboundCountTo
|
||||
v-for="(num, inx) of [1, 6, 6, 6]"
|
||||
:key="inx"
|
||||
:i="num"
|
||||
:blur="inx"
|
||||
:delay="inx + 1"
|
||||
/>
|
||||
</ul>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium">数字动画组件</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="flex items-center">
|
||||
<ReNormalCountTo
|
||||
prefix="$"
|
||||
:duration="1000"
|
||||
:color="'#409EFF'"
|
||||
:fontSize="'2em'"
|
||||
:startVal="1"
|
||||
:endVal="1000"
|
||||
/>
|
||||
<ul class="flex ml-8">
|
||||
<ReboundCountTo
|
||||
v-for="(num, inx) of [1, 6, 6, 6]"
|
||||
:key="inx"
|
||||
:i="num"
|
||||
:blur="inx"
|
||||
:delay="inx + 1"
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -3,9 +3,9 @@ import { ref, nextTick, getCurrentInstance } from "vue";
|
||||
import Cropper from "/@/components/ReCropper";
|
||||
import img from "./picture.jpeg";
|
||||
|
||||
const instance = getCurrentInstance();
|
||||
let info = ref<object>(null);
|
||||
let cropperImg = ref<string>("");
|
||||
const instance = getCurrentInstance();
|
||||
|
||||
const onCropper = (): void => {
|
||||
nextTick(() => {
|
||||
@ -25,14 +25,19 @@ const onCropper = (): void => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium">图片裁剪组件</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="cropper-container">
|
||||
<Cropper ref="refCropper" :width="'40vw'" :src="img" />
|
||||
<img :src="cropperImg" class="croppered" v-if="cropperImg" />
|
||||
</div>
|
||||
<el-button type="primary" @click="onCropper">裁剪</el-button>
|
||||
<p v-if="cropperImg">裁剪后图片信息:{{ info }}</p>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import draggable from "vuedraggable/src/vuedraggable";
|
||||
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
|
||||
|
||||
let gridLists = ref<Array<Object>>([
|
||||
{ grid: "cn", num: 1 },
|
||||
@ -47,77 +48,92 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="drag-container">
|
||||
<!-- grid列表拖拽 -->
|
||||
<el-row :gutter="25">
|
||||
<el-col :xs="25" :sm="8" :md="8" :lg="8">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>grid列表拖拽</span>
|
||||
</div>
|
||||
</template>
|
||||
<draggable
|
||||
v-model="gridLists"
|
||||
class="grid-container"
|
||||
item-key="grid"
|
||||
animation="300"
|
||||
chosenClass="chosen"
|
||||
forceFallback="true"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<div :class="'item' + ' ' + 'item-' + element.num">
|
||||
{{ element.num }}
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span
|
||||
>拖拽组件,采用开源的<el-link
|
||||
href="https://sortablejs.github.io/vue.draggable.next/#/simple"
|
||||
target="_blank"
|
||||
:icon="useRenderIcon('rank')"
|
||||
style="font-size: 16px; margin: 0 4px 5px"
|
||||
>vuedraggable</el-link
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
<div class="drag-container">
|
||||
<!-- grid列表拖拽 -->
|
||||
<el-row :gutter="25">
|
||||
<el-col :xs="25" :sm="8" :md="8" :lg="8">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>grid列表拖拽</span>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :xs="25" :sm="8" :md="8" :lg="8">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>单列拖拽</span>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 单列拖拽 -->
|
||||
<draggable
|
||||
v-model="lists"
|
||||
item-key="name"
|
||||
@change="change"
|
||||
chosen-class="chosen"
|
||||
force-fallback="true"
|
||||
animation="300"
|
||||
>
|
||||
<template #item="{ element, index }">
|
||||
<div class="item-single">{{ element.name }} {{ index }}</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :xs="25" :sm="8" :md="8" :lg="8">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>拖拽实现元素位置切换</span>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 拖拽实现元素位置切换 -->
|
||||
<div class="cut-container">
|
||||
<div
|
||||
class="item-cut"
|
||||
v-for="(item, index) in cutLists"
|
||||
:key="index"
|
||||
<draggable
|
||||
v-model="gridLists"
|
||||
class="grid-container"
|
||||
item-key="grid"
|
||||
animation="300"
|
||||
chosenClass="chosen"
|
||||
forceFallback="true"
|
||||
>
|
||||
<p>{{ item.name }}</p>
|
||||
<template #item="{ element }">
|
||||
<div :class="'item' + ' ' + 'item-' + element.num">
|
||||
{{ element.num }}
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :xs="25" :sm="8" :md="8" :lg="8">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>单列拖拽</span>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 单列拖拽 -->
|
||||
<draggable
|
||||
v-model="lists"
|
||||
item-key="name"
|
||||
@change="change"
|
||||
chosen-class="chosen"
|
||||
force-fallback="true"
|
||||
animation="300"
|
||||
>
|
||||
<template #item="{ element, index }">
|
||||
<div class="item-single">{{ element.name }} {{ index }}</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<el-col :xs="25" :sm="8" :md="8" :lg="8">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>拖拽实现元素位置切换</span>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 拖拽实现元素位置切换 -->
|
||||
<div class="cut-container">
|
||||
<div
|
||||
class="item-cut"
|
||||
v-for="(item, index) in cutLists"
|
||||
:key="index"
|
||||
>
|
||||
<p>{{ item.name }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -16,27 +16,34 @@ const settingTB: ContextProps = reactive({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="split-pane">
|
||||
<splitpane :splitSet="settingLR">
|
||||
<!-- #paneL 表示指定该组件为左侧面板 -->
|
||||
<template #paneL>
|
||||
<!-- 自定义左侧面板的内容 -->
|
||||
<div class="dv-a">A</div>
|
||||
</template>
|
||||
<!-- #paneR 表示指定该组件为右侧面板 -->
|
||||
<template #paneR>
|
||||
<!-- 再次将右侧面板进行拆分 -->
|
||||
<splitpane :splitSet="settingTB">
|
||||
<template #paneL>
|
||||
<div class="dv-b">B</div>
|
||||
</template>
|
||||
<template #paneR>
|
||||
<div class="dv-c">C</div>
|
||||
</template>
|
||||
</splitpane>
|
||||
</template>
|
||||
</splitpane>
|
||||
</div>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium">切割面板组件</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="split-pane">
|
||||
<splitpane :splitSet="settingLR">
|
||||
<!-- #paneL 表示指定该组件为左侧面板 -->
|
||||
<template #paneL>
|
||||
<!-- 自定义左侧面板的内容 -->
|
||||
<div class="dv-a">A</div>
|
||||
</template>
|
||||
<!-- #paneR 表示指定该组件为右侧面板 -->
|
||||
<template #paneR>
|
||||
<!-- 再次将右侧面板进行拆分 -->
|
||||
<splitpane :splitSet="settingTB">
|
||||
<template #paneL>
|
||||
<div class="dv-b">B</div>
|
||||
</template>
|
||||
<template #paneR>
|
||||
<div class="dv-c">C</div>
|
||||
</template>
|
||||
</splitpane>
|
||||
</template>
|
||||
</splitpane>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -2,13 +2,16 @@
|
||||
import { onMounted } from "vue";
|
||||
import Player from "xgplayer/dist/simple_player";
|
||||
import volume from "xgplayer/es/controls/volume";
|
||||
import playbackRate from "xgplayer/es/controls/playbackRate";
|
||||
import screenShot from "xgplayer/es/controls/screenShot";
|
||||
import { deviceDetection } from "/@/utils/deviceDetection";
|
||||
import playbackRate from "xgplayer/es/controls/playbackRate";
|
||||
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
|
||||
|
||||
onMounted(() => {
|
||||
new Player({
|
||||
id: "mse",
|
||||
// 默认静音
|
||||
volume: 0,
|
||||
autoplay: false,
|
||||
screenShot: true,
|
||||
url: "https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-720p.mp4",
|
||||
@ -23,7 +26,22 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="mse"></div>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium"
|
||||
>视频组件,采用开源的<el-link
|
||||
href="https://v2.h5player.bytedance.com"
|
||||
target="_blank"
|
||||
:icon="useRenderIcon('video-play')"
|
||||
style="font-size: 16px; margin: 0 4px 5px"
|
||||
>西瓜播放器</el-link
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
<div id="mse"></div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
@ -5,12 +5,12 @@ export default {
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onBeforeUnmount, ref, unref } from "vue";
|
||||
import WangEditor from "wangeditor";
|
||||
import { onMounted, onBeforeUnmount, ref, unref } from "vue";
|
||||
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const editor = ref(null);
|
||||
const html = ref(null);
|
||||
const editor = ref(null);
|
||||
let instance: WangEditor;
|
||||
|
||||
onMounted(() => {
|
||||
@ -29,17 +29,26 @@ onBeforeUnmount(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium"
|
||||
>编辑器组件,采用开源的<el-link
|
||||
href="https://www.wangeditor.com"
|
||||
target="_blank"
|
||||
:icon="useRenderIcon('edit')"
|
||||
style="font-size: 16px; margin: 0 4px 5px"
|
||||
>wangeditor</el-link
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
<div ref="editor"></div>
|
||||
<div :innerHTML="html"></div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.main-content {
|
||||
margin: 40px;
|
||||
}
|
||||
|
||||
:deep(.w-e-text-container) {
|
||||
z-index: 99 !important;
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, unref, onMounted } from "vue";
|
||||
import LogicFlow from "@logicflow/core";
|
||||
import { Snapshot, BpmnElement, Menu } from "@logicflow/extension";
|
||||
import demoData from "./dataTurbo.json";
|
||||
import "@logicflow/core/dist/style/index.css";
|
||||
import "@logicflow/extension/lib/style/index.css";
|
||||
|
||||
import LogicFlow from "@logicflow/core";
|
||||
import { ref, unref, onMounted } from "vue";
|
||||
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
|
||||
import { BpmnNode } from "/@/components/ReFlowChart/src/config";
|
||||
import { Snapshot, BpmnElement, Menu } from "@logicflow/extension";
|
||||
import { Control, NodePanel, DataDialog } from "/@/components/ReFlowChart";
|
||||
import { toLogicflowData } from "/@/components/ReFlowChart/src/adpterForTurbo";
|
||||
import { BpmnNode } from "/@/components/ReFlowChart/src/config";
|
||||
import demoData from "./dataTurbo.json";
|
||||
|
||||
let lf = ref(null);
|
||||
let graphData = ref(null);
|
||||
@ -57,37 +59,52 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="logic-flow-view">
|
||||
<!-- 辅助工具栏 -->
|
||||
<Control
|
||||
class="demo-control"
|
||||
v-if="lf"
|
||||
:lf="lf"
|
||||
:catTurboData="false"
|
||||
@catData="catData"
|
||||
></Control>
|
||||
<!-- 节点面板 -->
|
||||
<NodePanel :lf="lf" :nodeList="nodeList"></NodePanel>
|
||||
<!-- 画布 -->
|
||||
<div id="LF-Turbo"></div>
|
||||
<!-- 数据查看面板 -->
|
||||
<el-dialog
|
||||
customClass="flow-dialog"
|
||||
title="数据"
|
||||
v-model="dataVisible"
|
||||
width="50%"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<DataDialog :graphData="graphData"></DataDialog>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium"
|
||||
>流程图组件,采用开源的<el-link
|
||||
href="http://logic-flow.org/"
|
||||
target="_blank"
|
||||
:icon="useRenderIcon('set-up')"
|
||||
style="font-size: 16px; margin: 0 4px 5px"
|
||||
>LogicFlow</el-link
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
<div class="logic-flow-view">
|
||||
<!-- 辅助工具栏 -->
|
||||
<Control
|
||||
class="demo-control"
|
||||
v-if="lf"
|
||||
:lf="lf"
|
||||
:catTurboData="false"
|
||||
@catData="catData"
|
||||
></Control>
|
||||
<!-- 节点面板 -->
|
||||
<NodePanel :lf="lf" :nodeList="nodeList"></NodePanel>
|
||||
<!-- 画布 -->
|
||||
<div id="LF-Turbo"></div>
|
||||
<!-- 数据查看面板 -->
|
||||
<el-dialog
|
||||
customClass="flow-dialog"
|
||||
title="数据"
|
||||
v-model="dataVisible"
|
||||
width="50%"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<DataDialog :graphData="graphData"></DataDialog>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
#LF-Turbo {
|
||||
width: 100%;
|
||||
height: calc(100vh - 90px);
|
||||
height: 70vh;
|
||||
}
|
||||
|
||||
.logic-flow-view {
|
||||
@ -137,8 +154,4 @@ onMounted(() => {
|
||||
height: 85vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,14 +1,7 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "reGuide"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Driver from "driver.js";
|
||||
import "driver.js/dist/driver.min.css";
|
||||
|
||||
// 步骤
|
||||
const steps = [
|
||||
{
|
||||
element: "#header-notice",
|
||||
@ -72,8 +65,14 @@ const guide = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<p>引导页对于一些第一次进入项目的人很有用,你可以简单介绍下项目的功能</p>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium"
|
||||
>引导页对于一些第一次进入项目的人很有用,你可以简单介绍下项目的功能</span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
<el-button
|
||||
type="primary"
|
||||
style="margin-top: 10px"
|
||||
@ -81,7 +80,7 @@ const guide = () => {
|
||||
>
|
||||
打开引导页
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
|
@ -20,12 +20,16 @@ function changRole(value) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-radio-group v-model="auth" @change="changRole">
|
||||
<el-radio-button label="admin"></el-radio-button>
|
||||
<el-radio-button label="test"></el-radio-button>
|
||||
</el-radio-group>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<el-radio-group v-model="auth" @change="changRole">
|
||||
<el-radio-button label="admin"></el-radio-button>
|
||||
<el-radio-button label="test"></el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</template>
|
||||
<p v-auth="'v-admin'">只有admin可看</p>
|
||||
<p v-auth="'v-test'">只有test可看</p>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
@ -29,19 +29,23 @@ function changRole() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h4>
|
||||
当前角色:
|
||||
<span style="font-size: 26px">{{ purview }}</span>
|
||||
<p style="color: #ffa500">
|
||||
查看左侧菜单变化(系统管理),模拟后台根据不同角色返回对应路由
|
||||
</p>
|
||||
</h4>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>
|
||||
当前角色:
|
||||
<span style="font-size: 26px">{{ purview }}</span>
|
||||
<p style="color: #ffa500">
|
||||
查看左侧菜单变化(系统管理),模拟后台根据不同角色返回对应路由
|
||||
</p></span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="changRole"
|
||||
:icon="useRenderIcon('user', { color: '#fff' })"
|
||||
>切换角色</el-button
|
||||
>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
@ -1,11 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import { useMultiTagsStoreHook } from "/@/store/modules/multiTags";
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const activeName = ref("tag");
|
||||
|
||||
function toDetail(index: number) {
|
||||
useMultiTagsStoreHook().handleTags("push", {
|
||||
@ -25,33 +23,16 @@ function toDetail(index: number) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-collapse v-model="activeName" class="tabs-container">
|
||||
<el-collapse-item
|
||||
title="标签页复用超出限制自动关闭(使用场景: 动态路由)"
|
||||
name="tag"
|
||||
>
|
||||
<el-button v-for="index in 6" :key="index" @click="toDetail(index)">
|
||||
打开{{ index }}详情页
|
||||
</el-button>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="font-medium"
|
||||
>标签页复用,超出限制自动关闭(使用场景: 动态路由)</span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
<el-button v-for="index in 6" :key="index" @click="toDetail(index)">
|
||||
打开{{ index }}详情页
|
||||
</el-button>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tabs-container {
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
|
||||
::v-deep(.el-collapse-item__header) {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
::v-deep(.el-collapse-item__wrap) {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -61,7 +61,7 @@ const openDepot = (): void => {
|
||||
}
|
||||
}"
|
||||
>
|
||||
<el-card>
|
||||
<el-card style="height: 360px">
|
||||
<template #header>
|
||||
<span style="font-size: 16px; font-weight: 500">GitHub信息</span>
|
||||
</template>
|
||||
@ -93,7 +93,7 @@ const openDepot = (): void => {
|
||||
}
|
||||
}"
|
||||
>
|
||||
<el-card>
|
||||
<el-card style="height: 360px">
|
||||
<template #header>
|
||||
<span style="font-size: 16px; font-weight: 500"
|
||||
>GitHub滚动信息</span
|
||||
|
Loading…
x
Reference in New Issue
Block a user