mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-28 05:03:31 +08:00
initial commit
This commit is contained in:
0
src/views/demo/.gitkeep
Normal file
0
src/views/demo/.gitkeep
Normal file
89
src/views/demo/comp/button/index.vue
Normal file
89
src/views/demo/comp/button/index.vue
Normal file
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<Alert
|
||||
message="温馨提醒"
|
||||
description="基础组件依赖于 ant-design-vue,组件库已有的基础组件,项目中不会再次进行demo展示(二次封装组件除外)"
|
||||
type="info"
|
||||
show-icon
|
||||
/>
|
||||
|
||||
<Alert message="按钮扩展" type="info" show-icon class="mt-4" />
|
||||
|
||||
<div class="my-2">
|
||||
<h3>success</h3>
|
||||
<a-button color="success">成功</a-button>
|
||||
<a-button color="success" class="ml-2" disabled> 禁用 </a-button>
|
||||
<a-button color="success" class="ml-2" loading> loading </a-button>
|
||||
<a-button color="success" type="link" class="ml-2"> link </a-button>
|
||||
<a-button color="success" type="link" class="ml-2" loading> loading link </a-button>
|
||||
<a-button color="success" type="link" class="ml-2" disabled> disabled link </a-button>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<h3>warning</h3>
|
||||
<a-button color="warning">警告</a-button>
|
||||
<a-button color="warning" class="ml-2" disabled> 禁用 </a-button>
|
||||
<a-button color="warning" class="ml-2" loading> loading </a-button>
|
||||
<a-button color="warning" type="link" class="ml-2"> link </a-button>
|
||||
<a-button color="warning" type="link" class="ml-2" loading> loading link </a-button>
|
||||
<a-button color="warning" type="link" class="ml-2" disabled> disabled link </a-button>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<h3>error</h3>
|
||||
<a-button color="error">错误</a-button>
|
||||
<a-button color="error" class="ml-2" disabled> 禁用 </a-button>
|
||||
<a-button color="error" class="ml-2" loading> loading </a-button>
|
||||
<a-button color="error" type="link" class="ml-2"> link </a-button>
|
||||
<a-button color="error" type="link" class="ml-2" loading> loading link </a-button>
|
||||
<a-button color="error" type="link" class="ml-2" disabled> disabled link </a-button>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<h3>ghost</h3>
|
||||
<a-button ghost>幽灵</a-button>
|
||||
<a-button ghost class="ml-2" disabled> 禁用 </a-button>
|
||||
<a-button ghost class="ml-2" loading> loading </a-button>
|
||||
<a-button ghost type="link" class="ml-2"> link </a-button>
|
||||
<a-button ghost type="link" class="ml-2" loading> loading link </a-button>
|
||||
<a-button ghost type="link" class="ml-2" disabled> disabled link </a-button>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<h3>primary</h3>
|
||||
<a-button type="primary">主按钮</a-button>
|
||||
<a-button type="primary" class="ml-2" disabled> 禁用 </a-button>
|
||||
<a-button type="primary" class="ml-2" loading> loading </a-button>
|
||||
<a-button type="link" class="ml-2"> link </a-button>
|
||||
<a-button type="link" class="ml-2" loading> loading link </a-button>
|
||||
<a-button type="link" class="ml-2" disabled> disabled link </a-button>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<h3>default</h3>
|
||||
<a-button type="default">默认</a-button>
|
||||
<a-button type="default" class="ml-2" disabled> 禁用 </a-button>
|
||||
<a-button type="default" class="ml-2" loading> loading </a-button>
|
||||
<a-button type="link" class="ml-2"> link </a-button>
|
||||
<a-button type="link" class="ml-2" loading> loading link </a-button>
|
||||
<a-button type="link" class="ml-2" disabled> disabled link </a-button>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<h3>dashed</h3>
|
||||
<a-button type="dashed">dashed</a-button>
|
||||
<a-button type="dashed" class="ml-2" disabled> 禁用 </a-button>
|
||||
<a-button type="dashed" class="ml-2" loading> loading </a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Alert } from 'ant-design-vue';
|
||||
export default defineComponent({
|
||||
components: { Alert },
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
32
src/views/demo/comp/click-out-side/index.vue
Normal file
32
src/views/demo/comp/click-out-side/index.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<div class="px-64">
|
||||
<Alert message="点内外部触发事件" show-icon class="mt-4"></Alert>
|
||||
<ClickOutSide @clickOutside="handleClickOutside" class="flex justify-center mt-10">
|
||||
<div
|
||||
@click="innerClick"
|
||||
class="bg-primary w-full h-64 flex justify-center items-center text-2xl text-white rounded-lg shadow-lg"
|
||||
>
|
||||
{{ text }}
|
||||
</div>
|
||||
</ClickOutSide>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { Alert } from 'ant-design-vue';
|
||||
import ClickOutSide from '/@/components/ClickOutSide/index.vue';
|
||||
export default defineComponent({
|
||||
components: { ClickOutSide, Alert },
|
||||
setup() {
|
||||
const text = ref('Click');
|
||||
function handleClickOutside() {
|
||||
text.value = 'Click Out Side';
|
||||
}
|
||||
|
||||
function innerClick() {
|
||||
text.value = 'Click Inner';
|
||||
}
|
||||
return { innerClick, handleClickOutside, text };
|
||||
},
|
||||
});
|
||||
</script>
|
83
src/views/demo/comp/desc/index.vue
Normal file
83
src/views/demo/comp/desc/index.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<Description
|
||||
title="基础示例"
|
||||
:collapseOptions="{ canExpand: true, helpMessage: 'help me' }"
|
||||
:column="3"
|
||||
:data="mockData"
|
||||
:schema="schema"
|
||||
/>
|
||||
|
||||
<Description
|
||||
class="mt-4"
|
||||
title="垂直示例"
|
||||
layout="vertical"
|
||||
:collapseOptions="{ canExpand: true, helpMessage: 'help me' }"
|
||||
:column="2"
|
||||
:data="mockData"
|
||||
:schema="schema"
|
||||
/>
|
||||
|
||||
<Description @register="register" class="mt-4" />
|
||||
<Description @register="register1" class="mt-4" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Alert } from 'ant-design-vue';
|
||||
import { Description, DescItem, useDescription } from '/@/components/Description/index';
|
||||
const mockData: any = {
|
||||
username: 'test',
|
||||
nickName: 'VB',
|
||||
age: 25,
|
||||
phone: '15695909xxx',
|
||||
email: '190848757@qq.com',
|
||||
addr: '厦门市思明区',
|
||||
sex: '男',
|
||||
certy: '3504256199xxxxxxxxx',
|
||||
tag: 'orange',
|
||||
};
|
||||
const schema: DescItem[] = [
|
||||
{
|
||||
field: 'username',
|
||||
label: '用户名',
|
||||
},
|
||||
{
|
||||
field: 'nickName',
|
||||
label: '昵称',
|
||||
render: (curVal, data) => {
|
||||
return `${data.username}-${curVal}`;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'phone',
|
||||
label: '联系电话',
|
||||
},
|
||||
{
|
||||
field: 'email',
|
||||
label: '邮箱',
|
||||
},
|
||||
{
|
||||
field: 'addr',
|
||||
label: '地址',
|
||||
},
|
||||
];
|
||||
export default defineComponent({
|
||||
components: { Description, Alert },
|
||||
setup() {
|
||||
const [register] = useDescription({
|
||||
title: 'useDescription',
|
||||
data: mockData,
|
||||
schema: schema,
|
||||
});
|
||||
|
||||
const [register1] = useDescription({
|
||||
title: '无边框',
|
||||
bordered: false,
|
||||
data: mockData,
|
||||
schema: schema,
|
||||
});
|
||||
return { mockData, schema, register, register1 };
|
||||
},
|
||||
});
|
||||
</script>
|
13
src/views/demo/comp/drawer/Drawer1.vue
Normal file
13
src/views/demo/comp/drawer/Drawer1.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<BasicDrawer v-bind="$attrs" title="Drawer Title" width="50%"> Drawer Info. </BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicDrawer } from '/@/components/Drawer';
|
||||
export default defineComponent({
|
||||
components: { BasicDrawer },
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
17
src/views/demo/comp/drawer/Drawer2.vue
Normal file
17
src/views/demo/comp/drawer/Drawer2.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<BasicDrawer v-bind="$attrs" @register="register" title="Drawer Title" width="50%">
|
||||
Drawer Info.
|
||||
<a-button type="primary" @click="closeDrawer">内部关闭drawer</a-button>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
export default defineComponent({
|
||||
components: { BasicDrawer },
|
||||
setup() {
|
||||
const [register, { closeDrawer }] = useDrawerInner();
|
||||
return { register, closeDrawer };
|
||||
},
|
||||
});
|
||||
</script>
|
15
src/views/demo/comp/drawer/Drawer3.vue
Normal file
15
src/views/demo/comp/drawer/Drawer3.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<BasicDrawer v-bind="$attrs" title="Modal Title" width="50%" showFooter>
|
||||
<p class="h-20" v-for="index in 20" :key="index">根据屏幕高度自适应</p>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicDrawer } from '/@/components/Drawer';
|
||||
export default defineComponent({
|
||||
components: { BasicDrawer },
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
16
src/views/demo/comp/drawer/Drawer4.vue
Normal file
16
src/views/demo/comp/drawer/Drawer4.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<BasicDrawer v-bind="$attrs" @register="register" title="Drawer Title" width="50%">
|
||||
<p class="h-20">外部传递数据: {{ receiveDrawerDataRef }}</p>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
export default defineComponent({
|
||||
components: { BasicDrawer },
|
||||
setup() {
|
||||
const [register, { receiveDrawerDataRef }] = useDrawerInner();
|
||||
return { register, receiveDrawerDataRef };
|
||||
},
|
||||
});
|
||||
</script>
|
15
src/views/demo/comp/drawer/Drawer5.vue
Normal file
15
src/views/demo/comp/drawer/Drawer5.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<BasicDrawer v-bind="$attrs" :drawerType="DrawerType.DETAIL" title="Drawer Title5">
|
||||
<p class="h-20">Content Message</p>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicDrawer, DrawerType } from '/@/components/Drawer';
|
||||
export default defineComponent({
|
||||
components: { BasicDrawer },
|
||||
setup() {
|
||||
return { DrawerType };
|
||||
},
|
||||
});
|
||||
</script>
|
73
src/views/demo/comp/drawer/index.vue
Normal file
73
src/views/demo/comp/drawer/index.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div class="px-10">
|
||||
<Alert message="使用 useDrawer 进行抽屉操作" show-icon class="my-4" />
|
||||
<a-button type="primary" class="mr-2" @click="openDrawerLoading">打开Drawer</a-button>
|
||||
|
||||
<Alert message="内外同时同时显示隐藏" show-icon class="my-4" />
|
||||
<a-button type="primary" class="mr-2" @click="openDrawer2">打开Drawer</a-button>
|
||||
<Alert message="自适应高度/显示footer" show-icon class="my-4" />
|
||||
<a-button type="primary" class="mr-2" @click="openDrawer3">打开Drawer</a-button>
|
||||
|
||||
<Alert
|
||||
message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式"
|
||||
show-icon
|
||||
class="my-4"
|
||||
/>
|
||||
<a-button type="primary" class="mr-2" @click="send">打开Drawer并传递数据</a-button>
|
||||
<Alert message="详情页模式" show-icon class="my-4" />
|
||||
<a-button type="primary" class="mr-2" @click="openDrawer5">打开详情Drawer</a-button>
|
||||
<Drawer1 @register="register1" />
|
||||
<Drawer2 @register="register2" />
|
||||
<Drawer3 @register="register3" />
|
||||
<Drawer4 @register="register4" />
|
||||
<Drawer5 @register="register5" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Alert } from 'ant-design-vue';
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import Drawer1 from './Drawer1.vue';
|
||||
import Drawer2 from './Drawer2.vue';
|
||||
import Drawer3 from './Drawer3.vue';
|
||||
import Drawer4 from './Drawer4.vue';
|
||||
import Drawer5 from './Drawer5.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: { Alert, Drawer1, Drawer2, Drawer3, Drawer4, Drawer5 },
|
||||
setup() {
|
||||
const [register1, { openDrawer: openDrawer1, setDrawerProps }] = useDrawer();
|
||||
const [register2, { openDrawer: openDrawer2 }] = useDrawer();
|
||||
const [register3, { openDrawer: openDrawer3 }] = useDrawer();
|
||||
const [register4, { openDrawer: openDrawer4, transferDrawerData }] = useDrawer();
|
||||
const [register5, { openDrawer: openDrawer5 }] = useDrawer();
|
||||
function send() {
|
||||
transferDrawerData({
|
||||
data: 'content',
|
||||
info: 'Info',
|
||||
});
|
||||
openDrawer4(true);
|
||||
}
|
||||
function openDrawerLoading() {
|
||||
openDrawer1();
|
||||
setDrawerProps({ loading: true });
|
||||
setTimeout(() => {
|
||||
setDrawerProps({ loading: false });
|
||||
}, 2000);
|
||||
}
|
||||
return {
|
||||
register1,
|
||||
openDrawer1,
|
||||
register2,
|
||||
openDrawer2,
|
||||
register3,
|
||||
openDrawer3,
|
||||
register4,
|
||||
register5,
|
||||
openDrawer5,
|
||||
send,
|
||||
openDrawerLoading,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
70
src/views/demo/comp/icon/index.vue
Normal file
70
src/views/demo/comp/icon/index.vue
Normal file
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div class="m-4">
|
||||
<CollapseContainer title="Antv Icon使用 (直接按需引入相应组件即可)">
|
||||
<div class="flex justify-around">
|
||||
<GithubFilled :style="{ fontSize: '30px' }" />
|
||||
<QqCircleFilled :style="{ fontSize: '30px' }" />
|
||||
<WechatFilled :style="{ fontSize: '30px' }" />
|
||||
<AlipayCircleFilled :style="{ fontSize: '30px' }" />
|
||||
<IeCircleFilled :style="{ fontSize: '30px' }" />
|
||||
<TaobaoCircleFilled :style="{ fontSize: '30px' }" />
|
||||
<CodepenCircleFilled :style="{ fontSize: '30px' }" />
|
||||
</div>
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer title="IconIfy 组件使用" class="mt-5">
|
||||
<div class="flex justify-around flex-wrap">
|
||||
<Icon icon="fa-solid:address-book" :size="30" />
|
||||
<Icon icon="mdi-light:bank" :size="30" />
|
||||
<Icon icon="jam:alien-f" :size="30" />
|
||||
<Icon icon="jam:android" :size="30" />
|
||||
</div>
|
||||
</CollapseContainer>
|
||||
|
||||
<Alert
|
||||
show-icon
|
||||
class="mt-5"
|
||||
message="推荐使用Iconify组件"
|
||||
description="Icon组件基本包含所有的图标,在下面网址内你可以查询到你想要的任何图标。并且打包只会打包所用到的图标。唯一不足的可能就是需要连接外网进行使用。"
|
||||
/>
|
||||
<a-button type="link" @click="toIconify">Iconify 图标大全</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { Alert } from 'ant-design-vue';
|
||||
import {
|
||||
QqCircleFilled,
|
||||
GithubFilled,
|
||||
WechatFilled,
|
||||
AlipayCircleFilled,
|
||||
IeCircleFilled,
|
||||
TaobaoCircleFilled,
|
||||
CodepenCircleFilled,
|
||||
} from '@ant-design/icons-vue';
|
||||
|
||||
import Icon from '/@/components/Icon/index';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
CollapseContainer,
|
||||
GithubFilled,
|
||||
QqCircleFilled,
|
||||
WechatFilled,
|
||||
AlipayCircleFilled,
|
||||
IeCircleFilled,
|
||||
TaobaoCircleFilled,
|
||||
CodepenCircleFilled,
|
||||
Icon,
|
||||
Alert,
|
||||
},
|
||||
setup() {
|
||||
return {
|
||||
toIconify: () => {
|
||||
window.open('https://iconify.design/', '__blank');
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
15
src/views/demo/comp/modal/Modal1.vue
Normal file
15
src/views/demo/comp/modal/Modal1.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" title="Modal Title" :helpMessage="['提示1', '提示2']">
|
||||
Modal Info.
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicModal } from '/@/components/Modal';
|
||||
export default defineComponent({
|
||||
components: { BasicModal },
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
29
src/views/demo/comp/modal/Modal2.vue
Normal file
29
src/views/demo/comp/modal/Modal2.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
@register="register"
|
||||
title="Modal Title"
|
||||
:helpMessage="['提示1', '提示2']"
|
||||
>
|
||||
<a-button type="primary" @click="closeModal" class="mr-2">从内部关闭弹窗</a-button>
|
||||
|
||||
<a-button type="primary" @click="setModalProps">从内部修改title</a-button>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
export default defineComponent({
|
||||
components: { BasicModal },
|
||||
setup() {
|
||||
const [register, { closeModal, setModalProps }] = useModalInner();
|
||||
return {
|
||||
register,
|
||||
closeModal,
|
||||
setModalProps: () => {
|
||||
setModalProps({ title: 'Modal New Title' });
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
15
src/views/demo/comp/modal/Modal3.vue
Normal file
15
src/views/demo/comp/modal/Modal3.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" title="Modal Title" :helpMessage="['提示1', '提示2']" width="700px">
|
||||
<p class="h-20" v-for="index in 20" :key="index">根据屏幕高度自适应</p>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicModal } from '/@/components/Modal';
|
||||
export default defineComponent({
|
||||
components: { BasicModal },
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
16
src/views/demo/comp/modal/Modal4.vue
Normal file
16
src/views/demo/comp/modal/Modal4.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="register" title="Modal Title">
|
||||
<p class="h-20">外部传递数据: {{ receiveModalDataRef }}</p>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
export default defineComponent({
|
||||
components: { BasicModal },
|
||||
setup() {
|
||||
const [register, { receiveModalDataRef }] = useModalInner();
|
||||
return { register, receiveModalDataRef };
|
||||
},
|
||||
});
|
||||
</script>
|
74
src/views/demo/comp/modal/index.vue
Normal file
74
src/views/demo/comp/modal/index.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div class="px-10">
|
||||
<Alert
|
||||
message="使用 useModal 进行弹窗操作,默认可以拖动,可以通过 draggable
|
||||
参数进行控制是否可以拖动/全屏"
|
||||
show-icon
|
||||
class="my-4"
|
||||
/>
|
||||
<a-button type="primary" class="mr-2" @click="openModalLoading"
|
||||
>打开弹窗 默认可以拖动/全屏</a-button
|
||||
>
|
||||
|
||||
<Alert message="内外同时同时显示隐藏" show-icon class="my-4" />
|
||||
<a-button type="primary" class="mr-2" @click="openModal2">打开弹窗</a-button>
|
||||
<Alert message="自适应高度" show-icon class="my-4" />
|
||||
<a-button type="primary" class="mr-2" @click="openModal3">打开弹窗</a-button>
|
||||
|
||||
<Alert
|
||||
message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式"
|
||||
show-icon
|
||||
class="my-4"
|
||||
/>
|
||||
<a-button type="primary" class="mr-2" @click="send">打开弹窗并传递数据</a-button>
|
||||
|
||||
<Modal1 @register="register1" />
|
||||
<Modal2 @register="register2" />
|
||||
<Modal3 @register="register3" />
|
||||
<Modal4 @register="register4" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Alert } from 'ant-design-vue';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import Modal1 from './Modal1.vue';
|
||||
import Modal2 from './Modal2.vue';
|
||||
import Modal3 from './Modal3.vue';
|
||||
import Modal4 from './Modal4.vue';
|
||||
export default defineComponent({
|
||||
components: { Alert, Modal1, Modal2, Modal3, Modal4 },
|
||||
setup() {
|
||||
const [register1, { openModal: openModal1, setModalProps }] = useModal();
|
||||
const [register2, { openModal: openModal2 }] = useModal();
|
||||
const [register3, { openModal: openModal3 }] = useModal();
|
||||
const [register4, { openModal: openModal4, transferModalData }] = useModal();
|
||||
function send() {
|
||||
transferModalData({
|
||||
data: 'content',
|
||||
info: 'Info',
|
||||
});
|
||||
openModal4(true);
|
||||
}
|
||||
function openModalLoading() {
|
||||
openModal1();
|
||||
setModalProps({ loading: true });
|
||||
setTimeout(() => {
|
||||
setModalProps({ loading: false });
|
||||
}, 2000);
|
||||
}
|
||||
return {
|
||||
register1,
|
||||
openModal1,
|
||||
register2,
|
||||
openModal2,
|
||||
register3,
|
||||
openModal3,
|
||||
register4,
|
||||
openModal4,
|
||||
send,
|
||||
openModalLoading,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
87
src/views/demo/comp/qrcode/index.vue
Normal file
87
src/views/demo/comp/qrcode/index.vue
Normal file
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<div class="p-4 flex flex-wrap">
|
||||
<CollapseContainer title="基础示例" :canExpan="true" class="text-center mb-6 qrcode-demo-item">
|
||||
<QrCode :value="qrCodeUrl" />
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer title="渲染成img标签示例" class="text-center mb-6 qrcode-demo-item">
|
||||
<QrCode :value="qrCodeUrl" tag="img" />
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer title="配置样式示例" class="text-center mb-6 qrcode-demo-item">
|
||||
<QrCode
|
||||
:value="qrCodeUrl"
|
||||
:options="{
|
||||
color: { dark: '#55D187' },
|
||||
}"
|
||||
/>
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer title="本地logo示例" class="text-center mb-6 qrcode-demo-item">
|
||||
<QrCode :value="qrCodeUrl" :logo="LogoImg" />
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer title="在线logo示例" class="text-center mb-6 qrcode-demo-item">
|
||||
<QrCode
|
||||
:value="qrCodeUrl"
|
||||
logo="https://vebn.oss-cn-beijing.aliyuncs.com/vben/logo.png"
|
||||
:options="{
|
||||
color: { dark: '#55D187' },
|
||||
}"
|
||||
/>
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer title="logo配置示例" class="text-center mb-6 qrcode-demo-item">
|
||||
<QrCode
|
||||
:value="qrCodeUrl"
|
||||
:logo="{
|
||||
src: 'https://vebn.oss-cn-beijing.aliyuncs.com/vben/logo.png',
|
||||
logoSize: 0.2,
|
||||
borderSize: 0.05,
|
||||
borderRadius: 50,
|
||||
bgColor: 'blue',
|
||||
}"
|
||||
/>
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer title="下载示例" class="text-center qrcode-demo-item">
|
||||
<QrCode :value="qrCodeUrl" ref="qrRef" :logo="LogoImg" />
|
||||
<a-button class="mb-2" type="primary" @click="download"> 下载 </a-button>
|
||||
<div class="msg">(在线logo会导致图片跨域,需要下载图片需要自行解决跨域问题)</div>
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer title="配置大小示例" class="text-center qrcode-demo-item">
|
||||
<QrCode :value="qrCodeUrl" :width="300" />
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, unref } from 'vue';
|
||||
import { QrCode, QrCodeActionType } from '/@/components/Qrcode/index';
|
||||
import LogoImg from '/@/assets/images/logo.png';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
const qrCodeUrl = 'https://www.vvbin.cn';
|
||||
export default defineComponent({
|
||||
components: { CollapseContainer, QrCode },
|
||||
setup() {
|
||||
const qrRef = ref<Nullable<QrCodeActionType>>(null);
|
||||
function download() {
|
||||
const qrEl = unref(qrRef);
|
||||
if (!qrEl) return;
|
||||
qrEl.download('文件名');
|
||||
}
|
||||
return {
|
||||
qrCodeUrl,
|
||||
LogoImg,
|
||||
download,
|
||||
qrRef,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
.qrcode-demo-item {
|
||||
width: 30%;
|
||||
margin-right: 1%;
|
||||
}
|
||||
</style>
|
52
src/views/demo/comp/scroll/Action.vue
Normal file
52
src/views/demo/comp/scroll/Action.vue
Normal file
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<Alert message="抽取el-scrollbar,并对其进行扩展,滚动条美化,适用于各个浏览器" type="info" />
|
||||
|
||||
<div class="my-4">
|
||||
<a-button @click="scrollTo(100)" class="mr-2">滚动到100px位置</a-button>
|
||||
<a-button @click="scrollTo(800)" class="mr-2">滚动到800px位置</a-button>
|
||||
<a-button @click="scrollTo(0)" class="mr-2">滚动到顶部</a-button>
|
||||
<a-button @click="scrollBottom()" class="mr-2">滚动到底部</a-button>
|
||||
</div>
|
||||
<div class="w-1/2 h-64 bg-white">
|
||||
<ScrollContainer class="mt-4" ref="scrollRef">
|
||||
<ul class="p-3">
|
||||
<template v-for="index in 100" :key="index">
|
||||
<li class="leading-8 px-2" :style="{ border: '1px solid #eee' }">{{ index }}</li>
|
||||
</template>
|
||||
</ul>
|
||||
</ScrollContainer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, unref } from 'vue';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { ScrollContainer, ScrollActionType } from '/@/components/Container/index';
|
||||
import { Alert } from 'ant-design-vue';
|
||||
export default defineComponent({
|
||||
components: { CollapseContainer, ScrollContainer, Alert },
|
||||
setup() {
|
||||
const scrollRef = ref<Nullable<ScrollActionType>>(null);
|
||||
const getScroll = () => {
|
||||
const scroll = unref(scrollRef);
|
||||
if (!scroll) {
|
||||
throw new Error('scroll is Null');
|
||||
}
|
||||
return scroll;
|
||||
};
|
||||
|
||||
function scrollTo(top: number) {
|
||||
getScroll().scrollTo(top);
|
||||
}
|
||||
function scrollBottom() {
|
||||
getScroll().scrollBottom();
|
||||
}
|
||||
return {
|
||||
scrollTo,
|
||||
scrollRef,
|
||||
scrollBottom,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
59
src/views/demo/comp/scroll/VirtualScroll.vue
Normal file
59
src/views/demo/comp/scroll/VirtualScroll.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<div class="p-4 virtual-scroll-demo">
|
||||
<Divider>基础滚动示例</Divider>
|
||||
<div class="virtual-scroll-demo-wrap">
|
||||
<VirtualScroll :itemHeight="41" :items="data" :height="300" :width="300">
|
||||
<template v-slot="{ item }">
|
||||
<div class="virtual-scroll-demo__item">{{ item.title }}</div>
|
||||
</template>
|
||||
</VirtualScroll>
|
||||
</div>
|
||||
|
||||
<Divider>即使不可见,也预先加载30条数据,防止空白</Divider>
|
||||
<div class="virtual-scroll-demo-wrap">
|
||||
<VirtualScroll :itemHeight="41" :items="data" :height="300" :width="300" :bench="30">
|
||||
<template v-slot="{ item }">
|
||||
<div class="virtual-scroll-demo__item">{{ item.title }}</div>
|
||||
</template>
|
||||
</VirtualScroll>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { VirtualScroll } from '/@/components/VirtualScroll/index';
|
||||
|
||||
import { Divider } from 'ant-design-vue';
|
||||
const data: any[] = (() => {
|
||||
const arr: any[] = [];
|
||||
for (let index = 1; index < 20000; index++) {
|
||||
arr.push({
|
||||
title: '列表项' + index,
|
||||
});
|
||||
}
|
||||
return arr;
|
||||
})();
|
||||
export default defineComponent({
|
||||
components: { VirtualScroll, Divider },
|
||||
setup() {
|
||||
return { data: data };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.virtual-scroll-demo {
|
||||
&-wrap {
|
||||
display: flex;
|
||||
margin: 0 30%;
|
||||
background: #fff;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/deep/ &__item {
|
||||
height: 40px;
|
||||
padding: 0 20px;
|
||||
line-height: 40px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
}
|
||||
</style>
|
26
src/views/demo/comp/scroll/index.vue
Normal file
26
src/views/demo/comp/scroll/index.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<Alert message="抽取el-scrollbar,并对其进行扩展,滚动条美化,适用于各个浏览器" type="info" />
|
||||
<div class="w-1/2 h-64 bg-white">
|
||||
<ScrollContainer class="mt-4">
|
||||
<ul class="p-3">
|
||||
<template v-for="index in 100" :key="index">
|
||||
<li class="leading-8 px-2" :style="{ border: '1px solid #eee' }">{{ index }}</li>
|
||||
</template>
|
||||
</ul>
|
||||
</ScrollContainer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { ScrollContainer } from '/@/components/Container/index';
|
||||
import { Alert } from 'ant-design-vue';
|
||||
export default defineComponent({
|
||||
components: { CollapseContainer, ScrollContainer, Alert },
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
23
src/views/demo/comp/strength-meter/index.vue
Normal file
23
src/views/demo/comp/strength-meter/index.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div class="p-4 flex justify-center">
|
||||
<div class="w-1/2 bg-white p-10 rounded-md">
|
||||
<StrengthMeter placeholder="默认" />
|
||||
<StrengthMeter placeholder="禁用" disabled />
|
||||
<br />
|
||||
<StrengthMeter placeholder="隐藏input" :show-input="false" value="!@#qwe12345" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import StrengthMeter from '/@/components/StrengthMeter/index';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
StrengthMeter,
|
||||
},
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
</script>
|
23
src/views/demo/comp/verify/Rotate.vue
Normal file
23
src/views/demo/comp/verify/Rotate.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div class="p-10">
|
||||
<div class="flex justify-center p-4 items-center bg-gray-700">
|
||||
<RotateDragVerify src="/@/assets/images/header.jpg" ref="el" @success="handleSuccess" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { RotateDragVerify } from '/@/components/Verify/index';
|
||||
|
||||
export default defineComponent({
|
||||
components: { RotateDragVerify },
|
||||
setup() {
|
||||
const handleSuccess = () => {
|
||||
console.log('success!');
|
||||
};
|
||||
return {
|
||||
handleSuccess,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
90
src/views/demo/comp/verify/index.vue
Normal file
90
src/views/demo/comp/verify/index.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<div class="p-10">
|
||||
<div class="flex justify-center p-4 items-center bg-gray-700">
|
||||
<BasicDragVerify ref="el1" @success="handleSuccess" />
|
||||
<a-button color="primary" class="ml-2" @click="handleBtnClick(el1)">还原</a-button>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center p-4 items-center bg-gray-700">
|
||||
<BasicDragVerify ref="el2" @success="handleSuccess" circle />
|
||||
<a-button color="primary" class="ml-2" @click="handleBtnClick(el2)">还原</a-button>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center p-4 items-center bg-gray-700">
|
||||
<BasicDragVerify
|
||||
ref="el3"
|
||||
@success="handleSuccess"
|
||||
text="拖动以进行校验"
|
||||
successText="校验成功"
|
||||
:barStyle="{
|
||||
background: '#018ffb',
|
||||
}"
|
||||
/>
|
||||
<a-button color="primary" class="ml-2" @click="handleBtnClick(el3)">还原</a-button>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center p-4 items-center bg-gray-700">
|
||||
<BasicDragVerify ref="el4" @success="handleSuccess">
|
||||
<template v-slot:actionIcon="isPassing">
|
||||
<BugOutlined v-if="isPassing" />
|
||||
<RightOutlined v-else />
|
||||
</template>
|
||||
</BasicDragVerify>
|
||||
<a-button color="primary" class="ml-2" @click="handleBtnClick(el4)">还原</a-button>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center p-4 items-center bg-gray-700">
|
||||
<BasicDragVerify ref="el5" @success="handleSuccess">
|
||||
<template v-slot:text="isPassing">
|
||||
<div v-if="isPassing">
|
||||
<BugOutlined />
|
||||
成功
|
||||
</div>
|
||||
<div v-else>
|
||||
拖动
|
||||
<RightOutlined />
|
||||
</div>
|
||||
</template>
|
||||
</BasicDragVerify>
|
||||
<a-button color="primary" class="ml-2" @click="handleBtnClick(el5)">还原</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { BasicDragVerify, DragVerifyActionType, PassingData } from '/@/components/Verify/index';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { BugOutlined, RightOutlined } from '@ant-design/icons-vue';
|
||||
export default defineComponent({
|
||||
components: { BasicDragVerify, BugOutlined, RightOutlined },
|
||||
setup() {
|
||||
const { createMessage } = useMessage();
|
||||
const el1 = ref<RefInstanceType<DragVerifyActionType>>(null);
|
||||
const el2 = ref<RefInstanceType<DragVerifyActionType>>(null);
|
||||
const el3 = ref<RefInstanceType<DragVerifyActionType>>(null);
|
||||
const el4 = ref<RefInstanceType<DragVerifyActionType>>(null);
|
||||
const el5 = ref<RefInstanceType<DragVerifyActionType>>(null);
|
||||
|
||||
function handleSuccess(data: PassingData) {
|
||||
const { time } = data;
|
||||
createMessage.success(`校验成功,耗时${time}秒`);
|
||||
}
|
||||
|
||||
function handleBtnClick(elRef: RefInstanceType<DragVerifyActionType>) {
|
||||
if (!elRef) {
|
||||
return;
|
||||
}
|
||||
elRef.$.resume();
|
||||
}
|
||||
return {
|
||||
handleSuccess,
|
||||
el1,
|
||||
el2,
|
||||
el3,
|
||||
el4,
|
||||
el5,
|
||||
handleBtnClick,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
42
src/views/demo/feat/context-menu/index.vue
Normal file
42
src/views/demo/feat/context-menu/index.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<CollapseContainer title="Simple">
|
||||
<a-button type="primary" @contextmenu="handleContext">Right Click on me</a-button>
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { useContextMenu } from '/@/hooks/web/useContextMenu';
|
||||
import { CollapseContainer } from '/@/components/Container';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
export default defineComponent({
|
||||
components: { CollapseContainer },
|
||||
setup() {
|
||||
const [createContextMenu] = useContextMenu();
|
||||
const { createMessage } = useMessage();
|
||||
function handleContext(e: MouseEvent) {
|
||||
createContextMenu({
|
||||
event: e,
|
||||
items: [
|
||||
{
|
||||
label: 'New',
|
||||
icon: 'ant-design:plus-outlined',
|
||||
handler: () => {
|
||||
createMessage.success('click new');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Open',
|
||||
icon: 'ant-design:folder-open-filled',
|
||||
handler: () => {
|
||||
createMessage.success('click open');
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
return { handleContext };
|
||||
},
|
||||
});
|
||||
</script>
|
38
src/views/demo/feat/copy/index.vue
Normal file
38
src/views/demo/feat/copy/index.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<CollapseContainer class="px-20 bg-white w-full h-32 rounded-md" title="Copy Example">
|
||||
<div class="flex justify-center">
|
||||
<a-input placeholder="请输入" v-model:value="value" />
|
||||
<a-button type="primary" @click="handleCopy">Copy</a-button>
|
||||
</div>
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, unref, ref } from 'vue';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
export default defineComponent({
|
||||
components: { CollapseContainer },
|
||||
setup() {
|
||||
const valueRef = ref('');
|
||||
const { createMessage } = useMessage();
|
||||
const { clipboardRef, copiedRef } = useCopyToClipboard();
|
||||
|
||||
function handleCopy() {
|
||||
const value = unref(valueRef);
|
||||
if (!value) {
|
||||
createMessage.warning('请输入要拷贝的内容!');
|
||||
return;
|
||||
}
|
||||
clipboardRef.value = value;
|
||||
if (unref(copiedRef)) {
|
||||
createMessage.warning('copy success!');
|
||||
}
|
||||
}
|
||||
return { handleCopy, value: valueRef };
|
||||
},
|
||||
});
|
||||
</script>
|
56
src/views/demo/feat/full-screen/index.vue
Normal file
56
src/views/demo/feat/full-screen/index.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<CollapseContainer class="px-20 bg-white w-full h-32 rounded-md" title="Window Full Screen">
|
||||
<a-button type="primary" @click="enterFullscreen" class="mr-2">
|
||||
Enter Window Full Screen
|
||||
</a-button>
|
||||
<a-button color="success" @click="toggleFullscreen" class="mr-2">
|
||||
Toggle Window Full Screen
|
||||
</a-button>
|
||||
|
||||
<a-button color="error" @click="exitFullscreen" class="mr-2">
|
||||
Exit Window Full Screen
|
||||
</a-button>
|
||||
|
||||
Current State: {{ isFullscreenRef }}
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer class="px-20 bg-white w-full h-32 rounded-md mt-5" title="Dom Full Screen">
|
||||
<a-button type="primary" @click="toggleDom" class="mr-2"> Enter Dom Full Screen </a-button>
|
||||
</CollapseContainer>
|
||||
|
||||
<div
|
||||
ref="domRef"
|
||||
class="w-1/2 h-64 flex justify-center rounded-md items-center bg-white mx-auto mt-10"
|
||||
>
|
||||
<a-button type="primary" @click="toggleDom" class="mr-2"> Exit Dom Full Screen </a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { useFullscreen } from '/@/hooks/web/useFullScreen';
|
||||
export default defineComponent({
|
||||
components: { CollapseContainer },
|
||||
setup() {
|
||||
const domRef = ref<Nullable<HTMLElement>>(null);
|
||||
const {
|
||||
enterFullscreen,
|
||||
toggleFullscreen,
|
||||
isFullscreenRef,
|
||||
exitFullscreen,
|
||||
} = useFullscreen();
|
||||
|
||||
const { toggleFullscreen: toggleDom } = useFullscreen(domRef);
|
||||
return {
|
||||
enterFullscreen,
|
||||
toggleDom,
|
||||
toggleFullscreen,
|
||||
isFullscreenRef,
|
||||
exitFullscreen,
|
||||
domRef,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
38
src/views/demo/feat/i18n/index.vue
Normal file
38
src/views/demo/feat/i18n/index.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<Alert message="国际化方式,没有进行全局国际化,有需要可以自行处理。" type="info" />
|
||||
<Divider />
|
||||
国际化信息: {{ t('hello') }}
|
||||
<Divider />
|
||||
<a-button :type="localeRef === 'zhCN' ? 'primary' : ''" @click="localeRef = 'zhCN'">
|
||||
中文
|
||||
</a-button>
|
||||
<a-button :type="localeRef === 'en' ? 'primary' : ''" @click="localeRef = 'en'">
|
||||
英文
|
||||
</a-button>
|
||||
<Divider />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Alert, Divider } from 'ant-design-vue';
|
||||
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
export default defineComponent({
|
||||
components: { Alert, Divider },
|
||||
setup() {
|
||||
const { t, localeRef } = useI18n({
|
||||
locale: 'zhCN',
|
||||
messages: {
|
||||
en: {
|
||||
hello: 'hello',
|
||||
},
|
||||
zhCN: {
|
||||
hello: '你好',
|
||||
},
|
||||
},
|
||||
});
|
||||
return { localeRef, t };
|
||||
},
|
||||
});
|
||||
</script>
|
27
src/views/demo/feat/img-preview/index.vue
Normal file
27
src/views/demo/feat/img-preview/index.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<Alert message="有预览图" type="info" />
|
||||
<div class="flex justify-center mt-4">
|
||||
<img :src="img" v-for="img in imgList" :key="img" class="mr-2" @click="handleClick(img)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Alert } from 'ant-design-vue';
|
||||
import { createImgPreview } from '/@/components/Preview/index';
|
||||
const imgList: string[] = [
|
||||
'https://picsum.photos/id/66/346/216',
|
||||
'https://picsum.photos/id/67/346/216',
|
||||
'https://picsum.photos/id/68/346/216',
|
||||
];
|
||||
export default defineComponent({
|
||||
components: { Alert },
|
||||
setup() {
|
||||
function handleClick(img: string) {
|
||||
createImgPreview({ imageList: [img] });
|
||||
}
|
||||
return { imgList, handleClick };
|
||||
},
|
||||
});
|
||||
</script>
|
97
src/views/demo/feat/msg/index.vue
Normal file
97
src/views/demo/feat/msg/index.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<CollapseContainer class="px-20 bg-white w-full h-32 rounded-md" title="Message">
|
||||
<a-button @click="infoMsg('Info message')" class="mr-2">Info</a-button>
|
||||
<a-button @click="successMsg('Success message')" class="mr-2" color="success">
|
||||
Success
|
||||
</a-button>
|
||||
<a-button @click="warningMsg('Warning message')" class="mr-2" color="warning">
|
||||
Warning
|
||||
</a-button>
|
||||
<a-button @click="errorMsg('Error message')" class="mr-2" color="error"> Error </a-button>
|
||||
<a-button @click="handleLoading" class="mr-2" type="primary"> Loading </a-button>
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer class="px-20 bg-white w-full h-32 rounded-md mt-5" title="Comfirm">
|
||||
<a-button @click="handleConfirm('warning')" color="warning" class="mr-2">Warning</a-button>
|
||||
<a-button @click="handleConfirm('success')" color="success" class="mr-2">Success</a-button>
|
||||
<a-button @click="handleConfirm('error')" color="error" class="mr-2">Error</a-button>
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer class="px-20 bg-white w-full h-32 rounded-md mt-5" title="Modal">
|
||||
<a-button @click="handleInfoModal" class="mr-2">Info</a-button>
|
||||
<a-button @click="handleSuccessModal" color="success" class="mr-2">Success</a-button>
|
||||
<a-button @click="handleErrorModal" color="error" class="mr-2">Error</a-button>
|
||||
<a-button @click="handleWarningModal" color="warning" class="mr-2">Warning</a-button>
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer
|
||||
class="px-20 bg-white w-full h-32 rounded-md mt-5"
|
||||
title="Notification 用法与上面一致"
|
||||
>
|
||||
<a-button @click="handleNotify" color="success" class="mr-2">Success</a-button>
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
export default defineComponent({
|
||||
components: { CollapseContainer },
|
||||
setup() {
|
||||
const {
|
||||
createMessage,
|
||||
createConfirm,
|
||||
createSuccessModal,
|
||||
createInfoModal,
|
||||
createErrorModal,
|
||||
createWarningModal,
|
||||
notification,
|
||||
} = useMessage();
|
||||
const { info, success, warning, error } = createMessage;
|
||||
|
||||
function handleLoading() {
|
||||
createMessage.loading('Loading...');
|
||||
}
|
||||
function handleConfirm(type: 'warning' | 'error' | 'success') {
|
||||
createConfirm({
|
||||
iconType: type,
|
||||
title: 'Tip',
|
||||
content: 'content message...',
|
||||
});
|
||||
}
|
||||
function handleSuccessModal() {
|
||||
createSuccessModal({ title: 'Tip', content: 'content message...' });
|
||||
}
|
||||
function handleErrorModal() {
|
||||
createErrorModal({ title: 'Tip', content: 'content message...' });
|
||||
}
|
||||
function handleWarningModal() {
|
||||
createWarningModal({ title: 'Tip', content: 'content message...' });
|
||||
}
|
||||
function handleInfoModal() {
|
||||
createInfoModal({ title: 'Tip', content: 'content message...' });
|
||||
}
|
||||
function handleNotify() {
|
||||
notification.success({
|
||||
message: 'Tip',
|
||||
description: 'content message...',
|
||||
});
|
||||
}
|
||||
return {
|
||||
infoMsg: info,
|
||||
successMsg: success,
|
||||
warningMsg: warning,
|
||||
errorMsg: error,
|
||||
handleLoading,
|
||||
handleConfirm,
|
||||
handleSuccessModal,
|
||||
handleErrorModal,
|
||||
handleWarningModal,
|
||||
handleInfoModal,
|
||||
handleNotify,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
32
src/views/demo/feat/tabs/index.vue
Normal file
32
src/views/demo/feat/tabs/index.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<CollapseContainer
|
||||
class="px-20 bg-white w-full h-32 rounded-md"
|
||||
title="在下面输入框输入文本,切换后回来内容会保存"
|
||||
>
|
||||
<a-input placeholder="请输入" />
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer class="px-20 mt-10 bg-white w-full h-32 rounded-md" title="标签页操作">
|
||||
<a-button class="mr-2" @click="closeAll">关闭所有</a-button>
|
||||
<a-button class="mr-2" @click="closeLeft">关闭左侧</a-button>
|
||||
<a-button class="mr-2" @click="closeRight">关闭右侧</a-button>
|
||||
<a-button class="mr-2" @click="closeOther">关闭其他</a-button>
|
||||
<a-button class="mr-2" @click="closeCurrent">关闭当前</a-button>
|
||||
<a-button class="mr-2" @click="refreshPage">刷新当前</a-button>
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { useTabs } from '/@/hooks/web/useTabs';
|
||||
export default defineComponent({
|
||||
name: 'TabsDemo',
|
||||
components: { CollapseContainer },
|
||||
setup() {
|
||||
const { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage } = useTabs();
|
||||
return { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage };
|
||||
},
|
||||
});
|
||||
</script>
|
31
src/views/demo/feat/watermark/index.vue
Normal file
31
src/views/demo/feat/watermark/index.vue
Normal file
@@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<CollapseContainer class="px-20 bg-white w-full h-32 rounded-md" title="Global WaterMark">
|
||||
<a-button type="primary" class="mr-2" @click="setWatermark('WaterMark Info')">
|
||||
Create
|
||||
</a-button>
|
||||
<a-button color="error" class="mr-2" @click="clear">Clear</a-button>
|
||||
<a-button color="warning" class="mr-2" @click="setWatermark('WaterMark Info New')">
|
||||
Reset
|
||||
</a-button>
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { useWatermark } from '/@/hooks/web/useWatermark';
|
||||
|
||||
export default defineComponent({
|
||||
components: { CollapseContainer },
|
||||
setup() {
|
||||
const areaRef = ref<Nullable<HTMLElement>>(null);
|
||||
const { setWatermark, clear } = useWatermark();
|
||||
return {
|
||||
setWatermark,
|
||||
clear,
|
||||
areaRef,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
178
src/views/demo/form/AdvancedForm.vue
Normal file
178
src/views/demo/form/AdvancedForm.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div class="m-4">
|
||||
<div class="mb-4"> </div>
|
||||
<CollapseContainer title="基础收缩示例">
|
||||
<BasicForm @register="register" />
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer title="超过3行自动收起" class="mt-4">
|
||||
<BasicForm @register="register1" />
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
|
||||
const getSchamas = (): FormSchema[] => {
|
||||
return [
|
||||
{
|
||||
field: 'field1',
|
||||
component: 'Input',
|
||||
label: '字段1',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: '自定义placeholder',
|
||||
onChange: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field2',
|
||||
component: 'Input',
|
||||
label: '字段2',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field3',
|
||||
component: 'DatePicker',
|
||||
label: '字段3',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field4',
|
||||
component: 'Select',
|
||||
label: '字段4',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
key: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
key: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field5',
|
||||
component: 'CheckboxGroup',
|
||||
label: '字段5',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
// {
|
||||
// field: 'field7',
|
||||
// component: 'RadioGroup',
|
||||
// label: '字段7',
|
||||
// colProps: {
|
||||
// span: 8,
|
||||
// },
|
||||
// componentProps: {
|
||||
// options: [
|
||||
// {
|
||||
// label: '选项1',
|
||||
// value: '1',
|
||||
// },
|
||||
// {
|
||||
// label: '选项2',
|
||||
// value: '2',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// },
|
||||
];
|
||||
};
|
||||
|
||||
function getAppendSchemas(): FormSchema[] {
|
||||
return [
|
||||
{
|
||||
field: 'field10',
|
||||
component: 'Input',
|
||||
label: '字段10',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field11',
|
||||
component: 'Input',
|
||||
label: '字段11',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field12',
|
||||
component: 'Input',
|
||||
label: '字段12',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field13',
|
||||
component: 'Input',
|
||||
label: '字段13',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
export default defineComponent({
|
||||
components: { BasicForm, CollapseContainer },
|
||||
setup() {
|
||||
const [register] = useForm({
|
||||
labelWidth: 120,
|
||||
schemas: getSchamas(),
|
||||
actionColOptions: {
|
||||
span: 24,
|
||||
},
|
||||
compact: true,
|
||||
showAdvancedButton: true,
|
||||
});
|
||||
const [register1] = useForm({
|
||||
labelWidth: 120,
|
||||
schemas: [...getSchamas(), ...getAppendSchemas()],
|
||||
actionColOptions: {
|
||||
span: 24,
|
||||
},
|
||||
compact: true,
|
||||
showAdvancedButton: true,
|
||||
});
|
||||
return {
|
||||
register,
|
||||
register1,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
70
src/views/demo/form/CustomerForm.vue
Normal file
70
src/views/demo/form/CustomerForm.vue
Normal file
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div class="m-4">
|
||||
<div class="mb-4"> </div>
|
||||
<CollapseContainer title="自定义表单">
|
||||
<BasicForm @register="register" @submit="handleSubmit" />
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, h } from 'vue';
|
||||
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { Input } from 'ant-design-vue';
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'field1',
|
||||
component: 'Input',
|
||||
label: '字段1',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
render: ({ model, field }) => {
|
||||
return h(Input, {
|
||||
placeholder: '请输入',
|
||||
value: model[field],
|
||||
onChange: (e: ChangeEvent) => {
|
||||
model[field] = e.target.value;
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field2',
|
||||
component: 'Input',
|
||||
label: '字段2',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
renderComponentContent: () => {
|
||||
return {
|
||||
suffix: () => 'suffix',
|
||||
};
|
||||
},
|
||||
},
|
||||
];
|
||||
export default defineComponent({
|
||||
components: { BasicForm, CollapseContainer },
|
||||
setup() {
|
||||
const { createMessage } = useMessage();
|
||||
const [register, { setProps }] = useForm({
|
||||
labelWidth: 120,
|
||||
schemas,
|
||||
actionColOptions: {
|
||||
span: 24,
|
||||
},
|
||||
});
|
||||
return {
|
||||
register,
|
||||
schemas,
|
||||
handleSubmit: (values: any) => {
|
||||
createMessage.success('click search,values:' + JSON.stringify(values));
|
||||
},
|
||||
setProps,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
183
src/views/demo/form/DynamicForm.vue
Normal file
183
src/views/demo/form/DynamicForm.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<div class="m-4">
|
||||
<div class="mb-4">
|
||||
<a-button @click="changeLabel3" class="mr-2">更改字段3label</a-button>
|
||||
<a-button @click="changeLabel34" class="mr-2">同时更改字段3,4label</a-button>
|
||||
<a-button @click="appendField" class="mr-2">往字段3后面插入字段10</a-button>
|
||||
<a-button @click="deleteField" class="mr-2">删除字段11</a-button>
|
||||
</div>
|
||||
<div class="mb-4"> </div>
|
||||
<CollapseContainer title="动态表单示例,动态根据表单内其他值改变">
|
||||
<BasicForm @register="register" />
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'field1',
|
||||
component: 'Input',
|
||||
label: '字段1',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
show: ({ values }) => {
|
||||
return !!values.field5;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field2',
|
||||
component: 'Input',
|
||||
label: '字段2',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
ifShow: ({ values }) => {
|
||||
return !!values.field6;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field3',
|
||||
component: 'DatePicker',
|
||||
label: '字段3',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
dynamicDisabled: ({ values }) => {
|
||||
return !!values.field7;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field4',
|
||||
component: 'Select',
|
||||
label: '字段4',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
dynamicRules: ({ values }) => {
|
||||
return values.field8 ? [{ required: true, message: '字段4必填' }] : [];
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
key: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
key: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field11',
|
||||
component: 'DatePicker',
|
||||
label: '字段11',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field5',
|
||||
component: 'Switch',
|
||||
label: '是否显示字段1(css控制)',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
labelWidth: 200,
|
||||
},
|
||||
{
|
||||
field: 'field6',
|
||||
component: 'Switch',
|
||||
label: '是否显示字段2(dom控制)',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
labelWidth: 200,
|
||||
},
|
||||
{
|
||||
field: 'field7',
|
||||
component: 'Switch',
|
||||
label: '是否禁用字段3',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
labelWidth: 200,
|
||||
},
|
||||
{
|
||||
field: 'field8',
|
||||
component: 'Switch',
|
||||
label: '字段4是否必填',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
labelWidth: 200,
|
||||
},
|
||||
];
|
||||
|
||||
export default defineComponent({
|
||||
components: { BasicForm, CollapseContainer },
|
||||
setup() {
|
||||
const [
|
||||
register,
|
||||
{ setProps, updateSchema, appendSchemaByField, removeSchemaByFiled },
|
||||
] = useForm({
|
||||
labelWidth: 120,
|
||||
schemas,
|
||||
actionColOptions: {
|
||||
span: 24,
|
||||
},
|
||||
});
|
||||
function changeLabel3() {
|
||||
updateSchema({
|
||||
field: 'field3',
|
||||
label: '字段3 New',
|
||||
});
|
||||
}
|
||||
function changeLabel34() {
|
||||
updateSchema([
|
||||
{
|
||||
field: 'field3',
|
||||
label: '字段3 New++',
|
||||
},
|
||||
{
|
||||
field: 'field4',
|
||||
label: '字段4 New++',
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
function appendField() {
|
||||
appendSchemaByField(
|
||||
{
|
||||
field: 'field10',
|
||||
label: '字段10',
|
||||
component: 'Input',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
'field3'
|
||||
);
|
||||
}
|
||||
function deleteField() {
|
||||
removeSchemaByFiled('field11');
|
||||
}
|
||||
return {
|
||||
register,
|
||||
schemas,
|
||||
setProps,
|
||||
changeLabel3,
|
||||
changeLabel34,
|
||||
appendField,
|
||||
deleteField,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
186
src/views/demo/form/RefForm.vue
Normal file
186
src/views/demo/form/RefForm.vue
Normal file
@@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<div class="m-4">
|
||||
<div class="mb-4">
|
||||
<a-button @click="setProps({ labelWidth: 150 })" class="mr-2">更改labelWidth</a-button>
|
||||
<a-button @click="setProps({ labelWidth: 120 })" class="mr-2">还原labelWidth</a-button>
|
||||
<a-button @click="setProps({ size: 'large' })" class="mr-2">更改Size</a-button>
|
||||
<a-button @click="setProps({ size: 'default' })" class="mr-2">还原Size</a-button>
|
||||
<a-button @click="setProps({ disabled: true })" class="mr-2">禁用表单</a-button>
|
||||
<a-button @click="setProps({ disabled: false })" class="mr-2">解除禁用</a-button>
|
||||
<a-button @click="setProps({ compact: true })" class="mr-2">紧凑表单</a-button>
|
||||
<a-button @click="setProps({ compact: false })" class="mr-2">还原正常间距</a-button>
|
||||
<a-button @click="setProps({ actionColOptions: { span: 8 } })" class="mr-2">
|
||||
操作按钮位置
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<a-button @click="setProps({ showActionButtonGroup: false })" class="mr-2">
|
||||
隐藏操作按钮
|
||||
</a-button>
|
||||
<a-button @click="setProps({ showActionButtonGroup: true })" class="mr-2">
|
||||
显示操作按钮
|
||||
</a-button>
|
||||
<a-button @click="setProps({ showResetButton: false })" class="mr-2"> 隐藏重置按钮 </a-button>
|
||||
<a-button @click="setProps({ showResetButton: true })" class="mr-2"> 显示重置按钮 </a-button>
|
||||
<a-button @click="setProps({ showSubmitButton: false })" class="mr-2">
|
||||
隐藏查询按钮
|
||||
</a-button>
|
||||
<a-button @click="setProps({ showSubmitButton: true })" class="mr-2"> 显示查询按钮 </a-button>
|
||||
<a-button
|
||||
@click="
|
||||
setProps({
|
||||
resetButtonOptions: {
|
||||
disabled: true,
|
||||
text: '重置New',
|
||||
},
|
||||
})
|
||||
"
|
||||
class="mr-2"
|
||||
>
|
||||
修改重置按钮
|
||||
</a-button>
|
||||
<a-button
|
||||
@click="
|
||||
setProps({
|
||||
submitButtonOptions: {
|
||||
disabled: true,
|
||||
loading: true,
|
||||
},
|
||||
})
|
||||
"
|
||||
class="mr-2"
|
||||
>
|
||||
修改查询按钮
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="mb-4"> </div>
|
||||
<CollapseContainer title="使用ref调用表单内部函数示例">
|
||||
<BasicForm
|
||||
:schemas="schemas"
|
||||
ref="formElRef"
|
||||
@submit="handleSubmit"
|
||||
:actionColOptions="{ span: 24 }"
|
||||
/>
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { BasicForm, FormSchema, FormActionType, FormProps } from '/@/components/Form/index';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'field1',
|
||||
component: 'Input',
|
||||
label: '字段1',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: '自定义placeholder',
|
||||
onChange: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field2',
|
||||
component: 'Input',
|
||||
label: '字段2',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field3',
|
||||
component: 'DatePicker',
|
||||
label: '字段3',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field4',
|
||||
component: 'Select',
|
||||
label: '字段4',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
key: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
key: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field5',
|
||||
component: 'CheckboxGroup',
|
||||
label: '字段5',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field7',
|
||||
component: 'RadioGroup',
|
||||
label: '字段7',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default defineComponent({
|
||||
components: { BasicForm, CollapseContainer },
|
||||
setup() {
|
||||
const formElRef = ref<Nullable<FormActionType>>(null);
|
||||
const { createMessage } = useMessage();
|
||||
return {
|
||||
formElRef,
|
||||
schemas,
|
||||
handleSubmit: (values: any) => {
|
||||
createMessage.success('click search,values:' + JSON.stringify(values));
|
||||
},
|
||||
setProps(props: FormProps) {
|
||||
const formEl = formElRef.value;
|
||||
if (!formEl) return;
|
||||
formEl.setProps(props);
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
163
src/views/demo/form/RuleForm.vue
Normal file
163
src/views/demo/form/RuleForm.vue
Normal file
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<div class="m-4">
|
||||
<div class="mb-4">
|
||||
<a-button @click="validateForm" class="mr-2">手动校验表单</a-button>
|
||||
<a-button @click="resetValidate" class="mr-2">清空校验信息</a-button>
|
||||
<a-button @click="getFormValues" class="mr-2">获取表单值</a-button>
|
||||
<a-button @click="setFormValues" class="mr-2">设置表单值</a-button>
|
||||
</div>
|
||||
<div class="mb-4"> </div>
|
||||
<CollapseContainer title="表单校验">
|
||||
<BasicForm @register="register" @submit="handleSubmit" />
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'field1',
|
||||
component: 'Input',
|
||||
label: '字段1',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
field: 'field2',
|
||||
component: 'Input',
|
||||
label: '字段2',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
field: 'field3',
|
||||
component: 'DatePicker',
|
||||
label: '字段3',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
field: 'field4',
|
||||
component: 'Select',
|
||||
label: '字段4',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
key: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
key: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
field: 'field5',
|
||||
component: 'CheckboxGroup',
|
||||
label: '字段5',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
{
|
||||
field: 'field7',
|
||||
component: 'RadioGroup',
|
||||
label: '字段7',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
rules: [{ required: true, message: '覆盖默认生成的校验信息' }],
|
||||
},
|
||||
];
|
||||
|
||||
export default defineComponent({
|
||||
components: { BasicForm, CollapseContainer },
|
||||
setup() {
|
||||
const { createMessage } = useMessage();
|
||||
const [register, { validateFields, clearValidate, getFieldsValue, setFieldsValue }] = useForm(
|
||||
{
|
||||
labelWidth: 120,
|
||||
schemas,
|
||||
actionColOptions: {
|
||||
span: 24,
|
||||
},
|
||||
}
|
||||
);
|
||||
async function validateForm() {
|
||||
try {
|
||||
const res = await validateFields();
|
||||
console.log('passing', res);
|
||||
} catch (error) {
|
||||
console.log('not passing', error);
|
||||
}
|
||||
}
|
||||
async function resetValidate() {
|
||||
clearValidate();
|
||||
}
|
||||
function getFormValues() {
|
||||
const values = getFieldsValue();
|
||||
createMessage.success('values:' + JSON.stringify(values));
|
||||
}
|
||||
function setFormValues() {
|
||||
setFieldsValue({
|
||||
field1: '1111',
|
||||
field5: ['1'],
|
||||
field7: '1',
|
||||
});
|
||||
}
|
||||
return {
|
||||
register,
|
||||
schemas,
|
||||
handleSubmit: (values: any) => {
|
||||
createMessage.success('click search,values:' + JSON.stringify(values));
|
||||
},
|
||||
getFormValues,
|
||||
setFormValues,
|
||||
validateForm,
|
||||
resetValidate,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
183
src/views/demo/form/UseForm.vue
Normal file
183
src/views/demo/form/UseForm.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<div class="m-4">
|
||||
<div class="mb-4">
|
||||
<a-button @click="setProps({ labelWidth: 150 })" class="mr-2">更改labelWidth</a-button>
|
||||
<a-button @click="setProps({ labelWidth: 120 })" class="mr-2">还原labelWidth</a-button>
|
||||
<a-button @click="setProps({ size: 'large' })" class="mr-2">更改Size</a-button>
|
||||
<a-button @click="setProps({ size: 'default' })" class="mr-2">还原Size</a-button>
|
||||
<a-button @click="setProps({ disabled: true })" class="mr-2">禁用表单</a-button>
|
||||
<a-button @click="setProps({ disabled: false })" class="mr-2">解除禁用</a-button>
|
||||
<a-button @click="setProps({ compact: true })" class="mr-2">紧凑表单</a-button>
|
||||
<a-button @click="setProps({ compact: false })" class="mr-2">还原正常间距</a-button>
|
||||
<a-button @click="setProps({ actionColOptions: { span: 8 } })" class="mr-2">
|
||||
操作按钮位置
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<a-button @click="setProps({ showActionButtonGroup: false })" class="mr-2">
|
||||
隐藏操作按钮
|
||||
</a-button>
|
||||
<a-button @click="setProps({ showActionButtonGroup: true })" class="mr-2">
|
||||
显示操作按钮
|
||||
</a-button>
|
||||
<a-button @click="setProps({ showResetButton: false })" class="mr-2"> 隐藏重置按钮 </a-button>
|
||||
<a-button @click="setProps({ showResetButton: true })" class="mr-2"> 显示重置按钮 </a-button>
|
||||
<a-button @click="setProps({ showSubmitButton: false })" class="mr-2">
|
||||
隐藏查询按钮
|
||||
</a-button>
|
||||
<a-button @click="setProps({ showSubmitButton: true })" class="mr-2"> 显示查询按钮 </a-button>
|
||||
<a-button
|
||||
@click="
|
||||
setProps({
|
||||
resetButtonOptions: {
|
||||
disabled: true,
|
||||
text: '重置New',
|
||||
},
|
||||
})
|
||||
"
|
||||
class="mr-2"
|
||||
>
|
||||
修改重置按钮
|
||||
</a-button>
|
||||
<a-button
|
||||
@click="
|
||||
setProps({
|
||||
submitButtonOptions: {
|
||||
disabled: true,
|
||||
loading: true,
|
||||
},
|
||||
})
|
||||
"
|
||||
class="mr-2"
|
||||
>
|
||||
修改查询按钮
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="mb-4"> </div>
|
||||
<CollapseContainer title="useForm示例">
|
||||
<BasicForm @register="register" @submit="handleSubmit" />
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'field1',
|
||||
component: 'Input',
|
||||
label: '字段1',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: '自定义placeholder',
|
||||
onChange: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field2',
|
||||
component: 'Input',
|
||||
label: '字段2',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field3',
|
||||
component: 'DatePicker',
|
||||
label: '字段3',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field4',
|
||||
component: 'Select',
|
||||
label: '字段4',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
key: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
key: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field5',
|
||||
component: 'CheckboxGroup',
|
||||
label: '字段5',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field7',
|
||||
component: 'RadioGroup',
|
||||
label: '字段7',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default defineComponent({
|
||||
components: { BasicForm, CollapseContainer },
|
||||
setup() {
|
||||
const { createMessage } = useMessage();
|
||||
const [register, { setProps }] = useForm({
|
||||
labelWidth: 120,
|
||||
schemas,
|
||||
actionColOptions: {
|
||||
span: 24,
|
||||
},
|
||||
});
|
||||
return {
|
||||
register,
|
||||
schemas,
|
||||
handleSubmit: (values: any) => {
|
||||
createMessage.success('click search,values:' + JSON.stringify(values));
|
||||
},
|
||||
setProps,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
126
src/views/demo/form/index.vue
Normal file
126
src/views/demo/form/index.vue
Normal file
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<div class="m-4">
|
||||
<CollapseContainer title="基础示例">
|
||||
<BasicForm
|
||||
:labelWidth="100"
|
||||
:schemas="schemas"
|
||||
:actionColOptions="{ span: 24 }"
|
||||
@submit="handleSubmit"
|
||||
/>
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicForm, FormSchema } from '/@/components/Form/index';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'field1',
|
||||
component: 'Input',
|
||||
label: '字段1',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
defaultValue: '111',
|
||||
componentProps: {
|
||||
placeholder: '自定义placeholder',
|
||||
onChange: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field2',
|
||||
component: 'Input',
|
||||
label: '字段2',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field3',
|
||||
component: 'DatePicker',
|
||||
label: '字段3',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field4',
|
||||
component: 'Select',
|
||||
label: '字段4',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
key: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
key: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field5',
|
||||
component: 'CheckboxGroup',
|
||||
label: '字段5',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field7',
|
||||
component: 'RadioGroup',
|
||||
label: '字段7',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default defineComponent({
|
||||
components: { BasicForm, CollapseContainer },
|
||||
setup() {
|
||||
const { createMessage } = useMessage();
|
||||
return {
|
||||
schemas,
|
||||
handleSubmit: (values: any) => {
|
||||
createMessage.success('click search,values:' + JSON.stringify(values));
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
33
src/views/demo/permission/CurrentPermissionMode.vue
Normal file
33
src/views/demo/permission/CurrentPermissionMode.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="mt-2">
|
||||
当前权限模式:
|
||||
<a-button type="link">
|
||||
{{ permissionMode === PermissionModeEnum.BACK ? '后台权限模式' : '前端角色权限模式' }}
|
||||
</a-button>
|
||||
<a-button class="ml-4" @click="togglePermissionMode" type="primary"> 切换权限模式 </a-button>
|
||||
<Divider />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { appStore } from '/@/store/modules/app';
|
||||
import { PermissionModeEnum } from '/@/enums/appEnum';
|
||||
import { Divider } from 'ant-design-vue';
|
||||
import { usePermission } from '/@/hooks/web/usePermission';
|
||||
export default defineComponent({
|
||||
name: 'CurrentPermissionMode',
|
||||
components: { Divider },
|
||||
setup() {
|
||||
const permissionMode = computed(() => {
|
||||
return appStore.getProjectConfig.permissionMode;
|
||||
});
|
||||
const { togglePermissionMode } = usePermission();
|
||||
|
||||
return {
|
||||
permissionMode,
|
||||
PermissionModeEnum,
|
||||
togglePermissionMode,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
85
src/views/demo/permission/back/Btn.vue
Normal file
85
src/views/demo/permission/back/Btn.vue
Normal file
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<div class="p-10 m-4 rounded-md bg-white">
|
||||
<Alert message="刷新后会还原" show-icon />
|
||||
|
||||
<CurrentPermissionMode />
|
||||
|
||||
<p>
|
||||
当前拥有的code列表: <a> {{ permissionStore.getPermCodeListState }} </a>
|
||||
</p>
|
||||
<Divider />
|
||||
<Alert class="mt-4" type="info" message="点击后请查看按钮变化" show-icon />
|
||||
<Divider />
|
||||
<a-button type="primary" class="mr-2" @click="changePermissionCode('2')">
|
||||
点击切换按钮权限(用户id为2)
|
||||
</a-button>
|
||||
<a-button type="primary" @click="changePermissionCode('1')">
|
||||
点击切换按钮权限(用户id为1,默认)
|
||||
</a-button>
|
||||
|
||||
<Divider>组件方式判断权限</Divider>
|
||||
<Authority :value="'1000'">
|
||||
<a-button type="primary" class="mx-4">拥有code ['1000']权限可见</a-button>
|
||||
</Authority>
|
||||
|
||||
<Authority :value="'2000'">
|
||||
<a-button color="success" class="mx-4">拥有code ['2000']权限可见</a-button>
|
||||
</Authority>
|
||||
|
||||
<Authority :value="['1000', '2000']">
|
||||
<a-button color="error" class="mx-4">拥有code ['1000','2000']角色权限可见</a-button>
|
||||
</Authority>
|
||||
|
||||
<Divider>函数方式方式判断权限</Divider>
|
||||
<a-button v-if="hasPermission('1000')" type="primary" class="mx-4">
|
||||
拥有code ['1000']权限可见
|
||||
</a-button>
|
||||
|
||||
<a-button v-if="hasPermission('2000')" color="success" class="mx-4">
|
||||
拥有code ['2000']权限可见
|
||||
</a-button>
|
||||
|
||||
<a-button v-if="hasPermission(['1000', '2000'])" color="error" class="mx-4">
|
||||
拥有code ['1000','2000']角色权限可见
|
||||
</a-button>
|
||||
|
||||
<Divider>指令方式方式判断权限(该方式不能动态修改权限.)</Divider>
|
||||
<a-button v-auth="'1000'" type="primary" class="mx-4"> 拥有code ['1000']权限可见 </a-button>
|
||||
|
||||
<a-button v-auth="'2000'" color="success" class="mx-4"> 拥有code ['2000']权限可见 </a-button>
|
||||
|
||||
<a-button v-auth="['1000', '2000']" color="error" class="mx-4">
|
||||
拥有code ['1000','2000']角色权限可见
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Alert, Divider } from 'ant-design-vue';
|
||||
import CurrentPermissionMode from '../CurrentPermissionMode.vue';
|
||||
import { usePermission } from '/@/hooks/web/usePermission';
|
||||
import Authority from '/@/components/Authority';
|
||||
import { getPermCodeByUserId } from '/@/api/sys/user';
|
||||
import { permissionStore } from '/@/store/modules/permission';
|
||||
import { PermissionModeEnum } from '/@/enums/appEnum';
|
||||
export default defineComponent({
|
||||
components: { Alert, CurrentPermissionMode, Divider, Authority },
|
||||
setup() {
|
||||
const { hasPermission } = usePermission();
|
||||
|
||||
// !模拟从后台获取权限编码, 该函数可能只需要执行一次,实际项目可以自行放到合适的时机
|
||||
async function changePermissionCode(userId: string) {
|
||||
const codeList = await getPermCodeByUserId({ userId });
|
||||
permissionStore.commitPermCodeListState(codeList);
|
||||
}
|
||||
// 默认初始化为1
|
||||
changePermissionCode('1');
|
||||
return {
|
||||
hasPermission,
|
||||
permissionStore,
|
||||
changePermissionCode,
|
||||
PermissionModeEnum,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
37
src/views/demo/permission/back/index.vue
Normal file
37
src/views/demo/permission/back/index.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<div class="p-10 m-4 rounded-md bg-white">
|
||||
<Alert
|
||||
message="目前mock了两组数据, id为1 和 2 具体返回的菜单可以在mock/sys/menu.ts内查看"
|
||||
show-icon
|
||||
/>
|
||||
<CurrentPermissionMode />
|
||||
|
||||
<Alert class="mt-4" type="info" message="点击后请查看左侧菜单变化" show-icon />
|
||||
|
||||
<div class="mt-4">
|
||||
权限切换(请先切换权限模式为后台权限模式):
|
||||
<a-button-group>
|
||||
<a-button @click="changeMenu('1')"> 获取用户id为1的菜单 </a-button>
|
||||
<a-button @click="changeMenu('2')"> 获取用户id为2的菜单 </a-button>
|
||||
</a-button-group>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Alert } from 'ant-design-vue';
|
||||
import CurrentPermissionMode from '../CurrentPermissionMode.vue';
|
||||
import { RoleEnum } from '/@/enums/roleEnum';
|
||||
import { usePermission } from '/@/hooks/web/usePermission';
|
||||
|
||||
export default defineComponent({
|
||||
components: { Alert, CurrentPermissionMode },
|
||||
setup() {
|
||||
const { changeMenu } = usePermission();
|
||||
return {
|
||||
RoleEnum,
|
||||
changeMenu,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
9
src/views/demo/permission/front/AuthPageA.vue
Normal file
9
src/views/demo/permission/front/AuthPageA.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<div class="m-10 bg-primary text-2xl h-64 rounded-lg flex justify-center items-center text-white">
|
||||
Super 角色可见
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
export default defineComponent({});
|
||||
</script>
|
9
src/views/demo/permission/front/AuthPageB.vue
Normal file
9
src/views/demo/permission/front/AuthPageB.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<div class="m-10 bg-primary text-2xl h-64 rounded-lg flex justify-center items-center text-white">
|
||||
Test 角色可见
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
export default defineComponent({});
|
||||
</script>
|
84
src/views/demo/permission/front/Btn.vue
Normal file
84
src/views/demo/permission/front/Btn.vue
Normal file
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<div class="p-10 m-4 rounded-md bg-white">
|
||||
<Alert
|
||||
message="由于刷新的时候会请求用户信息接口,会根据接口重置角色信息,所以刷新后界面会恢复原样,如果不需要,可以注释 src/layout/default/index内的获取用户信息接口"
|
||||
show-icon
|
||||
/>
|
||||
<CurrentPermissionMode />
|
||||
|
||||
<p>
|
||||
当前角色: <a> {{ userStore.getRoleListState }} </a>
|
||||
</p>
|
||||
<Alert class="mt-4" type="info" message="点击后请查看按钮变化" show-icon />
|
||||
|
||||
<div class="mt-4">
|
||||
权限切换(请先切换权限模式为前端角色权限模式):
|
||||
<a-button-group>
|
||||
<a-button @click="changeRole(RoleEnum.SUPER)" :type="isSuper ? 'primary' : ''">
|
||||
{{ RoleEnum.SUPER }}
|
||||
</a-button>
|
||||
<a-button @click="changeRole(RoleEnum.TEST)" :type="isTest ? 'primary' : ''">
|
||||
{{ RoleEnum.TEST }}
|
||||
</a-button>
|
||||
</a-button-group>
|
||||
</div>
|
||||
<Divider>组件方式判断权限(有需要可以自行全局注册)</Divider>
|
||||
<Authority :value="RoleEnum.SUPER">
|
||||
<a-button type="primary" class="mx-4">拥有super角色权限可见</a-button>
|
||||
</Authority>
|
||||
|
||||
<Authority :value="RoleEnum.TEST">
|
||||
<a-button color="success" class="mx-4">拥有test角色权限可见</a-button>
|
||||
</Authority>
|
||||
|
||||
<Authority :value="[RoleEnum.TEST, RoleEnum.SUPER]">
|
||||
<a-button color="error" class="mx-4">拥有[test,super]角色权限可见</a-button>
|
||||
</Authority>
|
||||
|
||||
<Divider>函数方式方式判断权限(适用于函数内部过滤)</Divider>
|
||||
<a-button v-if="hasPermission(RoleEnum.SUPER)" type="primary" class="mx-4">
|
||||
拥有super角色权限可见
|
||||
</a-button>
|
||||
|
||||
<a-button v-if="hasPermission(RoleEnum.TEST)" color="success" class="mx-4">
|
||||
拥有test角色权限可见
|
||||
</a-button>
|
||||
|
||||
<a-button v-if="hasPermission([RoleEnum.TEST, RoleEnum.SUPER])" color="error" class="mx-4">
|
||||
拥有[test,super]角色权限可见
|
||||
</a-button>
|
||||
|
||||
<Divider>指令方式方式判断权限(该方式不能动态修改权限.)</Divider>
|
||||
<a-button v-auth="RoleEnum.SUPER" type="primary" class="mx-4"> 拥有super角色权限可见 </a-button>
|
||||
|
||||
<a-button v-auth="RoleEnum.TEST" color="success" class="mx-4"> 拥有test角色权限可见 </a-button>
|
||||
|
||||
<a-button v-auth="[RoleEnum.TEST, RoleEnum.SUPER]" color="error" class="mx-4">
|
||||
拥有[test,super]角色权限可见
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import { Alert, Divider } from 'ant-design-vue';
|
||||
import CurrentPermissionMode from '../CurrentPermissionMode.vue';
|
||||
import { userStore } from '/@/store/modules/user';
|
||||
import { RoleEnum } from '/@/enums/roleEnum';
|
||||
import { usePermission } from '/@/hooks/web/usePermission';
|
||||
import Authority from '/@/components/Authority';
|
||||
|
||||
export default defineComponent({
|
||||
components: { Alert, CurrentPermissionMode, Divider, Authority },
|
||||
setup() {
|
||||
const { changeRole, hasPermission } = usePermission();
|
||||
return {
|
||||
userStore,
|
||||
RoleEnum,
|
||||
isSuper: computed(() => userStore.getRoleListState.includes(RoleEnum.SUPER)),
|
||||
isTest: computed(() => userStore.getRoleListState.includes(RoleEnum.TEST)),
|
||||
changeRole,
|
||||
hasPermission,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
48
src/views/demo/permission/front/index.vue
Normal file
48
src/views/demo/permission/front/index.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div class="p-10 m-4 rounded-md bg-white">
|
||||
<Alert
|
||||
message="由于刷新的时候会请求用户信息接口,会根据接口重置角色信息,所以刷新后界面会恢复原样,如果不需要,可以注释 src/layout/default/index内的获取用户信息接口"
|
||||
show-icon
|
||||
/>
|
||||
<CurrentPermissionMode />
|
||||
|
||||
<p>
|
||||
当前角色: <a> {{ userStore.getRoleListState }} </a>
|
||||
</p>
|
||||
<Alert class="mt-4" type="info" message="点击后请查看左侧菜单变化" show-icon />
|
||||
|
||||
<div class="mt-4">
|
||||
权限切换(请先切换权限模式为前端角色权限模式):
|
||||
<a-button-group>
|
||||
<a-button @click="changeRole(RoleEnum.SUPER)" :type="isSuper ? 'primary' : ''">
|
||||
{{ RoleEnum.SUPER }}
|
||||
</a-button>
|
||||
<a-button @click="changeRole(RoleEnum.TEST)" :type="isTest ? 'primary' : ''">
|
||||
{{ RoleEnum.TEST }}
|
||||
</a-button>
|
||||
</a-button-group>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import { Alert } from 'ant-design-vue';
|
||||
import CurrentPermissionMode from '../CurrentPermissionMode.vue';
|
||||
import { userStore } from '/@/store/modules/user';
|
||||
import { RoleEnum } from '/@/enums/roleEnum';
|
||||
import { usePermission } from '/@/hooks/web/usePermission';
|
||||
|
||||
export default defineComponent({
|
||||
components: { Alert, CurrentPermissionMode },
|
||||
setup() {
|
||||
const { changeRole } = usePermission();
|
||||
return {
|
||||
userStore,
|
||||
RoleEnum,
|
||||
isSuper: computed(() => userStore.getRoleListState.includes(RoleEnum.SUPER)),
|
||||
isTest: computed(() => userStore.getRoleListState.includes(RoleEnum.TEST)),
|
||||
changeRole,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
116
src/views/demo/tree/ActionTree.vue
Normal file
116
src/views/demo/tree/ActionTree.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<div class="mb-4">
|
||||
<a-button @click="handleLevel(2)" class="mr-2">显示到第2级</a-button>
|
||||
<a-button @click="handleLevel(1)" class="mr-2">显示到第1级</a-button>
|
||||
<a-button @click="handleSetCheckData" class="mr-2">设置勾选数据</a-button>
|
||||
<a-button @click="handleGetCheckData" class="mr-2">获取勾选数据</a-button>
|
||||
<a-button @click="handleSetSelectData" class="mr-2">设置选中数据</a-button>
|
||||
<a-button @click="handleGetSelectData" class="mr-2">获取选中数据</a-button>
|
||||
|
||||
<a-button @click="handleSetExpandData" class="mr-2">设置展开数据</a-button>
|
||||
<a-button @click="handleGetExpandData" class="mr-2">获取展开数据</a-button>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<a-button @click="appendNodeByKey(null)" class="mr-2">添加根节点</a-button>
|
||||
<a-button @click="appendNodeByKey('2-2')" class="mr-2">添加在parent3内添加节点</a-button>
|
||||
<a-button @click="deleteNodeByKey('2-2')" class="mr-2">删除parent3节点</a-button>
|
||||
<a-button @click="updateNodeByKey('1-1')" class="mr-2">更新parent2节点</a-button>
|
||||
</div>
|
||||
<CollapseContainer title="函数操作" class="w-1/3 mr-4" :canExpan="false">
|
||||
<BasicTree :treeData="treeData" ref="treeRef" :checkable="true" />
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, unref } from 'vue';
|
||||
import { BasicTree, TreeActionType } from '/@/components/Tree/index';
|
||||
import { treeData } from './data';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
export default defineComponent({
|
||||
components: { BasicTree, CollapseContainer },
|
||||
setup() {
|
||||
const treeRef = ref<RefInstanceType<TreeActionType>>(null);
|
||||
const { createMessage } = useMessage();
|
||||
function getTree() {
|
||||
const tree = unref(treeRef);
|
||||
if (!tree) {
|
||||
throw new Error('tree is null!');
|
||||
}
|
||||
return tree.$;
|
||||
}
|
||||
|
||||
function handleLevel(level: number) {
|
||||
getTree().filterByLevel(level);
|
||||
}
|
||||
|
||||
function handleSetCheckData() {
|
||||
getTree().setCheckedKeys(['0-0']);
|
||||
}
|
||||
|
||||
function handleGetCheckData() {
|
||||
const keys = getTree().getCheckedKeys();
|
||||
createMessage.success(JSON.stringify(keys));
|
||||
}
|
||||
|
||||
function handleSetSelectData() {
|
||||
getTree().setSelectedKeys(['0-0']);
|
||||
}
|
||||
|
||||
function handleGetSelectData() {
|
||||
const keys = getTree().getSelectedKeys();
|
||||
createMessage.success(JSON.stringify(keys));
|
||||
}
|
||||
|
||||
function handleSetExpandData() {
|
||||
getTree().setExpandedKeys(['0-0']);
|
||||
}
|
||||
|
||||
function handleGetExpandData() {
|
||||
const keys = getTree().getExpandedKeys();
|
||||
createMessage.success(JSON.stringify(keys));
|
||||
}
|
||||
|
||||
function appendNodeByKey(parentKey: string | null = null) {
|
||||
getTree().insertNodeByKey({
|
||||
parentKey: parentKey,
|
||||
node: {
|
||||
title: '新增节点',
|
||||
key: '2-2-2',
|
||||
},
|
||||
// 往后插入
|
||||
push: 'push',
|
||||
// 往前插入
|
||||
// push:'unshift'
|
||||
});
|
||||
}
|
||||
|
||||
function deleteNodeByKey(key: string) {
|
||||
getTree().deleteNodeByKey(key);
|
||||
}
|
||||
|
||||
function updateNodeByKey(key: string) {
|
||||
getTree().updateNodeByKey(key, {
|
||||
title: 'parent2-new',
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
treeData,
|
||||
treeRef,
|
||||
handleLevel,
|
||||
handleSetCheckData,
|
||||
handleGetCheckData,
|
||||
handleSetSelectData,
|
||||
handleGetSelectData,
|
||||
handleSetExpandData,
|
||||
handleGetExpandData,
|
||||
appendNodeByKey,
|
||||
deleteNodeByKey,
|
||||
updateNodeByKey,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
63
src/views/demo/tree/EditTree.vue
Normal file
63
src/views/demo/tree/EditTree.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div class="flex p-4">
|
||||
<CollapseContainer title="右侧操作按钮" class="w-1/3 mr-4">
|
||||
<BasicTree :treeData="treeData" :actionList="actionList" />
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer title="右键菜单" class="w-1/3 mr-4">
|
||||
<BasicTree :treeData="treeData" :beforeRightClick="getRightMenuList" />
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, h } from 'vue';
|
||||
import { BasicTree, ActionItem, ContextMenuItem } from '/@/components/Tree/index';
|
||||
import { treeData } from './data';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons-vue';
|
||||
export default defineComponent({
|
||||
components: { BasicTree, CollapseContainer },
|
||||
setup() {
|
||||
function handlePlus(node: any) {
|
||||
console.log(node);
|
||||
}
|
||||
|
||||
function getRightMenuList(node: any): ContextMenuItem[] {
|
||||
return [
|
||||
{
|
||||
label: '新增',
|
||||
handler: () => {
|
||||
console.log('点击了新增', node);
|
||||
},
|
||||
icon: 'ant-design:plus-outlined',
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
handler: () => {
|
||||
console.log('点击了删除', node);
|
||||
},
|
||||
icon: 'ant-design:folder-open-filled',
|
||||
},
|
||||
];
|
||||
}
|
||||
const actionList: ActionItem[] = [
|
||||
{
|
||||
render: (node) => {
|
||||
return h(PlusOutlined, {
|
||||
class: 'ml-2',
|
||||
onClick: () => {
|
||||
handlePlus(node);
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
render: () => {
|
||||
return h(DeleteOutlined);
|
||||
},
|
||||
},
|
||||
];
|
||||
return { treeData, actionList, getRightMenuList };
|
||||
},
|
||||
});
|
||||
</script>
|
38
src/views/demo/tree/data.ts
Normal file
38
src/views/demo/tree/data.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { TreeItem } from '/@/components/Tree/index';
|
||||
|
||||
export const treeData: TreeItem[] = [
|
||||
{
|
||||
title: 'parent 1',
|
||||
key: '0-0',
|
||||
icon: 'home|svg',
|
||||
children: [
|
||||
{ title: 'leaf', key: '0-0-0' },
|
||||
{
|
||||
title: 'leaf',
|
||||
key: '0-0-1',
|
||||
children: [
|
||||
{ title: 'leaf', key: '0-0-0-0' },
|
||||
{ title: 'leaf', key: '0-0-0-1' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'parent 2',
|
||||
key: '1-1',
|
||||
icon: 'home|svg',
|
||||
children: [
|
||||
{ title: 'leaf', key: '1-1-0' },
|
||||
{ title: 'leaf', key: '1-1-1' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'parent 3',
|
||||
key: '2-2',
|
||||
icon: 'home|svg',
|
||||
children: [
|
||||
{ title: 'leaf', key: '2-2-0' },
|
||||
{ title: 'leaf', key: '2-2-1' },
|
||||
],
|
||||
},
|
||||
];
|
33
src/views/demo/tree/index.vue
Normal file
33
src/views/demo/tree/index.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="flex p-4">
|
||||
<CollapseContainer title="基础示例" class="w-1/3 mr-4">
|
||||
<BasicTree :treeData="treeData" />
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer title="可勾选" class="w-1/3 mr-4">
|
||||
<BasicTree :treeData="treeData" :checkable="true" />
|
||||
</CollapseContainer>
|
||||
|
||||
<CollapseContainer title="默认展开/勾选示例" class="w-1/3">
|
||||
<BasicTree
|
||||
:treeData="treeData"
|
||||
:checkable="true"
|
||||
:expandedKeys="['0-0']"
|
||||
:checkedKeys="['0-0']"
|
||||
/>
|
||||
</CollapseContainer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { BasicTree } from '/@/components/Tree/index';
|
||||
import { treeData } from './data';
|
||||
import { CollapseContainer } from '/@/components/Container/index';
|
||||
|
||||
export default defineComponent({
|
||||
components: { BasicTree, CollapseContainer },
|
||||
setup() {
|
||||
return { treeData };
|
||||
},
|
||||
});
|
||||
</script>
|
Reference in New Issue
Block a user