Commit 4b56b9ee authored by hucy's avatar hucy

fix:表单样式修改

parent 589b9c5c
interface DialogLayoutProps {
width?: number;
height?: number;
[proppName: string]: any;
}
export type { DialogLayoutProps };
export interface AnyType { export interface AnyType {
[proppName: string]: any; [proppName: string]: any;
} }
export * from './dialog-layout-props';
...@@ -23,4 +23,5 @@ export { ...@@ -23,4 +23,5 @@ export {
replace, replace,
repeat, repeat,
uniqueId, uniqueId,
omit,
} from 'lodash-es'; } from 'lodash-es';
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
{{ item.label }} {{ item.label }}
</div> </div>
<q-input <q-input
:class="{
'form-label-padding-bottom': isEmpty(item.bind?.rules),
}"
:type="item.isPwd ? 'password' : 'text'" :type="item.isPwd ? 'password' : 'text'"
v-model="formValue[item.fild]" v-model="formValue[item.fild]"
v-bind="item.bind" v-bind="item.bind"
...@@ -56,6 +59,9 @@ ...@@ -56,6 +59,9 @@
{{ item.label }} {{ item.label }}
</div> </div>
<date-time-pick <date-time-pick
:class="{
'form-label-padding-bottom': isEmpty(item.bind?.rules),
}"
:dense=" :dense="
item.bind.dense === undefined ? props.dense : item.bind.dense item.bind.dense === undefined ? props.dense : item.bind.dense
" "
...@@ -86,6 +92,9 @@ ...@@ -86,6 +92,9 @@
{{ item.label }} {{ item.label }}
</div> </div>
<time-pick <time-pick
:class="{
'form-label-padding-bottom': isEmpty(item.bind?.rules),
}"
format24h format24h
v-model="formValue[item.fild]" v-model="formValue[item.fild]"
:config="item.bind" :config="item.bind"
...@@ -114,6 +123,9 @@ ...@@ -114,6 +123,9 @@
{{ item.label }} {{ item.label }}
</div> </div>
<date-multiple <date-multiple
:class="{
'form-label-padding-bottom': isEmpty(item.bind?.rules),
}"
v-model="formValue[item.fild]" v-model="formValue[item.fild]"
:config="item.bind" :config="item.bind"
:dense=" :dense="
...@@ -141,6 +153,9 @@ ...@@ -141,6 +153,9 @@
{{ item.label }} {{ item.label }}
</div> </div>
<date-range <date-range
:class="{
'form-label-padding-bottom': isEmpty(item.bind?.rules),
}"
v-model="formValue[item.fild]" v-model="formValue[item.fild]"
:config="item.bind" :config="item.bind"
:dense=" :dense="
...@@ -168,6 +183,9 @@ ...@@ -168,6 +183,9 @@
{{ item.label }} {{ item.label }}
</div> </div>
<color-pick <color-pick
:class="{
'form-label-padding-bottom': isEmpty(item.bind?.rules),
}"
v-model="formValue[item.fild]" v-model="formValue[item.fild]"
:config="item.bind" :config="item.bind"
:dense=" :dense="
...@@ -194,7 +212,11 @@ ...@@ -194,7 +212,11 @@
> >
{{ item.label }} {{ item.label }}
</div> </div>
<q-input <q-input
:class="{
'form-label-padding-bottom': isEmpty(item.bind?.rules),
}"
v-if="item.type !== 'select'" v-if="item.type !== 'select'"
:type="item.type" :type="item.type"
v-model="formValue[item.fild]" v-model="formValue[item.fild]"
...@@ -215,6 +237,9 @@ ...@@ -215,6 +237,9 @@
/> />
<q-select <q-select
class="my-select" class="my-select"
:class="{
'form-label-padding-bottom': isEmpty(item.bind?.rules),
}"
v-if="item.type === 'select'" v-if="item.type === 'select'"
v-bind="item.bind" v-bind="item.bind"
v-model="formValue[item.fild]" v-model="formValue[item.fild]"
...@@ -245,7 +270,7 @@ import TimePick from './TimePick.vue'; ...@@ -245,7 +270,7 @@ import TimePick from './TimePick.vue';
import DateMultiple from './DateMultiple.vue'; import DateMultiple from './DateMultiple.vue';
import DateRange from './DateRange.vue'; import DateRange from './DateRange.vue';
import ColorPick from './ColorPick.vue'; import ColorPick from './ColorPick.vue';
import { cloneDeep, isObjEqual } from 'src/common/utils'; import { cloneDeep, isObjEqual, isEmpty } from 'src/common/utils';
interface Props { interface Props {
config: any; config: any;
...@@ -334,6 +359,9 @@ function reset() { ...@@ -334,6 +359,9 @@ function reset() {
<style lang="scss" scoped> <style lang="scss" scoped>
.item { .item {
padding: $padding-sm; padding: $padding-sm;
padding-bottom: 0;
padding-top: 0;
// border: 1px solid red;
} }
.item-content { .item-content {
height: 100%; height: 100%;
...@@ -350,14 +378,17 @@ function reset() { ...@@ -350,14 +378,17 @@ function reset() {
margin-bottom: 2px; margin-bottom: 2px;
display: inline-block; display: inline-block;
} }
.form-label-padding-bottom {
:deep(.my-select padding-bottom: 20px;
> :nth-child(1)
> :nth-child(1)
> :nth-child(1)
> :nth-child(1)
> span) {
white-space: nowrap;
overflow: hidden;
} }
// :deep(.my-select
// > :nth-child(1)
// > :nth-child(1)
// > :nth-child(1)
// > :nth-child(1)
// > span) {
// white-space: nowrap;
// overflow: hidden;
// }
</style> </style>
<script setup lang="ts">
import { reactive, computed } from 'vue';
interface IDetailProps {
title?: any;
width?: number;
maxWidth?: number;
minWidth?: number;
height?: number;
maxHeight?: number;
minHeight?: number;
}
const props = withDefaults(defineProps<IDetailProps>(), {
title: '',
width: 1000,
maxWidth: 1000,
minWidth: 500,
height: 600,
maxHeight: 900,
minHeight: 500,
});
const emit = defineEmits<{
(e: 'onOk'): void;
(e: 'onCancel'): void;
}>();
const myCardStyle = computed(() => {
return {
width: props.width + 'px',
maxWidth: props.maxWidth + 'px',
minWidth: props.minWidth + 'px',
height: props.height + 'px',
maxHeight: props.maxHeight + 'px',
minHeight: props.minHeight + 'px',
};
});
const thumbStyle = reactive({
right: '4px',
borderRadius: '5px',
backgroundColor: '#64b3f4',
width: '5px',
opacity: '1',
});
const barStyle = reactive({
right: '2px',
borderRadius: '9px',
backgroundColor: '#027be3',
width: '9px',
opacity: '0.2',
});
function onCancel() {
emit('onCancel');
}
function onSave() {
emit('onOk');
}
</script>
<template>
<q-card class="my-card" :style="myCardStyle">
<div class="card-content">
<div class="title">{{ title }}</div>
<div class="content">
<q-scroll-area
style="height: 100%; max-width: 100%"
:thumb-style="thumbStyle"
:bar-style="barStyle"
>
<slot></slot>
</q-scroll-area>
</div>
<div class="bottom-action">
<q-btn flat style="color: #64b3f4" label="取消" @click="onCancel" />
<q-btn
unelevated
style="background: #64b3f4; color: white"
label="确定"
@click="onSave()"
/>
</div>
</div>
</q-card>
</template>
<style lang="scss" scoped>
.my-card {
padding: 20px;
background-image: linear-gradient(60deg, #c2e59c 0%, #64b3f4 100%);
box-sizing: border-box;
display: flex;
}
.card-content {
width: 100%;
background-color: #fff;
display: flex;
flex-direction: column;
overflow: hidden;
.title {
height: 40px;
padding: 8px;
font-size: 16px;
font-weight: bolder;
color: #c2e59c;
display: flex;
align-items: center;
}
.content {
flex: 1;
padding: 8px;
position: relative;
}
.bottom-action {
padding: 8px;
display: flex;
flex-direction: row;
column-gap: 4px;
justify-content: flex-end;
align-items: center;
}
}
</style>
...@@ -15,6 +15,7 @@ import AgGridNoRowsComponent from './ag-grid/NoRowsOverlayComponent.vue'; ...@@ -15,6 +15,7 @@ import AgGridNoRowsComponent from './ag-grid/NoRowsOverlayComponent.vue';
import AgGridLoadingOverlayComponent from './ag-grid/LoadingOverlayComponent.vue'; import AgGridLoadingOverlayComponent from './ag-grid/LoadingOverlayComponent.vue';
import AgGridDateComponent from './ag-grid/DateComponent.vue'; import AgGridDateComponent from './ag-grid/DateComponent.vue';
import DialogTip from './dialog-tip/DialogTip.vue'; import DialogTip from './dialog-tip/DialogTip.vue';
import DialogLayout from './dialog-layout/DialogLayout.vue';
export { export {
DateTimePick as ComDateTimePick, DateTimePick as ComDateTimePick,
...@@ -33,6 +34,7 @@ export { ...@@ -33,6 +34,7 @@ export {
AgGridLoadingOverlayComponent as ComAgGridLoadingOverlayComponent, AgGridLoadingOverlayComponent as ComAgGridLoadingOverlayComponent,
AgGridDateComponent as ComAgGridDateComponent, AgGridDateComponent as ComAgGridDateComponent,
DialogTip as ComDialogTip, DialogTip as ComDialogTip,
DialogLayout as ComDialogLayout,
}; };
export default { export default {
...@@ -52,4 +54,5 @@ export default { ...@@ -52,4 +54,5 @@ export default {
AgGridLoadingOverlayComponent, AgGridLoadingOverlayComponent,
AgGridDateComponent, AgGridDateComponent,
DialogTip, DialogTip,
DialogLayout,
}; };
...@@ -7,45 +7,45 @@ export const MenuList = [ ...@@ -7,45 +7,45 @@ export const MenuList = [
active: false, active: false,
}, },
{ {
title: '', title: '图表',
caption: '日历', caption: 'chart虚拟滚动',
icon: require('./menuListIcons/page1.svg'), icon: require('./menuListIcons/page1.svg'),
link: '/page1', link: '/page1',
active: false, active: false,
}, },
{ {
title: '', title: 'canvas',
caption: 'canvas小车动画', caption: 'canvas小车动画',
icon: require('./menuListIcons/page4.svg'), icon: require('./menuListIcons/page4.svg'),
link: '/page4', link: '/page4',
active: false, active: false,
}, },
{ {
title: '', title: '动画',
caption: '动画', caption: '',
icon: require('./menuListIcons/page8.svg'), icon: require('./menuListIcons/page8.svg'),
link: '/page8', link: '/page8',
active: false, active: false,
}, },
{ {
title: '', title: '表格',
caption: '动画2&表格', caption: '动画2&表格',
icon: require('./menuListIcons/page9.svg'), icon: require('./menuListIcons/page9.svg'),
link: '/page9', link: '/page9',
active: false, active: false,
}, },
{ {
title: '', title: '设计',
caption: '设计', caption: '一言',
icon: require('./menuListIcons/page10.svg'), icon: require('./menuListIcons/page10.svg'),
link: '/page10', link: '/page10',
active: false, active: false,
}, },
{ {
title: 'tree', title: 'Tree',
caption: '树', caption: '树',
icon: require('./menuListIcons/page10.svg'), icon: require('./menuListIcons/tree.svg'),
link: '/tree', link: '/tree',
active: false, active: false,
}, },
...@@ -56,8 +56,8 @@ export const MenuList = [ ...@@ -56,8 +56,8 @@ export const MenuList = [
active: false, active: false,
children: [ children: [
{ {
title: '', title: '表单',
caption: '表单', caption: '',
icon: require('./menuListIcons/page2.svg'), icon: require('./menuListIcons/page2.svg'),
link: '/page2', link: '/page2',
active: false, active: false,
...@@ -85,14 +85,14 @@ export const MenuList = [ ...@@ -85,14 +85,14 @@ export const MenuList = [
active: false, active: false,
}, },
{ {
title: '', title: '防抖节流',
caption: '表格&防抖节流', caption: '表格&防抖节流',
icon: require('./menuListIcons/page5.svg'), icon: require('./menuListIcons/page5.svg'),
link: '/page5', link: '/page5',
active: false, active: false,
}, },
{ {
title: '', title: 'JS',
caption: '一些js练习', caption: '一些js练习',
icon: require('./menuListIcons/page6.png'), icon: require('./menuListIcons/page6.png'),
link: '/js-page6', link: '/js-page6',
...@@ -107,8 +107,8 @@ export const MenuList = [ ...@@ -107,8 +107,8 @@ export const MenuList = [
active: false, active: false,
children: [ children: [
{ {
title: '', title: '疫情防控',
caption: '疫情防控', caption: '',
icon: require('./menuListIcons/page7.svg'), icon: require('./menuListIcons/page7.svg'),
link: '/page7', link: '/page7',
active: false, active: false,
......
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1674021701598" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1097" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M165.8 224.4l333.3 217.5M487.3 450.6L154 233.1l23.6-17.3L511 433.2zM874.7 224.4L541.4 441.9M553.2 450.6l333.4-217.5-23.7-17.3-333.4 217.4z" fill="#65C8D0" p-id="1098"></path><path d="M485.8 412.2h64.3v545.2h-64.3z" fill="#65C8D0" p-id="1099"></path><path d="M312.3 159.7a43.1 35.6 0 1 0 86.2 0 43.1 35.6 0 1 0-86.2 0Z" fill="#65C8D0" p-id="1100"></path><path d="M467.9 297.6a43.1 35.6 0 1 0 86.2 0 43.1 35.6 0 1 0-86.2 0Z" fill="#65C8D0" p-id="1101"></path><path d="M648.4 207.6a43.1 35.6 0 1 0 86.2 0 43.1 35.6 0 1 0-86.2 0Z" fill="#65C8D0" p-id="1102"></path><path d="M495.3 124.1a43.1 35.6 0 1 0 86.2 0 43.1 35.6 0 1 0-86.2 0Z" fill="#65C8D0" p-id="1103"></path></svg>
\ No newline at end of file
...@@ -43,11 +43,16 @@ function getData() { ...@@ -43,11 +43,16 @@ function getData() {
function clickAdd() { function clickAdd() {
formDialogRef.value.openDialog(); formDialogRef.value.openDialog();
} }
function viewData() {
console.log('查看', state.rowData);
}
</script> </script>
<template> <template>
<div class="box"> <div class="box">
<div class="actions"> <div class="actions">
<q-btn color="primary" label="添加" @click="clickAdd" /> <q-btn unelevated color="primary" label="添加" @click="clickAdd" />
<q-btn unelevated color="primary" label="查看" @click="viewData" />
</div> </div>
<div class="ag-table"> <div class="ag-table">
<ag-grid-vue <ag-grid-vue
......
...@@ -21,7 +21,6 @@ export const form_config = [ ...@@ -21,7 +21,6 @@ export const form_config = [
bind: { bind: {
filled: true, filled: true,
lazyRules: true, lazyRules: true,
hideBottomSpace: true,
rules: [(val: any) => !isEmpty(val) || '必填'], rules: [(val: any) => !isEmpty(val) || '必填'],
}, },
}, },
...@@ -34,7 +33,6 @@ export const form_config = [ ...@@ -34,7 +33,6 @@ export const form_config = [
bind: { bind: {
filled: true, filled: true,
lazyRules: true, lazyRules: true,
hideBottomSpace: true,
rules: [(val: any) => !isEmpty(val) || '必填'], rules: [(val: any) => !isEmpty(val) || '必填'],
}, },
}, },
...@@ -47,7 +45,6 @@ export const form_config = [ ...@@ -47,7 +45,6 @@ export const form_config = [
bind: { bind: {
filled: true, filled: true,
lazyRules: true, lazyRules: true,
hideBottomSpace: true,
rules: [ rules: [
(val: any) => !isEmpty(val) || '必填', (val: any) => !isEmpty(val) || '必填',
(val: any) => (val > 0 && val < 100) || '请输入真实年龄', (val: any) => (val > 0 && val < 100) || '请输入真实年龄',
...@@ -55,29 +52,8 @@ export const form_config = [ ...@@ -55,29 +52,8 @@ export const form_config = [
}, },
}, },
{ {
fild: 'sex', solt: 'sex',
label: '性别',
col: 'col-4', col: 'col-4',
type: 'select',
required: true,
bind: {
filled: true,
lazyRules: true,
hideBottomSpace: true,
rules: [(val: any) => !isEmpty(val) || '必填'],
emitValue: true,
mapOptions: true,
options: [
{
label: '男',
value: 1,
},
{
label: '女',
value: 0,
},
],
},
}, },
{ {
fild: 'dateRange', fild: 'dateRange',
...@@ -122,6 +98,10 @@ export const form_config = [ ...@@ -122,6 +98,10 @@ export const form_config = [
label: 'Facebook', label: 'Facebook',
value: 'Facebook', value: 'Facebook',
}, },
{
label: 'AAA',
value: 'aaa',
},
], ],
}, },
}, },
......
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'; import { ref, reactive, onMounted } from 'vue';
import { useMessage } from 'src/common/hooks';
import Com from 'src/components'; import Com from 'src/components';
import { isEmpty } from 'src/common/utils';
import { form_config } from '../config'; import { form_config } from '../config';
import type { DialogLayoutProps } from 'src/common/types';
defineExpose({ defineExpose({
openDialog, openDialog,
closeDialog, closeDialog,
}); });
const { warn } = useMessage();
const formRef = ref<any>(null); const formRef = ref<any>(null);
const show = ref(false); const show = ref(false);
...@@ -19,6 +24,21 @@ const state = reactive({ ...@@ -19,6 +24,21 @@ const state = reactive({
formData: {} as any, formData: {} as any,
}); });
const pagestate = reactive<DialogLayoutProps>({
title: '添加',
});
const sexOpt = reactive([
{
label: '男',
value: 1,
},
{
label: '女',
value: 0,
},
]);
onMounted(() => { onMounted(() => {
initFormConfig(); initFormConfig();
}); });
...@@ -40,89 +60,73 @@ function closeDialog() { ...@@ -40,89 +60,73 @@ function closeDialog() {
initDialog(); initDialog();
} }
function onCancel() {
closeDialog();
}
function onSave() { function onSave() {
const { formData } = state;
formRef.value.validate().then((suc: any) => { formRef.value.validate().then((suc: any) => {
if (!suc) return; if (!suc) return;
console.log('formData >>>>', state.formData); if (isEmpty(formData.sex)) return warn('性别必填');
console.log('formData >>>>', formData);
closeDialog(); closeDialog();
}); });
} }
function onCancel() {
closeDialog();
}
</script> </script>
<template> <template>
<q-dialog v-model="show" persistent> <q-dialog v-model="show" persistent>
<q-card class="my-card"> <Com.DialogLayout v-bind="pagestate" @onOk="onSave" @onCancel="onCancel">
<div class="card-content">
<div class="title">添加</div>
<div class="content">
<Com.MyForm <Com.MyForm
ref="formRef" ref="formRef"
dense dense
:readonly="state.readonly" :readonly="state.readonly"
:config="state.formConfig" :config="state.formConfig"
v-model="state.formData" v-model="state.formData"
></Com.MyForm> >
</div> <template #sex>
<div class="bottom-action"> <div class="item-content">
<q-btn flat style="color: #64b3f4" label="取消" @click="onCancel" /> <div class="label-title text-required">性别</div>
<q-btn <div class="label-content">
unelevated <q-option-group
style="background: #64b3f4; color: white" v-model="state.formData.sex"
label="确定" :options="sexOpt"
@click="onSave()" color="primary"
inline
:disable="state.readonly"
/> />
</div> </div>
</div> </div>
</q-card> </template>
</Com.MyForm>
</Com.DialogLayout>
</q-dialog> </q-dialog>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.my-card { .item-content {
width: 1000px; height: 40px;
max-width: 1000px;
min-height: 500px;
padding: 20px;
background-image: linear-gradient(60deg, #c2e59c 0%, #64b3f4 100%);
box-sizing: border-box;
display: flex;
}
.card-content {
width: 100%; width: 100%;
background-color: #fff;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-wrap: nowrap;
.title { }
height: 40px; .label-title {
padding: 8px; height: 22px;
font-size: 16px; font-size: 14px;
font-weight: bolder; line-height: 22px;
color: #c2e59c; color: rgba(0, 0, 0, 0.871);
display: flex; margin-bottom: 2px;
align-items: center; display: inline-block;
// background-color: #ee9ca7; }
} .label-content {
.content {
flex: 1; flex: 1;
padding: 8px;
}
.bottom-action {
// background-color: #209cff;
padding: 8px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
column-gap: 4px;
justify-content: flex-end;
align-items: center; align-items: center;
} background-color: rgba(0, 0, 0, 0.05);
border-radius: 4px 4px 0 0;
} }
</style> </style>
...@@ -4,7 +4,7 @@ export default [ ...@@ -4,7 +4,7 @@ export default [
name: 'FORM_TEST', name: 'FORM_TEST',
component: () => import('./IndexPage.vue'), component: () => import('./IndexPage.vue'),
meta: { meta: {
title: '表单&表格', title: '信息',
permission: ['*'], permission: ['*'],
keepalive: true, keepalive: true,
}, },
......
...@@ -265,7 +265,7 @@ function onResetForm() { ...@@ -265,7 +265,7 @@ function onResetForm() {
border: 1px solid $border-color; border: 1px solid $border-color;
} }
.item-content { .item-content {
height: 100%; height: calc(100% - 20px);
width: 100%; width: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
......
...@@ -9,7 +9,6 @@ export const form = [ ...@@ -9,7 +9,6 @@ export const form = [
readonly: true, readonly: true,
filled: true, filled: true,
lazyRules: true, lazyRules: true,
hideBottomSpace: true,
rules: [(val: any) => (val && val.length > 0) || '必填'], rules: [(val: any) => (val && val.length > 0) || '必填'],
}, },
}, },
...@@ -19,11 +18,11 @@ export const form = [ ...@@ -19,11 +18,11 @@ export const form = [
col: 'col-6', col: 'col-6',
type: 'password', type: 'password',
isPwd: true, isPwd: true,
required: true,
bind: { bind: {
filled: true, filled: true,
// lazyRules: true, lazyRules: true,
// hideBottomSpace: true, rules: [(val: any) => (val && val.length > 0) || '必填'],
// rules: [(val: any) => (val && val.length > 0) || '必填'],
}, },
}, },
{ {
...@@ -59,7 +58,6 @@ export const form = [ ...@@ -59,7 +58,6 @@ export const form = [
}, },
], ],
// lazyRules: true, // lazyRules: true,
// hideBottomSpace: true,
// rules: [(val: any) => (val && val.length > 0) || '必填'], // rules: [(val: any) => (val && val.length > 0) || '必填'],
clearable: true, clearable: true,
}, },
......
<script setup lang="ts"> <script setup lang="ts">
import { reactive, onMounted } from 'vue'; import { reactive, onMounted } from 'vue';
import { cloneDeep, isEmpty } from 'src/common/utils'; import { useQuasar } from 'quasar';
import nestedDraggable from './infra/nested.vue'; import { cloneDeep, isEmpty, omit } from 'src/common/utils';
import nestedDraggable from './element/nested.vue';
import { ComDialogTip } from 'src/components';
const $q = useQuasar();
const SpcGroupItem = {
show: true,
title: null,
children: [],
};
const data = [ const data = [
{ {
name: 'task 1', title: '1',
show: true, children: [
tasks: [
{ {
name: 'task 2', title: '1-1',
show: true, children: [],
tasks: [],
},
],
key: '1',
}, },
{ {
name: 'task 3', title: '1-2',
show: true, children: [],
tasks: [ },
{ {
name: 'task 4', title: '1-3',
show: true, children: [],
tasks: [],
}, },
], ],
key: '2',
}, },
{ {
name: 'task 5', title: '2',
show: true, children: [],
tasks: [],
key: '3',
}, },
]; ];
const state = reactive({ const state = reactive({
list: [] as any[],
originalData: [] as any[], originalData: [] as any[],
list: [] as any[],
itemKey: 'key',
childrenKey: 'children',
labelKey: 'title',
dataStacks: [] as any,
}); });
onMounted(() => { onMounted(() => {
state.originalData = cloneDeep(data); initData(data);
handleData(data);
state.list = data;
}); });
function handleData(data: any, key = 'tasks', before = 0) { function initData(data: any) {
state.originalData = data;
const _data = cloneDeep(data);
handleData(_data);
state.list = _data;
pushDataToStacks();
// console.log('state.list', state.list);
}
function pushDataToStacks() {
state.dataStacks.push({
data: cloneDeep(state.list),
});
}
function handleData(data: any, key = state.childrenKey, before = 0) {
let index = 0; let index = 0;
data.map((item: any) => { data.map((item: any) => {
let indexstr; let indexstr;
if (before) { if (before) {
indexstr = before + '-' + String(index); indexstr = String(before) + '-' + String(index);
} else { } else {
indexstr = String(index); indexstr = String(index);
} }
if (isEmpty(item.show)) {
item.show = true;
}
item['test_index'] = indexstr; item['test_index'] = indexstr;
item[state.itemKey] = indexstr;
if (data.length - 1 === index) {
item.lastChild = true;
} else {
item.lastChild = false;
}
index++; index++;
if (!isEmpty(item[key])) { if (!isEmpty(item[key])) {
...@@ -69,61 +94,93 @@ function handleData(data: any, key = 'tasks', before = 0) { ...@@ -69,61 +94,93 @@ function handleData(data: any, key = 'tasks', before = 0) {
}); });
} }
function viewData() { function handelDel(listdata: any[]) {
console.log('查看 >>>>', state.list); const chiledKey = state.childrenKey;
let newArr = [] as any[];
listdata.map((item) => {
if (!isEmpty(item[chiledKey])) {
item[chiledKey] = handelDel(item[chiledKey]);
}
if (!item['test_delete']) {
newArr.push(item);
}
});
return newArr;
} }
function onReset() { function getTarget(list: any, index: number) {
const data = cloneDeep(state.originalData); const target = list[index];
handleData(data); const parent = list;
state.list = data; return { target, parent };
}
function delTestKey(listdata: any[]) {
const chiledKey = state.childrenKey;
let seq = 1;
return listdata.map((item: any) => {
if (!isEmpty(item[chiledKey])) {
item[chiledKey] = delTestKey(item[chiledKey]);
}
const newObj = omit(item, ['key', 'test_index', 'show', 'lastChild']);
newObj.seq = seq;
seq++;
return newObj;
});
} }
// 查看
function viewData() {
const data = cloneDeep(state.list);
const resdata = delTestKey(data);
console.log('最后处理格式', resdata);
}
// 重置
function onReset() {
state.dataStacks = [];
initData(cloneDeep(state.originalData));
}
// 拖拽结束 // 拖拽结束
function dragEnd() { function dragEnd() {
handleData(state.list); handleData(state.list);
console.log('拖拽结束2', state.list); pushDataToStacks();
} }
// 添加
function onAdd() { function onAdd() {
let obj: any = { let obj = { ...SpcGroupItem } as any;
name: null, obj[state.itemKey] = Date.now();
tasks: [],
key: Date.now(),
};
state.list.push(obj); state.list.push(obj);
handleData(state.list); handleData(state.list);
pushDataToStacks();
} }
// 删除 // 删除
function delItem(data: any) { function delItem(data: any) {
console.log('删除', data); let msg = '';
if (!isEmpty(data.children)) {
msg = '确定删除 ' + <string>data.title + '及其所有子项?';
} else {
msg = '确定删除 ' + <string>data.title + '?';
}
$q.dialog({
component: ComDialogTip,
componentProps: {
persistent: true,
text: msg,
color: 'negative',
},
}).onOk(() => {
data['test_delete'] = true; data['test_delete'] = true;
let res = handelDel(state.list); let res = handelDel(state.list);
handleData(res); handleData(res);
state.list = res; state.list = res;
} pushDataToStacks();
function handelDel(listdata: any[]) {
const chiledKey = 'tasks';
let newArr = [] as any[];
listdata.map((item) => {
if (!isEmpty(item[chiledKey])) {
item[chiledKey] = handelDel(item[chiledKey]);
}
if (!item['test_delete']) {
newArr.push(item);
}
}); });
return newArr;
} }
// 同级添加 // 同级添加
function addItem(data: any) { function addItem(data: any) {
console.log('同级添加', data); const key = state.childrenKey;
const key = 'tasks';
const indexList = data['test_index'].split('-'); const indexList = data['test_index'].split('-');
let re: any; let re: any;
...@@ -136,21 +193,16 @@ function addItem(data: any) { ...@@ -136,21 +193,16 @@ function addItem(data: any) {
} }
} }
let obj: any = { let obj = { ...SpcGroupItem } as any;
name: null, obj[state.itemKey] = Date.now();
show: true,
key: Date.now(),
};
obj[key] = [];
re.parent.push(obj); re.parent.push(obj);
handleData(state.list); handleData(state.list);
pushDataToStacks();
} }
// 子级添加 // 子级添加
function addNest(data: any) { function addNest(data: any) {
const key = 'tasks'; const key = state.childrenKey;
console.log('子级添加', data);
const indexList = data['test_index'].split('-'); const indexList = data['test_index'].split('-');
let re: any; let re: any;
...@@ -163,53 +215,41 @@ function addNest(data: any) { ...@@ -163,53 +215,41 @@ function addNest(data: any) {
} }
} }
let obj: any = { let obj = { ...SpcGroupItem } as any;
name: null, obj[state.itemKey] = Date.now();
show: true,
key: Date.now(),
};
obj[key] = [];
re.target[key].push(obj); re.target[key].push(obj);
handleData(state.list); handleData(state.list);
pushDataToStacks();
} }
// 撤销
function getTarget(list: any, index: number) { function onUndo() {
const target = list[index]; const lastindex = state.dataStacks.length - 2;
const parent = list; const lastdata = state.dataStacks[lastindex];
return { target, parent }; state.list = cloneDeep(lastdata.data);
} state.dataStacks.splice(lastindex + 1, 1);
function getParamData() {
//
let data = cloneDeep(state.list);
let res = delTestKey(data);
console.log('原来的格式', res);
}
function delTestKey(listdata: any[], delKey = 'test_index') {
const chiledKey = 'tasks';
return listdata.map((item: any) => {
if (!isEmpty(item[chiledKey])) {
item[chiledKey] = delTestKey(item[chiledKey], delKey);
}
delete item[delKey];
return item;
});
} }
</script> </script>
<template> <template>
<div class="box"> <div class="box">
<div class="actions"> <div class="actions">
<q-btn color="primary" label="查看" @click="viewData" /> <q-btn unelevated color="primary" label="查看" @click="viewData" />
<q-btn color="primary" label="原来的格式" @click="getParamData" /> <q-btn unelevated color="primary" label="重置" @click="onReset" />
<q-btn color="primary" label="重置" @click="onReset" /> <q-btn unelevated color="primary" label="添加" @click="onAdd" />
<q-btn color="primary" label="添加" @click="onAdd" /> <q-btn
unelevated
color="primary"
label="撤销"
@click="onUndo"
:disable="state.dataStacks.length < 2"
/>
</div> </div>
<div class="tree-box"> <div class="tree-box">
<nested-draggable <nested-draggable
:tasks="state.list" :tasks="state.list"
:item-key="state.itemKey"
:children-key="state.childrenKey"
:label-key="state.labelKey"
@onEnd="dragEnd" @onEnd="dragEnd"
@addItem="addItem" @addItem="addItem"
@addNest="addNest" @addNest="addNest"
...@@ -221,7 +261,7 @@ function delTestKey(listdata: any[], delKey = 'test_index') { ...@@ -221,7 +261,7 @@ function delTestKey(listdata: any[], delKey = 'test_index') {
<style lang="scss" scoped> <style lang="scss" scoped>
.actions { .actions {
padding: 10px; padding: 20px 10px 10px 20px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
...@@ -229,13 +269,6 @@ function delTestKey(listdata: any[], delKey = 'test_index') { ...@@ -229,13 +269,6 @@ function delTestKey(listdata: any[], delKey = 'test_index') {
column-gap: 10px; column-gap: 10px;
} }
.tree-box { .tree-box {
// width: 600px; transform: translateX(-20px);
height: 500px;
box-sizing: border-box;
// border: 1px solid brown;
overflow: auto;
> :nth-child(1) {
// padding-right: 10px;
}
} }
</style> </style>
<template>
<div class="row">
<div class="col-1">
<button class="btn btn-secondary button" @click="add">Add</button>
</div>
<div class="col-7">
<h3>Draggable {{ draggingInfo }}</h3>
<draggable
tag="ul"
:list="list"
class="list-group"
handle=".handle"
item-key="name"
>
<template #item="{ element, index }">
<li class="list-group-item">
<i class="fa fa-align-justify handle"></i>
<span class="text">{{ element.name }} </span>
<input type="text" class="form-control" v-model="element.text" />
<i class="fa fa-times close" @click="removeAt(index)"></i>
</li>
</template>
</draggable>
</div>
<rawDisplayer class="col-3" :value="list" title="List" />
</div>
</template>
<script>
let id = 3;
import draggable from 'vuedraggable';
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: 'handle',
display: 'Handle',
instruction: 'Drag using the handle icon',
order: 5,
components: {
draggable,
},
data() {
return {
list: [
{ name: 'John', text: '', id: 0 },
{ name: 'Joao', text: '', id: 1 },
{ name: 'Jean', text: '', id: 2 },
],
dragging: false,
};
},
computed: {
draggingInfo() {
return this.dragging ? 'under drag' : '';
},
},
methods: {
removeAt(idx) {
this.list.splice(idx, 1);
},
add: function () {
id++;
this.list.push({ name: 'Juan ' + id, id, text: '' });
},
},
};
</script>
<style scoped>
.button {
margin-top: 35px;
}
.handle {
float: left;
padding-top: 8px;
padding-bottom: 8px;
}
.close {
float: right;
padding-top: 8px;
padding-bottom: 8px;
}
input {
display: inline-block;
width: 50%;
}
.text {
margin: 20px;
}
</style>
<template>
<draggable
class="drag-area"
tag="div"
:scroll="true"
:list="tasks"
:group="{ name: 'g1' }"
:item-key="itemKey"
:onEnd="onEnd"
:animation="150"
>
<template #item="{ element }">
<div
:class="[
'drag-area-item',
`dragareaitem-${element.test_index}`,
{ 'has-left-line': hasLeftLine(element.test_index) },
]"
>
<span
class="has-left-vertical-line"
:class="{ 'has-left-vertical-line-last': element.lastChild }"
></span>
<div
class="drag-area-item-conten"
:style="{
paddingLeft: isEmpty(element[childrenKey]) ? '6px' : '0px',
}"
>
<div class="drag-area-item-conten-left">
<q-icon
v-if="!isEmpty(element[childrenKey])"
@click="element.show = !element.show"
color="grey"
name="bi-caret-down-fill"
class="handle"
:style="{
transform: element.show ? 'rotate(0deg)' : 'rotate(-90deg)',
}"
/>
<input
type="text"
class="item-conten-input"
v-model="element[labelKey]"
/>
</div>
<div class="actions">
<q-btn
color="grey"
dense
flat
icon="bi-hdd-stack-fill"
@click="addItem(element)"
>
<q-tooltip>同级添加</q-tooltip>
</q-btn>
<q-btn
color="grey"
dense
flat
icon="bi-hdd-network-fill"
@click="addNest(element)"
>
<q-tooltip>子级添加</q-tooltip>
</q-btn>
<q-btn
color="grey"
dense
flat
icon="bi-trash"
@click="delItem(element)"
>
<q-tooltip>删除</q-tooltip>
</q-btn>
</div>
</div>
<q-slide-transition>
<nested-draggable
v-show="element.show"
:tasks="element[childrenKey]"
:item-key="itemKey"
:children-key="childrenKey"
:label-key="labelKey"
@onEnd="onEnd"
@addItem="addItem"
@addNest="addNest"
@delItem="delItem"
/>
</q-slide-transition>
</div>
</template>
</draggable>
</template>
<script>
import { computed } from 'vue';
import { isEmpty } from 'src/common/utils';
import draggable from 'vuedraggable';
export default {
name: 'nested-draggable',
props: {
tasks: {
required: true,
type: Array,
},
itemKey: {
required: true,
type: String,
},
childrenKey: {
required: true,
type: String,
},
labelKey: {
required: true,
type: String,
},
},
components: {
draggable,
},
setup(props, ctx) {
const addItem = (data) => {
ctx.emit('addItem', data);
};
const addNest = (data) => {
ctx.emit('addNest', data);
};
const delItem = (data) => {
ctx.emit('delItem', data);
};
//
const onEnd = (data) => {
ctx.emit('onEnd', data);
};
const hasLeftLine = computed(() => (str) => {
let falg;
const leng = str.split('-');
if (leng.length > 1) {
falg = true;
} else {
falg = false;
}
return falg;
});
return {
isEmpty,
addItem,
addNest,
delItem,
onEnd,
hasLeftLine,
};
},
};
</script>
<style scoped lang="scss">
.drag-area {
// min-width: 600px;
// min-height: 20px;
overflow: auto;
/* outline: 1px dashed; */
// border: 1px solid red;
padding-left: 40px;
& > :nth-child(1) {
margin-top: 10px;
}
.drag-area-item {
position: relative;
// min-width: 600px;
// outline: 1px solid rgba(0, 0, 0, 0.125);
margin-bottom: 10px;
// background-color: pink;
.drag-area-item-conten {
height: 40px;
box-sizing: border-box;
background-color: rgba(0, 0, 0, 0.075);
// background-color: pink;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
.drag-area-item-conten-left {
// border: 1px solid purple;
// background-color: purple;
display: flex;
flex-direction: row;
align-items: center;
}
.item-conten-input {
// display: inline-block;
// background-color: #fff;
// display: flex;
// min-width: 180px;
// align-items: center;
outline-style: none;
border: 1px solid rgba(0, 0, 0, 0.075);
border-radius: 3px;
height: 32px;
padding: 0 8px;
&:focus {
// width: fit-content;
border-color: $primary;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),
0 0 8px $primary-1;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px $primary-1;
}
}
.actions {
padding: 10px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
column-gap: 10px;
}
}
}
.has-left-line {
&::before {
content: '';
position: absolute;
top: 18px;
left: -40px;
box-sizing: border-box;
width: 36px;
border-top: 1px solid rgba(0, 0, 0, 0.125);
}
}
.has-left-vertical-line {
display: inline-block;
position: absolute;
box-sizing: border-box;
// width: 50px;
height: calc(100% + 10px);
left: -40px;
top: -10px;
border-left: 1px solid rgba(0, 0, 0, 0.125);
}
.has-left-vertical-line-last {
// border-color: green;
height: 30px;
}
.handle {
float: left;
padding: 4px 8px;
font-size: 16px;
cursor: pointer;
// border: 1px solid red;
transition: transform 0.3s;
}
}
</style>
<template>
<draggable
class="drag-area"
tag="div"
:list="tasks"
:group="{ name: 'g1' }"
handle=".handle-icon"
item-key="key"
:onEnd="onEnd"
:animation="150"
>
<template #item="{ element }">
<div class="item">
<div>
<div :class="['toggle-box', { 'toggle-box-btn': !element.show }]">
<div class="toggle-left-content">
<q-icon name="fa-solid fa-bars" class="handle-icon" />
<input type="text" class="input-control" v-model="element.name" />
</div>
<div class="toggle-right-content">
<q-btn flat dense label="同级添加" @click="addItem(element)" />
<q-btn flat dense label="子级添加" @click="addNest(element)" />
<q-btn
flat
dense
label="删除"
style="margin-right: 20px"
@click="delItem(element)"
/>
<q-icon
v-if="!isEmpty(element.tasks)"
name="bi-chevron-down"
:class="[
'expansion-icon',
{ 'expansion-icon-hide': !element.show },
]"
@click="element.show = !element.show"
/>
</div>
</div>
<q-slide-transition>
<div v-show="element.show" class="content">
<div
:class="[
'placeholder',
{ 'placeholder-last': isEmpty(element.tasks) },
]"
></div>
<nested-draggable
v-show="element.show"
:tasks="element.tasks"
@onEnd="onEnd"
@addItem="addItem"
@addNest="addNest"
@delItem="delItem"
/>
</div>
</q-slide-transition>
</div>
</div>
</template>
</draggable>
</template>
<script>
// import { ref } from 'vue';
import { isEmpty } from 'src/common/utils';
import draggable from 'vuedraggable';
export default {
name: 'nested-draggable',
props: {
tasks: {
required: true,
type: Array,
},
},
components: {
draggable,
},
setup(props, ctx) {
const addItem = (data) => {
ctx.emit('addItem', data);
};
const addNest = (data) => {
ctx.emit('addNest', data);
};
const delItem = (data) => {
ctx.emit('delItem', data);
};
// 拖拽结束
const onEnd = (data) => {
ctx.emit('onEnd', data);
};
return {
isEmpty,
addItem,
addNest,
delItem,
onEnd,
};
},
};
</script>
<style scoped lang="scss">
.drag-area {
// border: 1px solid red;
}
.item {
// outline: 1px solid rgba(0, 0, 0, 0.035);
// background-color: pink;
background-color: rgba(0, 0, 0, 0.035);
margin: 10px 0;
padding-left: 10px;
margin-left: 20px;
margin-top: 10px;
transition: height 0.3s;
}
.toggle-box {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding-top: 8px;
// padding-bottom: 6px;
padding-right: 10px;
}
.toggle-box-btn {
padding-bottom: 6px;
}
.toggle-left-content {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
column-gap: 10px;
}
.toggle-right-content {
display: grid;
grid-template-columns: 70px 70px 60px 30px;
align-items: center;
}
.handle-icon {
font-size: 18px;
box-sizing: border-box;
display: inline-block;
// border: 1px solid red;
cursor: grab;
}
.expansion-icon {
font-size: 16px;
cursor: pointer;
transform: rotate(180deg);
transition: transform 0.3s;
}
.expansion-icon-hide {
transform: rotate(0);
transition: transform 0.3s;
}
.content {
// height: 46px;
// background-color: pink;
}
.placeholder {
height: 20px;
// background-color: pink;
}
.placeholder-last {
height: 6px;
// background-color: pink;
}
.input-control {
outline-style: none;
border: 1px solid rgba(0, 0, 0, 0.035);
border-radius: 3px;
height: 32px;
padding: 0 6px;
&:focus {
border-color: $primary;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px $primary-1;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px $primary-1;
}
}
</style>
<template>
<draggable
class="drag-area"
tag="div"
:list="tasks"
handle=".handle"
:group="{ name: 'g1' }"
item-key="key"
:onEnd="onEnd"
:animation="150"
>
<template #item="{ element }">
<div class="drag-area-item">
<div class="drag-area-item-conten">
<!-- <div class="text">{{ element.name }}</div> -->
<div>
<i class="fa fa-align-justify handle"></i>
<input type="text" class="form-control" v-model="element.name" />
</div>
<div class="actions">
<q-btn color="primary" icon="bi-list" @click="addItem(element)" />
<q-btn
color="primary"
icon="bi-list-nested"
@click="addNest(element)"
/>
<q-btn color="primary" label="删除" @click="delItem(element)" />
</div>
</div>
<nested-draggable
:tasks="element.tasks"
@onEnd="onEnd"
@addItem="addItem"
@addNest="addNest"
@delItem="delItem"
/>
</div>
</template>
</draggable>
</template>
<script>
import { isEmpty } from 'src/common/utils';
import draggable from 'vuedraggable';
export default {
name: 'nested-draggable',
props: {
tasks: {
required: true,
type: Array,
},
},
components: {
draggable,
},
setup(props, ctx) {
const addItem = (data) => {
ctx.emit('addItem', data);
};
const addNest = (data) => {
ctx.emit('addNest', data);
};
const delItem = (data) => {
ctx.emit('delItem', data);
};
// 拖拽结束
const onEnd = (data) => {
ctx.emit('onEnd', data);
};
return {
isEmpty,
addItem,
addNest,
delItem,
onEnd,
};
},
};
</script>
<style scoped lang="scss">
.drag-area {
min-width: 450px;
// min-height: 20px;
overflow: auto;
/* outline: 1px dashed; */
border: 1px solid red;
padding-left: 40px;
& > :nth-child(1) {
margin-top: 10px;
}
.drag-area-item {
min-width: 450px;
outline: 1px solid #1ee3cf;
margin-bottom: 10px;
.drag-area-item-conten {
height: 40px;
box-sizing: border-box;
background-color: #f9bcdd;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
.actions {
padding: 10px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
column-gap: 10px;
}
}
}
.handle {
float: left;
padding: 8px;
}
}
</style>
...@@ -4,7 +4,7 @@ export default [ ...@@ -4,7 +4,7 @@ export default [
name: 'TREE', name: 'TREE',
component: () => import('./IndexPage.vue'), component: () => import('./IndexPage.vue'),
meta: { meta: {
title: '', title: 'Tree',
permission: ['*'], permission: ['*'],
keepalive: true, keepalive: true,
}, },
......
...@@ -30,7 +30,7 @@ const routes: RouteRecordRaw[] = [ ...@@ -30,7 +30,7 @@ const routes: RouteRecordRaw[] = [
name: 'PAGE1', name: 'PAGE1',
component: () => import('../modules/page1/IndexPage.vue'), component: () => import('../modules/page1/IndexPage.vue'),
meta: { meta: {
title: '页面1', title: '图表',
permission: ['*'], permission: ['*'],
keepalive: true, keepalive: true,
}, },
...@@ -40,7 +40,7 @@ const routes: RouteRecordRaw[] = [ ...@@ -40,7 +40,7 @@ const routes: RouteRecordRaw[] = [
name: 'PAGE2', name: 'PAGE2',
component: () => import('../modules/page2/IndexPage.vue'), component: () => import('../modules/page2/IndexPage.vue'),
meta: { meta: {
title: '页面2', title: '表单',
permission: ['*'], permission: ['*'],
keepalive: true, keepalive: true,
}, },
...@@ -50,7 +50,7 @@ const routes: RouteRecordRaw[] = [ ...@@ -50,7 +50,7 @@ const routes: RouteRecordRaw[] = [
name: 'PAGE4', name: 'PAGE4',
component: () => import('../modules/page4/IndexPage.vue'), component: () => import('../modules/page4/IndexPage.vue'),
meta: { meta: {
title: '页面4', title: 'canvas',
permission: ['*'], permission: ['*'],
keepalive: true, keepalive: true,
}, },
...@@ -60,7 +60,7 @@ const routes: RouteRecordRaw[] = [ ...@@ -60,7 +60,7 @@ const routes: RouteRecordRaw[] = [
name: 'PAGE5', name: 'PAGE5',
component: () => import('../modules/page5/IndexPage.vue'), component: () => import('../modules/page5/IndexPage.vue'),
meta: { meta: {
title: '页面5', title: '防抖节流',
permission: ['*'], permission: ['*'],
keepalive: true, keepalive: true,
}, },
...@@ -70,7 +70,7 @@ const routes: RouteRecordRaw[] = [ ...@@ -70,7 +70,7 @@ const routes: RouteRecordRaw[] = [
name: 'PAGE7', name: 'PAGE7',
component: () => import('../modules/page7/IndexPage.vue'), component: () => import('../modules/page7/IndexPage.vue'),
meta: { meta: {
title: '页面7', title: '疫情防控',
permission: ['*'], permission: ['*'],
keepalive: true, keepalive: true,
}, },
...@@ -90,7 +90,7 @@ const routes: RouteRecordRaw[] = [ ...@@ -90,7 +90,7 @@ const routes: RouteRecordRaw[] = [
name: 'PAGE9', name: 'PAGE9',
component: () => import('../modules/page9/IndexPage.vue'), component: () => import('../modules/page9/IndexPage.vue'),
meta: { meta: {
title: '动画2&表格', title: '表格',
permission: ['*'], permission: ['*'],
keepalive: true, keepalive: true,
}, },
...@@ -110,7 +110,7 @@ const routes: RouteRecordRaw[] = [ ...@@ -110,7 +110,7 @@ const routes: RouteRecordRaw[] = [
name: 'JS_PAGE3', name: 'JS_PAGE3',
component: () => import('../modules/page3/IndexPage.vue'), component: () => import('../modules/page3/IndexPage.vue'),
meta: { meta: {
title: '页面3', title: '链表',
permission: ['*'], permission: ['*'],
keepalive: true, keepalive: true,
}, },
...@@ -120,7 +120,7 @@ const routes: RouteRecordRaw[] = [ ...@@ -120,7 +120,7 @@ const routes: RouteRecordRaw[] = [
name: 'JS_PAGE6', name: 'JS_PAGE6',
component: () => import('../modules/page6/IndexPage.vue'), component: () => import('../modules/page6/IndexPage.vue'),
meta: { meta: {
title: '一些js练习', title: 'JS',
permission: ['*'], permission: ['*'],
keepalive: true, keepalive: true,
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment