refactor(demo): 重构demo页面组件为 script setup 语法 (#3293)

* refactor: charts demo use setup refactor

* refactor: demo use script setup refactor

* refactor: demo feat use script setup refactor

* fix: tab-params

* revert: settings.json

* style(demo->Modal1): loading text line height

* Update index.vue

---------

Co-authored-by: invalid w <wangjuesix@gmail.com>
This commit is contained in:
xingyu 2023-11-18 11:43:18 +08:00 committed by GitHub
parent cb907165ec
commit 35751068c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
133 changed files with 2861 additions and 3967 deletions

View File

@ -1,117 +1,113 @@
<template>
<div ref="chartRef" :style="{ height, width }"></div>
</template>
<script lang="ts">
import { defineComponent, PropType, ref, Ref, onMounted } from 'vue';
import { useECharts } from '/@/hooks/web/useECharts';
<script lang="ts" setup>
import { PropType, ref, Ref, onMounted } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { getLineData } from './data';
export default defineComponent({
props: {
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: 'calc(100vh - 78px)',
},
defineProps({
width: {
type: String as PropType<string>,
default: '100%',
},
setup() {
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions, echarts } = useECharts(chartRef as Ref<HTMLDivElement>);
const { barData, lineData, category } = getLineData;
onMounted(() => {
setOptions({
backgroundColor: '#0f375f',
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true,
backgroundColor: '#333',
},
},
},
legend: {
data: ['line', 'bar'],
textStyle: {
color: '#ccc',
},
},
xAxis: {
data: category,
axisLine: {
lineStyle: {
color: '#ccc',
},
},
},
yAxis: {
splitLine: { show: false },
axisLine: {
lineStyle: {
color: '#ccc',
},
},
},
series: [
{
name: 'line',
type: 'line',
smooth: true,
showAllSymbol: 'auto',
symbol: 'emptyCircle',
symbolSize: 15,
data: lineData,
},
{
name: 'bar',
type: 'bar',
barWidth: 10,
itemStyle: {
borderRadius: 5,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#14c8d4' },
{ offset: 1, color: '#43eec6' },
]),
},
data: barData,
},
{
name: 'line',
type: 'bar',
barGap: '-100%',
barWidth: 10,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(20,200,212,0.5)' },
{ offset: 0.2, color: 'rgba(20,200,212,0.2)' },
{ offset: 1, color: 'rgba(20,200,212,0)' },
]),
},
z: -12,
data: lineData,
},
{
name: 'dotted',
type: 'pictorialBar',
symbol: 'rect',
itemStyle: {
color: '#0f375f',
},
symbolRepeat: true,
symbolSize: [12, 4],
symbolMargin: 1,
z: -10,
data: lineData,
},
],
});
});
return { chartRef };
height: {
type: String as PropType<string>,
default: 'calc(100vh - 78px)',
},
});
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions, echarts } = useECharts(chartRef as Ref<HTMLDivElement>);
const { barData, lineData, category } = getLineData;
onMounted(() => {
setOptions({
backgroundColor: '#0f375f',
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true,
backgroundColor: '#333',
},
},
},
legend: {
data: ['line', 'bar'],
textStyle: {
color: '#ccc',
},
},
xAxis: {
data: category,
axisLine: {
lineStyle: {
color: '#ccc',
},
},
},
yAxis: {
splitLine: { show: false },
axisLine: {
lineStyle: {
color: '#ccc',
},
},
},
series: [
{
name: 'line',
type: 'line',
smooth: true,
showAllSymbol: 'auto',
symbol: 'emptyCircle',
symbolSize: 15,
data: lineData,
},
{
name: 'bar',
type: 'bar',
barWidth: 10,
itemStyle: {
borderRadius: 5,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#14c8d4' },
{ offset: 1, color: '#43eec6' },
]),
},
data: barData,
},
{
name: 'line',
type: 'bar',
barGap: '-100%',
barWidth: 10,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(20,200,212,0.5)' },
{ offset: 0.2, color: 'rgba(20,200,212,0.2)' },
{ offset: 1, color: 'rgba(20,200,212,0)' },
]),
},
z: -12,
data: lineData,
},
{
name: 'dotted',
type: 'pictorialBar',
symbol: 'rect',
itemStyle: {
color: '#0f375f',
},
symbolRepeat: true,
symbolSize: [12, 4],
symbolMargin: 1,
z: -10,
data: lineData,
},
],
});
});
</script>

View File

@ -1,75 +1,70 @@
<template>
<div ref="chartRef" :style="{ height, width }"></div>
</template>
<script lang="ts">
import { defineComponent, PropType, ref, Ref, onMounted } from 'vue';
import { useECharts } from '/@/hooks/web/useECharts';
<script lang="ts" setup>
import { PropType, ref, Ref, onMounted } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { mapData } from './data';
import { registerMap } from 'echarts';
export default defineComponent({
props: {
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: 'calc(100vh - 78px)',
},
defineProps({
width: {
type: String as PropType<string>,
default: '100%',
},
setup() {
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
onMounted(async () => {
const json = (await (await import('./china.json')).default) as any;
registerMap('china', json);
setOptions({
visualMap: [
{
min: 0,
max: 1000,
left: 'left',
top: 'bottom',
text: ['高', '低'],
calculable: false,
orient: 'horizontal',
inRange: {
color: ['#e0ffff', '#006edd'],
symbolSize: [30, 100],
},
},
],
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(0, 0, 0, .6)',
textStyle: {
color: '#fff',
fontSize: 12,
},
},
series: [
{
name: 'iphone4',
type: 'map',
map: 'china',
label: {
show: true,
color: 'rgb(249, 249, 249)',
fontSize: 10,
},
itemStyle: {
areaColor: '#2f82ce',
borderColor: '#0DAAC1',
},
data: mapData,
},
],
});
});
return { chartRef };
height: {
type: String as PropType<string>,
default: 'calc(100vh - 78px)',
},
});
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
onMounted(async () => {
const json = (await (await import('./china.json')).default) as any;
registerMap('china', json);
setOptions({
visualMap: [
{
min: 0,
max: 1000,
left: 'left',
top: 'bottom',
text: ['高', '低'],
calculable: false,
orient: 'horizontal',
inRange: {
color: ['#e0ffff', '#006edd'],
symbolSize: [30, 100],
},
},
],
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(0, 0, 0, .6)',
textStyle: {
color: '#fff',
fontSize: 12,
},
},
series: [
{
name: 'iphone4',
type: 'map',
map: 'china',
label: {
show: true,
color: 'rgb(249, 249, 249)',
fontSize: 10,
},
itemStyle: {
areaColor: '#2f82ce',
borderColor: '#0DAAC1',
},
data: mapData,
},
],
});
});
</script>

View File

@ -1,146 +1,141 @@
<template>
<div ref="chartRef" :style="{ height, width }"></div>
</template>
<script lang="ts">
import { defineComponent, PropType, ref, Ref, onMounted } from 'vue';
<script lang="ts" setup>
import { PropType, ref, Ref, onMounted } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import { useECharts } from '/@/hooks/web/useECharts';
export default defineComponent({
props: {
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: 'calc(100vh - 78px)',
},
defineProps({
width: {
type: String as PropType<string>,
default: '100%',
},
setup() {
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
const dataAll = [389, 259, 262, 324, 232, 176, 196, 214, 133, 370];
const yAxisData = [
'原因1',
'原因2',
'原因3',
'原因4',
'原因5',
'原因6',
'原因7',
'原因8',
'原因9',
'原因10',
];
onMounted(() => {
setOptions({
backgroundColor: '#0f375f',
title: [
{
text: '各渠道投诉占比',
left: '2%',
top: '1%',
textStyle: {
color: '#fff',
fontSize: 14,
},
},
{
text: '投诉原因TOP10',
left: '40%',
top: '1%',
textStyle: {
color: '#fff',
fontSize: 14,
},
},
{
text: '各级别投诉占比',
left: '2%',
top: '50%',
textStyle: {
color: '#fff',
fontSize: 14,
},
},
],
grid: [{ left: '50%', top: '7%', width: '45%', height: '90%' }],
tooltip: {
formatter: '{b} ({c})',
},
xAxis: [
{
gridIndex: 0,
axisTick: { show: false },
axisLabel: { show: false },
splitLine: { show: false },
axisLine: { show: false },
},
],
yAxis: [
{
gridIndex: 0,
interval: 0,
data: yAxisData.reverse(),
axisTick: { show: false },
axisLabel: { show: true },
splitLine: { show: false },
axisLine: { show: true, lineStyle: { color: '#6173a3' } },
},
],
series: [
{
name: '各渠道投诉占比',
type: 'pie',
radius: '30%',
center: ['22%', '25%'],
data: [
{ value: 335, name: '客服电话' },
{ value: 310, name: '奥迪官网' },
{ value: 234, name: '媒体曝光' },
{ value: 135, name: '质检总局' },
{ value: 105, name: '其他' },
],
labelLine: { show: false },
label: {
show: true,
formatter: '{b} \n ({d}%)',
color: '#B1B9D3',
},
},
{
name: '各级别投诉占比',
type: 'pie',
radius: '30%',
center: ['22%', '75%'],
labelLine: { show: false },
data: [
{ value: 335, name: 'A级' },
{ value: 310, name: 'B级' },
{ value: 234, name: 'C级' },
{ value: 135, name: 'D级' },
],
label: {
show: true,
formatter: '{b} \n ({d}%)',
color: '#B1B9D3',
},
},
{
name: '投诉原因TOP10',
type: 'bar',
xAxisIndex: 0,
yAxisIndex: 0,
barWidth: '45%',
itemStyle: { color: '#86c9f4' },
label: { show: true, position: 'right', color: '#9EA7C4' },
data: dataAll.sort(),
},
],
});
});
return { chartRef };
height: {
type: String as PropType<string>,
default: 'calc(100vh - 78px)',
},
});
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
const dataAll = [389, 259, 262, 324, 232, 176, 196, 214, 133, 370];
const yAxisData = [
'原因1',
'原因2',
'原因3',
'原因4',
'原因5',
'原因6',
'原因7',
'原因8',
'原因9',
'原因10',
];
onMounted(() => {
setOptions({
backgroundColor: '#0f375f',
title: [
{
text: '各渠道投诉占比',
left: '2%',
top: '1%',
textStyle: {
color: '#fff',
fontSize: 14,
},
},
{
text: '投诉原因TOP10',
left: '40%',
top: '1%',
textStyle: {
color: '#fff',
fontSize: 14,
},
},
{
text: '各级别投诉占比',
left: '2%',
top: '50%',
textStyle: {
color: '#fff',
fontSize: 14,
},
},
],
grid: [{ left: '50%', top: '7%', width: '45%', height: '90%' }],
tooltip: {
formatter: '{b} ({c})',
},
xAxis: [
{
gridIndex: 0,
axisTick: { show: false },
axisLabel: { show: false },
splitLine: { show: false },
axisLine: { show: false },
},
],
yAxis: [
{
gridIndex: 0,
interval: 0,
data: yAxisData.reverse(),
axisTick: { show: false },
axisLabel: { show: true },
splitLine: { show: false },
axisLine: { show: true, lineStyle: { color: '#6173a3' } },
},
],
series: [
{
name: '各渠道投诉占比',
type: 'pie',
radius: '30%',
center: ['22%', '25%'],
data: [
{ value: 335, name: '客服电话' },
{ value: 310, name: '奥迪官网' },
{ value: 234, name: '媒体曝光' },
{ value: 135, name: '质检总局' },
{ value: 105, name: '其他' },
],
labelLine: { show: false },
label: {
show: true,
formatter: '{b} \n ({d}%)',
color: '#B1B9D3',
},
},
{
name: '各级别投诉占比',
type: 'pie',
radius: '30%',
center: ['22%', '75%'],
labelLine: { show: false },
data: [
{ value: 335, name: 'A级' },
{ value: 310, name: 'B级' },
{ value: 234, name: 'C级' },
{ value: 135, name: 'D级' },
],
label: {
show: true,
formatter: '{b} \n ({d}%)',
color: '#B1B9D3',
},
},
{
name: '投诉原因TOP10',
type: 'bar',
xAxisIndex: 0,
yAxisIndex: 0,
barWidth: '45%',
itemStyle: { color: '#86c9f4' },
label: { show: true, position: 'right', color: '#9EA7C4' },
data: dataAll.sort(),
},
],
});
});
</script>

View File

@ -3,99 +3,93 @@
<div ref="chartRef" :style="{ width, height }"></div>
</Card>
</template>
<script lang="ts">
<script lang="ts" setup>
import type { Ref } from 'vue';
import { defineComponent, ref, watch } from 'vue';
import { ref, watch } from 'vue';
import { Card } from 'ant-design-vue';
import { useECharts } from '/@/hooks/web/useECharts';
import { useECharts } from '@/hooks/web/useECharts';
export default defineComponent({
components: { Card },
props: {
loading: Boolean,
width: {
type: String as PropType<string>,
default: '100%',
},
height: {
type: String as PropType<string>,
default: '400px',
},
const props = defineProps({
loading: Boolean,
width: {
type: String as PropType<string>,
default: '100%',
},
setup(props) {
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
watch(
() => props.loading,
() => {
if (props.loading) {
return;
}
setOptions({
legend: {
bottom: 0,
data: ['Visits', 'Sales'],
},
tooltip: {},
radar: {
radius: '60%',
splitNumber: 8,
indicator: [
{
name: '2017',
},
{
name: '2017',
},
{
name: '2018',
},
{
name: '2019',
},
{
name: '2020',
},
{
name: '2021',
},
],
},
series: [
{
type: 'radar',
symbolSize: 0,
areaStyle: {
shadowBlur: 0,
shadowColor: 'rgba(0,0,0,.2)',
shadowOffsetX: 0,
shadowOffsetY: 10,
opacity: 1,
},
data: [
{
value: [90, 50, 86, 40, 50, 20],
name: 'Visits',
itemStyle: {
color: '#9f8ed7',
},
},
{
value: [70, 75, 70, 76, 20, 85],
name: 'Sales',
itemStyle: {
color: '#1edec5',
},
},
],
},
],
});
},
{ immediate: true },
);
return { chartRef };
height: {
type: String as PropType<string>,
default: '400px',
},
});
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
watch(
() => props.loading,
() => {
if (props.loading) {
return;
}
setOptions({
legend: {
bottom: 0,
data: ['Visits', 'Sales'],
},
tooltip: {},
radar: {
radius: '60%',
splitNumber: 8,
indicator: [
{
name: '2017',
},
{
name: '2017',
},
{
name: '2018',
},
{
name: '2019',
},
{
name: '2020',
},
{
name: '2021',
},
],
},
series: [
{
type: 'radar',
symbolSize: 0,
areaStyle: {
shadowBlur: 0,
shadowColor: 'rgba(0,0,0,.2)',
shadowOffsetX: 0,
shadowOffsetY: 10,
opacity: 1,
},
data: [
{
value: [90, 50, 86, 40, 50, 20],
name: 'Visits',
itemStyle: {
color: '#9f8ed7',
},
},
{
value: [70, 75, 70, 76, 20, 85],
name: 'Sales',
itemStyle: {
color: '#1edec5',
},
},
],
},
],
});
},
{ immediate: true },
);
</script>

View File

@ -1,46 +1,42 @@
<template>
<div ref="wrapRef" :style="{ height, width }"></div>
</template>
<script lang="ts">
import { defineComponent, ref, nextTick, unref, onMounted } from 'vue';
<script lang="ts" setup>
import { ref, nextTick, unref, onMounted } from 'vue';
import { useScript } from '@/hooks/web/useScript';
import { useScript } from '/@/hooks/web/useScript';
defineOptions({ name: 'BaiduMap' });
defineProps({
width: {
type: String,
default: '100%',
},
height: {
type: String,
default: 'calc(100vh - 78px)',
},
});
const BAI_DU_MAP_URL =
'https://api.map.baidu.com/getscript?v=3.0&ak=OaBvYmKX3pjF7YFUFeeBCeGdy9Zp7xB2&services=&t=20210201100830&s=1';
export default defineComponent({
name: 'BaiduMap',
props: {
width: {
type: String,
default: '100%',
},
height: {
type: String,
default: 'calc(100vh - 78px)',
},
},
setup() {
const wrapRef = ref<HTMLDivElement | null>(null);
const { toPromise } = useScript({ src: BAI_DU_MAP_URL });
async function initMap() {
await toPromise();
await nextTick();
const wrapEl = unref(wrapRef);
if (!wrapEl) return;
const BMap = (window as any).BMap;
const map = new BMap.Map(wrapEl);
const point = new BMap.Point(116.404, 39.915);
map.centerAndZoom(point, 15);
map.enableScrollWheelZoom(true);
}
const wrapRef = ref<HTMLDivElement | null>(null);
const { toPromise } = useScript({ src: BAI_DU_MAP_URL });
onMounted(() => {
initMap();
});
async function initMap() {
await toPromise();
await nextTick();
const wrapEl = unref(wrapRef);
if (!wrapEl) return;
const BMap = (window as any).BMap;
const map = new BMap.Map(wrapEl);
const point = new BMap.Point(116.404, 39.915);
map.centerAndZoom(point, 15);
map.enableScrollWheelZoom(true);
}
return { wrapRef };
},
onMounted(async () => {
await initMap();
});
</script>

View File

@ -1,47 +1,42 @@
<template>
<div ref="wrapRef" :style="{ height, width }"></div>
</template>
<script lang="ts">
import { defineComponent, ref, nextTick, unref, onMounted } from 'vue';
<script lang="ts" setup>
import { ref, nextTick, unref, onMounted } from 'vue';
import { useScript } from '@/hooks/web/useScript';
import { useScript } from '/@/hooks/web/useScript';
defineOptions({ name: 'AMap' });
defineProps({
width: {
type: String,
default: '100%',
},
height: {
type: String,
default: 'calc(100vh - 78px)',
},
});
const A_MAP_URL = 'https://webapi.amap.com/maps?v=2.0&key=d7bb98e7185300250dd5f918c12f484b';
export default defineComponent({
name: 'AMap',
props: {
width: {
type: String,
default: '100%',
},
height: {
type: String,
default: 'calc(100vh - 78px)',
},
},
setup() {
const wrapRef = ref<HTMLDivElement | null>(null);
const { toPromise } = useScript({ src: A_MAP_URL });
const wrapRef = ref<HTMLDivElement | null>(null);
const { toPromise } = useScript({ src: A_MAP_URL });
async function initMap() {
await toPromise();
await nextTick();
const wrapEl = unref(wrapRef);
if (!wrapEl) return;
const AMap = (window as any).AMap;
new AMap.Map(wrapEl, {
zoom: 11,
center: [116.397428, 39.90923],
viewMode: '3D',
});
}
async function initMap() {
await toPromise();
await nextTick();
const wrapEl = unref(wrapRef);
if (!wrapEl) return;
const AMap = (window as any).AMap;
new AMap.Map(wrapEl, {
zoom: 11,
center: [116.397428, 39.90923],
viewMode: '3D',
});
}
onMounted(() => {
initMap();
});
return { wrapRef };
},
onMounted(async () => {
await initMap();
});
</script>

View File

@ -1,53 +1,48 @@
<template>
<div ref="wrapRef" :style="{ height, width }"></div>
</template>
<script lang="ts">
import { defineComponent, ref, nextTick, unref, onMounted } from 'vue';
<script lang="ts" setup>
import { ref, nextTick, unref, onMounted } from 'vue';
import { useScript } from '@/hooks/web/useScript';
import { useScript } from '/@/hooks/web/useScript';
defineOptions({ name: 'GoogleMap' });
defineProps({
width: {
type: String,
default: '100%',
},
height: {
type: String,
default: 'calc(100vh - 78px)',
},
});
const MAP_URL =
'https://maps.googleapis.com/maps/api/js?key=AIzaSyBQWrGwj4gAzKndcbwD5favT9K0wgty_0&signed_in=true';
export default defineComponent({
name: 'GoogleMap',
props: {
width: {
type: String,
default: '100%',
},
height: {
type: String,
default: 'calc(100vh - 78px)',
},
},
setup() {
const wrapRef = ref<HTMLDivElement | null>(null);
const { toPromise } = useScript({ src: MAP_URL });
const wrapRef = ref<HTMLDivElement | null>(null);
const { toPromise } = useScript({ src: MAP_URL });
async function initMap() {
await toPromise();
await nextTick();
const wrapEl = unref(wrapRef);
if (!wrapEl) return;
const google = (window as any).google;
const latLng = { lat: 116.404, lng: 39.915 };
const map = new google.maps.Map(wrapEl, {
zoom: 4,
center: latLng,
});
new google.maps.Marker({
position: latLng,
map: map,
title: 'Hello World!',
});
}
async function initMap() {
await toPromise();
await nextTick();
const wrapEl = unref(wrapRef);
if (!wrapEl) return;
const google = (window as any).google;
const latLng = { lat: 116.404, lng: 39.915 };
const map = new google.maps.Map(wrapEl, {
zoom: 4,
center: latLng,
});
new google.maps.Marker({
position: latLng,
map: map,
title: 'Hello World!',
});
}
onMounted(() => {
initMap();
});
return { wrapRef };
},
onMounted(async () => {
await initMap();
});
</script>

View File

@ -4,9 +4,9 @@
title="基础组件"
content=" 基础组件依赖于ant-design-vue,组件库已有的基础组件,项目中不会再次进行demo展示二次封装组件除外"
>
<a-row :gutter="[20, 20]">
<a-col :xl="10" :lg="24">
<a-card title="BasicButton Color">
<Row :gutter="[20, 20]">
<Col :xl="10" :lg="24">
<Card title="BasicButton Color">
<div class="my-2">
<h3>success</h3>
<div class="py-2">
@ -47,10 +47,10 @@
<a-button ghost type="dashed" color="warning" class="ml-2"> 幽灵警告dashed </a-button>
<a-button ghost danger class="ml-2"> 幽灵危险 </a-button>
</div>
</a-card>
</a-col>
<a-col :xl="14" :lg="24">
<a-card title="BasicButton Types">
</Card>
</Col>
<Col :xl="14" :lg="24">
<Card title="BasicButton Types">
<div class="my-2">
<h3>primary</h3>
<a-button type="primary" preIcon="mdi:page-next-outline"> 主按钮 </a-button>
@ -97,17 +97,12 @@
<!-- <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>
</a-card>
</a-col>
</a-row>
</Card>
</Col>
</Row>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { PageWrapper } from '@/components/Page';
import { Card, Row, Col } from 'ant-design-vue';
export default defineComponent({
components: { PageWrapper, ACard: Card, ARow: Row, ACol: Col },
});
</script>

View File

@ -2,18 +2,17 @@
<PageWrapper title="卡片列表示例" content="基础封装">
<CardList :params="params" :api="demoListApi" @get-method="getMethod" @delete="handleDel">
<template #header>
<Button type="primary" color="error"> 按钮1 </Button>
<Button type="primary" color="success"> 按钮2 </Button>
<a-button type="primary" color="error"> 按钮1 </a-button>
<a-button type="primary" color="success"> 按钮2 </a-button>
</template>
</CardList>
</PageWrapper>
</template>
<script lang="ts" setup>
import { CardList } from '/@/components/CardList';
import { Button } from '/@/components/Button';
import { PageWrapper } from '/@/components/Page';
import { demoListApi } from '/@/api/demo/table';
import { useMessage } from '/@/hooks/web/useMessage';
import { CardList } from '@/components/CardList';
import { PageWrapper } from '@/components/Page';
import { demoListApi } from '@/api/demo/table';
import { useMessage } from '@/hooks/web/useMessage';
const { notification } = useMessage();
// api

View File

@ -35,20 +35,12 @@
</Card>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
<script lang="ts" setup>
import { Card } from 'ant-design-vue';
import { CountTo } from '/@/components/CountTo/index';
import { PageWrapper } from '/@/components/Page';
import { CountTo } from '@/components/CountTo/index';
import { PageWrapper } from '@/components/Page';
export default defineComponent({
components: {
Card,
CardGrid: Card.Grid,
CountTo,
PageWrapper,
},
});
const CardGrid = Card.Grid;
</script>
<style lang="less" scoped>
.count-to-demo {

View File

@ -1,7 +1,7 @@
<template>
<PageWrapper title="图片裁剪示例" content="需要开启测试接口服务才能进行上传测试!">
<CollapseContainer title="头像裁剪">
<CropperAvatar :uploadApi="uploadApi" :value="avatar" />
<CropperAvatar :uploadApi="uploadApi as any" :value="avatar" />
</CollapseContainer>
<CollapseContainer title="矩形裁剪" class="my-4">
@ -31,52 +31,30 @@
</CollapseContainer>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { PageWrapper } from '/@/components/Page';
import { CollapseContainer } from '/@/components/Container';
import { CropperImage, CropperAvatar } from '/@/components/Cropper';
import { uploadApi } from '/@/api/sys/upload';
import img from '/@/assets/images/header.jpg';
import { useUserStore } from '/@/store/modules/user';
<script lang="ts" setup>
import { ref } from 'vue';
import { PageWrapper } from '@/components/Page';
import { CollapseContainer } from '@/components/Container';
import { CropperImage, CropperAvatar } from '@/components/Cropper';
import { uploadApi } from '@/api/sys/upload';
import img from '@/assets/images/header.jpg';
import { useUserStore } from '@/store/modules/user';
export default defineComponent({
components: {
PageWrapper,
CropperImage,
CollapseContainer,
CropperAvatar,
},
setup() {
const info = ref('');
const cropperImg = ref('');
const circleInfo = ref('');
const circleImg = ref('');
const userStore = useUserStore();
const avatar = ref(userStore.getUserInfo?.avatar || '');
function handleCropend({ imgBase64, imgInfo }) {
info.value = imgInfo;
cropperImg.value = imgBase64;
}
const info = ref('');
const cropperImg = ref('');
const circleInfo = ref('');
const circleImg = ref('');
const userStore = useUserStore();
const avatar = ref(userStore.getUserInfo?.avatar || '');
function handleCropend({ imgBase64, imgInfo }) {
info.value = imgInfo;
cropperImg.value = imgBase64;
}
function handleCircleCropend({ imgBase64, imgInfo }) {
circleInfo.value = imgInfo;
circleImg.value = imgBase64;
}
return {
img,
info,
circleInfo,
cropperImg,
circleImg,
handleCropend,
handleCircleCropend,
avatar,
uploadApi: uploadApi as any,
};
},
});
function handleCircleCropend({ imgBase64, imgInfo }) {
circleInfo.value = imgInfo;
circleImg.value = imgBase64;
}
</script>
<style scoped>

View File

@ -22,10 +22,9 @@
<Description @register="register1" class="mt-4" />
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { Description, DescItem, useDescription } from '/@/components/Description/index';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { Description, DescItem, useDescription } from '@/components/Description';
import { PageWrapper } from '@/components/Page';
const mockData: Recordable = {
username: 'test',
@ -63,23 +62,16 @@
label: '地址',
},
];
export default defineComponent({
components: { Description, PageWrapper },
setup() {
const [register] = useDescription({
title: 'useDescription',
data: mockData,
schema: schema,
});
const [register] = useDescription({
title: 'useDescription',
data: mockData,
schema: schema,
});
const [register1] = useDescription({
title: '无边框',
bordered: false,
data: mockData,
schema: schema,
});
return { mockData, schema, register, register1 };
},
const [register1] = useDescription({
title: '无边框',
bordered: false,
data: mockData,
schema: schema,
});
</script>

View File

@ -1,14 +1,6 @@
<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 lang="ts" setup>
import { BasicDrawer } from '@/components/Drawer';
</script>

View File

@ -4,15 +4,8 @@
<a-button type="primary" @click="closeDrawer"> 内部关闭drawer </a-button>
</BasicDrawer>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
<script lang="ts" setup>
import { BasicDrawer, useDrawerInner } from '@/components/Drawer';
export default defineComponent({
components: { BasicDrawer },
setup() {
const [register, { closeDrawer }] = useDrawerInner();
return { register, closeDrawer };
},
});
const [register, { closeDrawer }] = useDrawerInner();
</script>

View File

@ -17,20 +17,12 @@
</template> -->
</BasicDrawer>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicDrawer } from '/@/components/Drawer';
<script lang="ts" setup>
import { BasicDrawer } from '@/components/Drawer';
export default defineComponent({
components: { BasicDrawer },
setup() {
return {
handleOk: () => {
console.log('=====================');
console.log('ok');
console.log('======================');
},
};
},
});
function handleOk() {
console.log('=====================');
console.log('ok');
console.log('======================');
}
</script>

View File

@ -5,11 +5,9 @@
</div>
</BasicDrawer>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
<script lang="ts" setup>
import { BasicDrawer, useDrawerInner } from '@/components/Drawer';
import { BasicForm, FormSchema, useForm } from '@/components/Form';
const schemas: FormSchema[] = [
{
@ -30,25 +28,19 @@
},
},
];
export default defineComponent({
components: { BasicDrawer, BasicForm },
setup() {
const [registerForm, { setFieldsValue }] = useForm({
labelWidth: 120,
schemas,
showActionButtonGroup: false,
actionColOptions: {
span: 24,
},
});
const [register] = useDrawerInner((data) => {
// 1
setFieldsValue({
field2: data.data,
field1: data.info,
});
});
return { register, schemas, registerForm };
const [registerForm, { setFieldsValue }] = useForm({
labelWidth: 120,
schemas,
showActionButtonGroup: false,
actionColOptions: {
span: 24,
},
});
const [register] = useDrawerInner((data) => {
// 1
setFieldsValue({
field2: data.data,
field1: data.info,
});
});
</script>

View File

@ -4,11 +4,6 @@
<template #titleToolbar> toolbar </template>
</BasicDrawer>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicDrawer } from '/@/components/Drawer';
export default defineComponent({
components: { BasicDrawer },
});
<script lang="ts" setup>
import { BasicDrawer } from '@/components/Drawer';
</script>

View File

@ -19,51 +19,32 @@
<Drawer5 @register="register5" />
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
<script lang="ts" setup>
import { Alert } from 'ant-design-vue';
import { useDrawer } from '/@/components/Drawer';
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';
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
export default defineComponent({
components: { Alert, PageWrapper, 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 }] = useDrawer();
const [register5, { openDrawer: openDrawer5 }] = useDrawer();
function send() {
openDrawer4(true, {
data: 'content',
info: 'Info',
});
}
function openDrawerLoading() {
openDrawer1();
setDrawerProps({ loading: true });
setTimeout(() => {
setDrawerProps({ loading: false });
}, 2000);
}
return {
register1,
openDrawer1,
register2,
openDrawer2,
register3,
openDrawer3,
register4,
register5,
openDrawer5,
send,
openDrawerLoading,
};
},
});
const [register1, { openDrawer: openDrawer1, setDrawerProps }] = useDrawer();
const [register2, { openDrawer: openDrawer2 }] = useDrawer();
const [register3, { openDrawer: openDrawer3 }] = useDrawer();
const [register4, { openDrawer: openDrawer4 }] = useDrawer();
const [register5, { openDrawer: openDrawer5 }] = useDrawer();
function send() {
openDrawer4(true, {
data: 'content',
info: 'Info',
});
}
function openDrawerLoading() {
openDrawer1();
setDrawerProps({ loading: true });
setTimeout(() => {
setDrawerProps({ loading: false });
}, 2000);
}
</script>

View File

@ -9,16 +9,8 @@
</PageWrapper>
</template>
<script lang="ts">
import { FlowChart } from '/@/components/FlowChart';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { FlowChart } from '@/components/FlowChart';
import { PageWrapper } from '@/components/Page';
import demoData from './dataTurbo.json';
export default {
components: { FlowChart, PageWrapper },
setup() {
return { demoData };
},
};
</script>

View File

@ -1,119 +1,103 @@
<template>
<PageWrapper v-loading="loadingRef" loading-tip="加载中..." title="Loading组件示例">
<div ref="wrapEl">
<a-alert message="组件方式" />
<Alert message="组件方式" />
<a-button class="my-4 mr-4" type="primary" @click="openCompFullLoading">
全屏 Loading
</a-button>
<a-button class="my-4" type="primary" @click="openCompAbsolute"> 容器内 Loading </a-button>
<Loading
:loading="loading"
:absolute="absolute"
:theme="theme"
:background="background"
:tip="tip"
:loading="compState.loading"
:absolute="compState.absolute"
:theme="compState.theme"
:background="compState.background"
:tip="compState.tip"
/>
<a-alert message="函数方式" />
<Alert message="函数方式" />
<a-button class="my-4 mr-4" type="primary" @click="openFnFullLoading">
全屏 Loading
</a-button>
<a-button class="my-4" type="primary" @click="openFnWrapLoading"> 容器内 Loading </a-button>
<a-alert message="指令方式" />
<Alert message="指令方式" />
<a-button class="my-4 mr-4" type="primary" @click="openDirectiveLoading">
打开指令Loading
</a-button>
</div>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs, ref } from 'vue';
import { Loading, useLoading } from '/@/components/Loading';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import { Loading, useLoading } from '@/components/Loading';
import { PageWrapper } from '@/components/Page';
import { Alert } from 'ant-design-vue';
export default defineComponent({
components: { Loading, PageWrapper, [Alert.name]: Alert },
setup() {
const wrapEl = ref<ElRef>(null);
const wrapEl = ref<ElRef>(null);
const loadingRef = ref(false);
const compState = reactive<{
absolute?: boolean;
loading?: boolean;
theme?: 'dark' | 'light';
background?: string;
tip?: string;
}>({
absolute: false,
loading: false,
theme: 'dark',
background: 'rgba(111,111,111,.7)',
tip: '加载中...',
});
const [openFullLoading, closeFullLoading] = useLoading({
tip: '加载中...',
});
const loadingRef = ref(false);
const compState = reactive<{
absolute?: boolean;
loading?: boolean;
theme?: 'dark' | 'light';
background?: string;
tip?: string;
}>({
absolute: false,
loading: false,
theme: 'dark',
background: 'rgba(111,111,111,.7)',
tip: '加载中...',
});
const [openFullLoading, closeFullLoading] = useLoading({
tip: '加载中...',
});
const [openWrapLoading, closeWrapLoading] = useLoading({
target: wrapEl,
props: {
tip: '加载中...',
absolute: true,
},
});
function openLoading(absolute: boolean) {
compState.absolute = absolute;
compState.loading = true;
setTimeout(() => {
compState.loading = false;
}, 2000);
}
function openCompFullLoading() {
openLoading(false);
}
function openCompAbsolute() {
openLoading(true);
}
function openFnFullLoading() {
openFullLoading();
setTimeout(() => {
closeFullLoading();
}, 2000);
}
function openFnWrapLoading() {
openWrapLoading();
setTimeout(() => {
closeWrapLoading();
}, 2000);
}
function openDirectiveLoading() {
loadingRef.value = true;
setTimeout(() => {
loadingRef.value = false;
}, 2000);
}
return {
openCompFullLoading,
openFnFullLoading,
openFnWrapLoading,
openCompAbsolute,
wrapEl,
loadingRef,
openDirectiveLoading,
...toRefs(compState),
};
const [openWrapLoading, closeWrapLoading] = useLoading({
target: wrapEl,
props: {
tip: '加载中...',
absolute: true,
},
});
function openLoading(absolute: boolean) {
compState.absolute = absolute;
compState.loading = true;
setTimeout(() => {
compState.loading = false;
}, 2000);
}
function openCompFullLoading() {
openLoading(false);
}
function openCompAbsolute() {
openLoading(true);
}
function openFnFullLoading() {
openFullLoading();
setTimeout(() => {
closeFullLoading();
}, 2000);
}
function openFnWrapLoading() {
openWrapLoading();
setTimeout(() => {
closeWrapLoading();
}, 2000);
}
function openDirectiveLoading() {
loadingRef.value = true;
setTimeout(() => {
loadingRef.value = false;
}, 2000);
}
</script>

View File

@ -11,7 +11,7 @@
<a-button type="primary" danger @click="setLines" :disabled="loading">点我更新内容</a-button>
</template>
<template v-if="loading">
<div class="empty-tips">加载中稍等3秒</div>
<div class="h-full text-center line-height-100px">加载中稍等3秒</div>
</template>
<template v-if="!loading">
<ul>
@ -20,47 +20,34 @@
</template>
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, ref, watch } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
<script lang="ts" setup>
import { ref, watch } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
export default defineComponent({
components: { BasicModal },
setup() {
const loading = ref(true);
const lines = ref(10);
const [register, { setModalProps, redoModalHeight }] = useModalInner();
const loading = ref(true);
const lines = ref(10);
const [register, { setModalProps, redoModalHeight }] = useModalInner();
watch(
() => lines.value,
() => {
redoModalHeight();
},
);
function handleShow(open: boolean) {
if (open) {
loading.value = true;
setModalProps({ loading: true, confirmLoading: true });
setTimeout(() => {
lines.value = Math.round(Math.random() * 30 + 5);
loading.value = false;
setModalProps({ loading: false, confirmLoading: false });
}, 3000);
}
}
function setLines() {
lines.value = Math.round(Math.random() * 20 + 10);
}
return { register, loading, handleShow, lines, setLines };
watch(
() => lines.value,
() => {
redoModalHeight();
},
});
</script>
<style scoped>
.empty-tips {
height: 100px;
line-height: 100px;
text-align: center;
);
function handleShow(open: boolean) {
if (open) {
loading.value = true;
setModalProps({ loading: true, confirmLoading: true });
setTimeout(() => {
lines.value = Math.round(Math.random() * 30 + 5);
loading.value = false;
setModalProps({ loading: false, confirmLoading: false });
}, 3000);
}
}
</style>
function setLines() {
lines.value = Math.round(Math.random() * 20 + 10);
}
</script>

View File

@ -6,24 +6,13 @@
:okButtonProps="{ disabled: true }"
>
<a-button type="primary" @click="closeModal" class="mr-2"> 从内部关闭弹窗 </a-button>
<a-button type="primary" @click="setModalProps"> 从内部修改title </a-button>
<a-button type="primary" @click="setModalProps({ title: 'Modal New Title' })">
从内部修改title
</a-button>
</BasicModal>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
<script lang="ts" setup>
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' });
},
};
},
});
const [register, { closeModal, setModalProps }] = useModalInner();
</script>

View File

@ -3,14 +3,6 @@
<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 lang="ts" setup>
import { BasicModal } from '@/components/Modal';
</script>

View File

@ -6,12 +6,12 @@
@visible-change="handleVisibleChange"
>
<div class="pt-3px pr-3px">
<BasicForm @register="registerForm" :model="model" />
<BasicForm @register="registerForm" :model="modelRef" />
</div>
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, ref, nextTick } from 'vue';
<script lang="ts" setup>
import { ref, nextTick } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
@ -34,53 +34,47 @@
},
},
];
export default defineComponent({
components: { BasicModal, BasicForm },
props: {
userData: { type: Object },
},
setup(props) {
const modelRef = ref({});
const [
registerForm,
// {
// // setFieldsValue,
// // setProps
// },
] = useForm({
labelWidth: 120,
schemas,
showActionButtonGroup: false,
actionColOptions: {
span: 24,
},
});
const [register] = useModalInner((data) => {
data && onDataReceive(data);
});
function onDataReceive(data) {
console.log('Data Received', data);
// 1;
// setFieldsValue({
// field2: data.data,
// field1: data.info,
// });
// // 2
modelRef.value = { field2: data.data, field1: data.info };
// setProps({
// model:{ field2: data.data, field1: data.info }
// })
}
function handleVisibleChange(v) {
v && props.userData && nextTick(() => onDataReceive(props.userData));
}
return { register, schemas, registerForm, model: modelRef, handleVisibleChange };
const props = defineProps({
userData: { type: Object },
});
const modelRef = ref({});
const [
registerForm,
// {
// // setFieldsValue,
// // setProps
// },
] = useForm({
labelWidth: 120,
schemas,
showActionButtonGroup: false,
actionColOptions: {
span: 24,
},
});
const [register] = useModalInner((data) => {
data && onDataReceive(data);
});
function onDataReceive(data) {
console.log('Data Received', data);
// 1;
// setFieldsValue({
// field2: data.data,
// field1: data.info,
// });
// // 2
modelRef.value = { field2: data.data, field1: data.info };
// setProps({
// model:{ field2: data.data, field1: data.info }
// })
}
function handleVisibleChange(v) {
v && props.userData && nextTick(() => onDataReceive(props.userData));
}
</script>

View File

@ -18,12 +18,12 @@
<a-button type="primary" class="my-4" @click="send"> 打开弹窗并传递数据 </a-button>
<Alert message="使用动态组件的方式在页面内使用多个弹窗" show-icon />
<a-space>
<Space>
<a-button type="primary" class="my-4" @click="openTargetModal(1)"> 打开弹窗1 </a-button>
<a-button type="primary" class="my-4" @click="openTargetModal(2)"> 打开弹窗2 </a-button>
<a-button type="primary" class="my-4" @click="openTargetModal(3)"> 打开弹窗3 </a-button>
<a-button type="primary" class="my-4" @click="openTargetModal(4)"> 打开弹窗4 </a-button>
</a-space>
</Space>
<Alert
message="使用函数方式创建Prompt适合较为简单的表单内容如果需要弹出较为复杂的内容请使用 Modal."
@ -44,97 +44,74 @@
<Modal4 @register="register4" />
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, shallowRef, ComponentOptions, ref, nextTick } from 'vue';
<script lang="ts" setup>
import { shallowRef, ComponentOptions, ref, nextTick } from 'vue';
import { Alert, Space, message } from 'ant-design-vue';
import { useModal } from '/@/components/Modal';
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';
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
import { type Nullable } from '@vben/types';
import { createPrompt } from '/@/components/Prompt';
import { createPrompt } from '@/components/Prompt';
export default defineComponent({
components: { Alert, Modal1, Modal2, Modal3, Modal4, PageWrapper, ASpace: Space },
setup() {
const currentModal = shallowRef<Nullable<ComponentOptions>>(null);
const [register1, { openModal: openModal1 }] = useModal();
const [register2, { openModal: openModal2 }] = useModal();
const [register3, { openModal: openModal3 }] = useModal();
const [register4, { openModal: openModal4 }] = useModal();
const modalOpen = ref<Boolean>(false);
const userData = ref<any>(null);
const currentModal = shallowRef<Nullable<ComponentOptions>>(null);
const [register1, { openModal: openModal1 }] = useModal();
const [register2, { openModal: openModal2 }] = useModal();
const [register3, { openModal: openModal3 }] = useModal();
const [register4, { openModal: openModal4 }] = useModal();
const modalOpen = ref<Boolean>(false);
const userData = ref<any>(null);
function send() {
openModal4(true, {
data: 'content',
info: 'Info',
});
}
function openModalLoading() {
openModal1(true);
// setModalProps({ loading: true });
// setTimeout(() => {
// setModalProps({ loading: false });
// }, 2000);
}
function send() {
openModal4(true, {
data: 'content',
info: 'Info',
});
}
function openModalLoading() {
openModal1(true);
// setModalProps({ loading: true });
// setTimeout(() => {
// setModalProps({ loading: false });
// }, 2000);
}
function openTargetModal(index: number) {
switch (index) {
case 1:
currentModal.value = Modal1 as ComponentOptions;
break;
case 2:
currentModal.value = Modal2 as ComponentOptions;
break;
case 3:
currentModal.value = Modal3 as ComponentOptions;
break;
default:
currentModal.value = Modal4 as ComponentOptions;
break;
}
nextTick(() => {
// `useModal` not working with dynamic component
// passing data through `userData` prop
userData.value = { data: Math.random(), info: 'Info222' };
// open the target modal
modalOpen.value = true;
});
}
function openTargetModal(index: number) {
switch (index) {
case 1:
currentModal.value = Modal1 as ComponentOptions;
break;
case 2:
currentModal.value = Modal2 as ComponentOptions;
break;
case 3:
currentModal.value = Modal3 as ComponentOptions;
break;
default:
currentModal.value = Modal4 as ComponentOptions;
break;
}
nextTick(() => {
// `useModal` not working with dynamic component
// passing data through `userData` prop
userData.value = { data: Math.random(), info: 'Info222' };
// open the target modal
modalOpen.value = true;
});
}
function handleCreatePrompt() {
createPrompt({
title: '请输入邮箱',
required: true,
label: '邮箱',
defaultValue: '默认邮箱',
onOK: async (email: string) => {
message.success('填写的邮箱地址为' + email);
},
inputType: 'Input',
});
}
return {
register1,
openModal1,
register2,
openModal2,
register3,
openModal3,
register4,
openModal4,
modalOpen,
userData,
openTargetModal,
send,
currentModal,
openModalLoading,
handleCreatePrompt,
};
},
});
function handleCreatePrompt() {
createPrompt({
title: '请输入邮箱',
required: true,
label: '邮箱',
defaultValue: '默认邮箱',
onOK: async (email: string) => {
message.success('填写的邮箱地址为' + email);
},
inputType: 'Input',
});
}
</script>

View File

@ -1,19 +1,15 @@
<template>
<PageWrapper title="二维码组件使用示例">
<div class="flex flex-wrap">
<CollapseContainer
title="基础示例"
:canExpan="true"
class="text-center mb-6 qrcode-demo-item"
>
<CollapseContainer title="基础示例" :canExpan="true" class="text-center mb-6 w-1/4 mr-6">
<QrCode :value="qrCodeUrl" />
</CollapseContainer>
<CollapseContainer title="渲染成img标签示例" class="text-center mb-6 qrcode-demo-item">
<CollapseContainer title="渲染成img标签示例" class="text-center mb-6 w-1/4 mr-6">
<QrCode :value="qrCodeUrl" tag="img" />
</CollapseContainer>
<CollapseContainer title="配置样式示例" class="text-center mb-6 qrcode-demo-item">
<CollapseContainer title="配置样式示例" class="text-center mb-6 w-1/4 mr-6">
<QrCode
:value="qrCodeUrl"
:options="{
@ -22,11 +18,11 @@
/>
</CollapseContainer>
<CollapseContainer title="本地logo示例" class="text-center mb-6 qrcode-demo-item">
<CollapseContainer title="本地logo示例" class="text-center mb-6 w-1/4 mr-6">
<QrCode :value="qrCodeUrl" :logo="LogoImg" />
</CollapseContainer>
<CollapseContainer title="在线logo示例" class="text-center mb-6 qrcode-demo-item">
<CollapseContainer title="在线logo示例" class="text-center mb-6 w-1/4 mr-6">
<QrCode
:value="qrCodeUrl"
logo="https://vebn.oss-cn-beijing.aliyuncs.com/vben/logo.png"
@ -36,7 +32,7 @@
/>
</CollapseContainer>
<CollapseContainer title="logo配置示例" class="text-center mb-6 qrcode-demo-item">
<CollapseContainer title="logo配置示例" class="text-center mb-6 w-1/4 mr-6">
<QrCode
:value="qrCodeUrl"
:logo="{
@ -49,17 +45,17 @@
/>
</CollapseContainer>
<CollapseContainer title="下载示例" class="text-center qrcode-demo-item">
<CollapseContainer title="下载示例" class="text-center w-1/4 mr-6">
<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">
<CollapseContainer title="配置大小示例" class="text-center w-1/4 mr-6">
<QrCode :value="qrCodeUrl" :width="300" />
</CollapseContainer>
<CollapseContainer title="扩展绘制示例" class="text-center qrcode-demo-item">
<CollapseContainer title="扩展绘制示例" class="text-center w-1/4 mr-6">
<QrCode
:value="qrCodeUrl"
:width="200"
@ -74,56 +70,36 @@
</div>
</PageWrapper>
</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';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { ref, unref } from 'vue';
import { QrCode, QrCodeActionType } from '@/components/Qrcode';
import LogoImg from '@/assets/images/logo.png';
import { CollapseContainer } from '@/components/Container';
import { PageWrapper } from '@/components/Page';
import { type Nullable } from '@vben/types';
const qrCodeUrl = 'https://www.vvbin.cn';
export default defineComponent({
components: { CollapseContainer, QrCode, PageWrapper },
setup() {
const qrRef = ref<Nullable<QrCodeActionType>>(null);
const qrDiyRef = ref<Nullable<QrCodeActionType>>(null);
function download() {
const qrEl = unref(qrRef);
if (!qrEl) return;
qrEl.download('文件名');
}
function downloadDiy() {
const qrEl = unref(qrDiyRef);
if (!qrEl) return;
qrEl.download('Qrcode');
}
function onQrcodeDone({ ctx }: any) {
if (ctx instanceof CanvasRenderingContext2D) {
//
ctx.fillStyle = 'black';
ctx.font = '16px "微软雅黑"';
ctx.textBaseline = 'bottom';
ctx.textAlign = 'center';
ctx.fillText('你帅你先扫', 100, 195, 200);
}
}
return {
onQrcodeDone,
qrCodeUrl,
LogoImg,
download,
downloadDiy,
qrRef,
qrDiyRef,
};
},
});
</script>
<style scoped>
.qrcode-demo-item {
width: 30%;
margin-right: 1%;
const qrRef = ref<Nullable<QrCodeActionType>>(null);
const qrDiyRef = ref<Nullable<QrCodeActionType>>(null);
function download() {
const qrEl = unref(qrRef);
if (!qrEl) return;
qrEl.download('文件名');
}
</style>
function downloadDiy() {
const qrEl = unref(qrDiyRef);
if (!qrEl) return;
qrEl.download('Qrcode');
}
function onQrcodeDone({ ctx }: any) {
if (ctx instanceof CanvasRenderingContext2D) {
//
ctx.fillStyle = 'black';
ctx.font = '16px "微软雅黑"';
ctx.textBaseline = 'bottom';
ctx.textAlign = 'center';
ctx.fillText('你帅你先扫', 100, 195, 200);
}
}
</script>

View File

@ -19,37 +19,27 @@
</div>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, ref, unref } from 'vue';
<script lang="ts" setup>
import { ref, unref } from 'vue';
import { ScrollContainer, ScrollActionType } from '/@/components/Container/index';
import { PageWrapper } from '/@/components/Page';
import { type Nullable } from '@vben/types';
export default defineComponent({
components: { ScrollContainer, PageWrapper },
setup() {
const scrollRef = ref<Nullable<ScrollActionType>>(null);
const getScroll = () => {
const scroll = unref(scrollRef);
if (!scroll) {
throw new Error('scroll is Null');
}
return scroll;
};
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,
};
},
});
function scrollTo(top: number) {
getScroll().scrollTo(top);
}
function scrollBottom() {
getScroll().scrollBottom();
}
</script>
<style lang="less" scoped>
.scroll-wrap {

View File

@ -23,12 +23,10 @@
</div>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { VScroll } from '/@/components/VirtualScroll/index';
<script lang="ts" setup>
import { VScroll } from '@/components/VirtualScroll/index';
import { Divider } from 'ant-design-vue';
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
const data = (() => {
const arr: any[] = [];
@ -39,12 +37,6 @@
}
return arr;
})();
export default defineComponent({
components: { VScroll: VScroll, Divider, PageWrapper },
setup() {
return { data: data };
},
});
</script>
<style lang="less" scoped>
.virtual-scroll-demo {

View File

@ -13,14 +13,9 @@
</div>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { ScrollContainer } from '/@/components/Container/index';
import { PageWrapper } from '/@/components/Page';
export default defineComponent({
components: { ScrollContainer, PageWrapper },
});
<script lang="ts" setup>
import { ScrollContainer } from '@/components/Container/index';
import { PageWrapper } from '@/components/Page';
</script>
<style lang="less" scoped>
.scroll-wrap {

View File

@ -11,17 +11,9 @@
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { StrengthMeter } from '/@/components/StrengthMeter';
import { PageWrapper } from '/@/components/Page';
export default defineComponent({
components: {
StrengthMeter,
PageWrapper,
},
});
<script lang="ts" setup>
import { StrengthMeter } from '@/components/StrengthMeter';
import { PageWrapper } from '@/components/Page';
</script>
<style lang="less" scoped>
.demo-wrap {

View File

@ -1,9 +1,9 @@
<template>
<PageWrapper title="时间组件示例">
<CollapseContainer title="基础示例">
<Time :value="time1" />
<Time :value="state.time1" />
<br />
<Time :value="time2" />
<Time :value="state.time2" />
</CollapseContainer>
<CollapseContainer title="定时更新" class="my-4">
@ -21,24 +21,15 @@
</CollapseContainer>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs } from 'vue';
import { PageWrapper } from '/@/components/Page';
import { Time } from '/@/components/Time';
import { CollapseContainer } from '/@/components/Container/index';
<script lang="ts" setup>
import { reactive } from 'vue';
import { PageWrapper } from '@/components/Page';
import { Time } from '@/components/Time';
import { CollapseContainer } from '@/components/Container';
export default defineComponent({
components: { PageWrapper, Time, CollapseContainer },
setup() {
const now = new Date().getTime();
const state = reactive({
time1: now - 60 * 3 * 1000,
time2: now - 86400 * 3 * 1000,
});
return {
...toRefs(state),
now,
};
},
const now = new Date().getTime();
const state = reactive({
time1: now - 60 * 3 * 1000,
time2: now - 86400 * 3 * 1000,
});
</script>

View File

@ -1,6 +1,6 @@
<template>
<PageWrapper title="上传组件示例">
<a-alert message="基础示例" />
<Alert message="基础示例" />
<BasicUpload
:maxSize="20"
:maxNumber="10"
@ -10,19 +10,18 @@
:accept="['image/*']"
/>
<a-alert message="嵌入表单,加入表单校验" />
<Alert message="嵌入表单,加入表单校验" />
<BasicForm @register="register" class="my-5" />
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicUpload } from '/@/components/Upload';
import { useMessage } from '/@/hooks/web/useMessage';
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { BasicUpload } from '@/components/Upload';
import { useMessage } from '@/hooks/web/useMessage';
import { BasicForm, FormSchema, useForm } from '@/components/Form';
import { PageWrapper } from '@/components/Page';
import { Alert } from 'ant-design-vue';
import { uploadApi } from '/@/api/sys/upload';
import { uploadApi } from '@/api/sys/upload';
const schemas: FormSchema[] = [
{
@ -38,24 +37,16 @@
},
},
];
export default defineComponent({
components: { BasicUpload, BasicForm, PageWrapper, [Alert.name]: Alert },
setup() {
const { createMessage } = useMessage();
const [register] = useForm({
labelWidth: 120,
schemas,
actionColOptions: {
span: 16,
},
});
return {
handleChange: (list: string[]) => {
createMessage.info(`已上传文件${JSON.stringify(list)}`);
},
uploadApi,
register,
};
const { createMessage } = useMessage();
const [register] = useForm({
labelWidth: 120,
schemas,
actionColOptions: {
span: 16,
},
});
function handleChange(list: string[]) {
createMessage.info(`已上传文件${JSON.stringify(list)}`);
}
</script>

View File

@ -5,29 +5,14 @@
</div>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { RotateDragVerify } from '/@/components/Verify/index';
<script lang="ts" setup>
import { RotateDragVerify } from '@/components/Verify';
import img from '/@/assets/images/header.jpg';
import img from '@/assets/images/header.jpg';
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
export default defineComponent({
components: { RotateDragVerify, PageWrapper },
setup() {
const handleSuccess = () => {
console.log('success!');
};
return {
handleSuccess,
img,
};
},
});
</script>
<style lang="less" scoped>
.bg-gray-700 {
background-color: #4a5568;
function handleSuccess() {
console.log('success!');
}
</style>
</script>

View File

@ -50,49 +50,30 @@
</div>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { BasicDragVerify, DragVerifyActionType, PassingData } from '/@/components/Verify/index';
import { useMessage } from '/@/hooks/web/useMessage';
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicDragVerify, DragVerifyActionType, PassingData } from '@/components/Verify';
import { useMessage } from '@/hooks/web/useMessage';
import { BugOutlined, RightOutlined } from '@ant-design/icons-vue';
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
import { type Nullable } from '@vben/types';
export default defineComponent({
components: { BasicDragVerify, BugOutlined, RightOutlined, PageWrapper },
setup() {
const { createMessage } = useMessage();
const el1 = ref<Nullable<DragVerifyActionType>>(null);
const el2 = ref<Nullable<DragVerifyActionType>>(null);
const el3 = ref<Nullable<DragVerifyActionType>>(null);
const el4 = ref<Nullable<DragVerifyActionType>>(null);
const el5 = ref<Nullable<DragVerifyActionType>>(null);
const { createMessage } = useMessage();
const el1 = ref<Nullable<DragVerifyActionType>>(null);
const el2 = ref<Nullable<DragVerifyActionType>>(null);
const el3 = ref<Nullable<DragVerifyActionType>>(null);
const el4 = ref<Nullable<DragVerifyActionType>>(null);
const el5 = ref<Nullable<DragVerifyActionType>>(null);
function handleSuccess(data: PassingData) {
const { time } = data;
createMessage.success(`校验成功,耗时${time}`);
}
function handleBtnClick(elRef: Nullable<DragVerifyActionType>) {
if (!elRef) {
return;
}
elRef.resume();
}
return {
handleSuccess,
el1,
el2,
el3,
el4,
el5,
handleBtnClick,
};
},
});
</script>
<style lang="less" scoped>
.bg-gray-700 {
background-color: #4a5568;
function handleSuccess(data: PassingData) {
const { time } = data;
createMessage.success(`校验成功,耗时${time}`);
}
</style>
function handleBtnClick(elRef: Nullable<DragVerifyActionType>) {
if (!elRef) {
return;
}
elRef.resume();
}
</script>

View File

@ -1,40 +1,40 @@
<template>
<PageWrapper title="代码编辑器组件示例" contentFullHeight fixedHeight contentBackground>
<template #extra>
<a-space size="middle">
<Space size="middle">
<a-button @click="showData" type="primary">获取数据</a-button>
<RadioGroup button-style="solid" v-model:value="modeValue" @change="handleModeChange">
<RadioButton value="application/json"> json数据 </RadioButton>
<RadioButton value="htmlmixed"> html代码 </RadioButton>
<RadioButton value="javascript"> javascript代码 </RadioButton>
</RadioGroup>
</a-space>
</Space>
</template>
<CodeEditor v-model:value="value" :mode="modeValue" />
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, ref, unref, h } from 'vue';
import { CodeEditor, JsonPreview, MODE } from '/@/components/CodeEditor';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { ref, unref, h } from 'vue';
import { CodeEditor, JsonPreview, MODE } from '@/components/CodeEditor';
import { PageWrapper } from '@/components/Page';
import { Radio, Space, Modal, type RadioGroupProps } from 'ant-design-vue';
const jsonData =
'{"name":"BeJson","url":"http://www.xxx.com","page":88,"isNonProfit":true,"address":{"street":"科技园路.","city":"江苏苏州","country":"中国"},"links":[{"name":"Google","url":"http://www.xxx.com"},{"name":"Baidu","url":"http://www.xxx.com"},{"name":"SoSo","url":"http://www.xxx.com"}]}';
const jsData = `
(() => {
var htmlRoot = document.getElementById('htmlRoot');
var theme = window.localStorage.getItem('__APP__DARK__MODE__');
if (htmlRoot && theme) {
htmlRoot.setAttribute('data-theme', theme);
theme = htmlRoot = null;
}
})();
(() => {
var htmlRoot = document.getElementById('htmlRoot');
var theme = window.localStorage.getItem('__APP__DARK__MODE__');
if (htmlRoot && theme) {
htmlRoot.setAttribute('data-theme', theme);
theme = htmlRoot = null;
}
})();
`;
const htmlData = `
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en" id="htmlRoot">
<head>
<meta charset="UTF-8" />
@ -53,46 +53,37 @@
</body>
</html>
`;
export default defineComponent({
components: {
CodeEditor,
PageWrapper,
RadioButton: Radio.Button,
RadioGroup: Radio.Group,
ASpace: Space,
},
setup() {
const modeValue = ref<MODE>(MODE.JSON);
const value = ref(jsonData);
const handleModeChange: RadioGroupProps['onChange'] = (e) => {
const mode = e.target.value;
if (mode === MODE.JSON) {
value.value = jsonData;
return;
}
if (mode === MODE.HTML) {
value.value = htmlData;
return;
}
if (mode === MODE.JS) {
value.value = jsData;
return;
}
};
const RadioButton = Radio.Button;
const RadioGroup = Radio.Group;
function showData() {
if (unref(modeValue) === 'application/json') {
Modal.info({
title: '编辑器当前值',
content: h(JsonPreview, { data: JSON.parse(value.value) }),
});
} else {
Modal.info({ title: '编辑器当前值', content: value.value });
}
}
const modeValue = ref<MODE>(MODE.JSON);
const value = ref(jsonData);
return { value, modeValue, handleModeChange, showData };
},
});
const handleModeChange: RadioGroupProps['onChange'] = (e) => {
const mode = e.target.value;
if (mode === MODE.JSON) {
value.value = jsonData;
return;
}
if (mode === MODE.HTML) {
value.value = htmlData;
return;
}
if (mode === MODE.JS) {
value.value = jsData;
return;
}
};
function showData() {
if (unref(modeValue) === 'application/json') {
Modal.info({
title: '编辑器当前值',
content: h(JsonPreview, { data: JSON.parse(value.value) }),
});
} else {
Modal.info({ title: '编辑器当前值', content: value.value });
}
}
</script>

View File

@ -11,13 +11,13 @@
</CollapseContainer>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, h } from 'vue';
import { BasicForm, FormSchema } from '/@/components/Form/index';
import { CollapseContainer } from '/@/components/Container/index';
import { useMessage } from '/@/hooks/web/useMessage';
import { MarkDown } from '/@/components/Markdown';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { h } from 'vue';
import { BasicForm, FormSchema } from '@/components/Form';
import { CollapseContainer } from '@/components/Container';
import { useMessage } from '@/hooks/web/useMessage';
import { MarkDown } from '@/components/Markdown';
import { PageWrapper } from '@/components/Page';
const schemas: FormSchema[] = [
{
@ -43,17 +43,9 @@
},
},
];
export default defineComponent({
components: { BasicForm, CollapseContainer, PageWrapper },
setup() {
const { createMessage } = useMessage();
const { createMessage } = useMessage();
return {
schemas,
handleSubmit: (values: any) => {
createMessage.success('click search,values:' + JSON.stringify(values));
},
};
},
});
function handleSubmit(values: any) {
createMessage.success('click search,values:' + JSON.stringify(values));
}
</script>

View File

@ -4,31 +4,28 @@
<a-button @click="toggleTheme" class="mb-2" type="primary"> 黑暗主题 </a-button>
<a-button @click="clearValue" class="mb-2" type="default"> 清空内容 </a-button>
<MarkDown
v-model:value="value"
v-model:value="valueRef"
@change="handleChange"
ref="markDownRef"
placeholder="这是占位文本"
/>
</div>
<div class="mt-2">
<a-card title="Markdown Viewer 组件演示">
<MarkdownViewer :value="value" />
</a-card>
<Card title="Markdown Viewer 组件演示">
<MarkdownViewer :value="valueRef" />
</Card>
</div>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, ref, unref } from 'vue';
<script lang="ts" setup>
import { ref, unref } from 'vue';
import { MarkDown, MarkDownActionType, MarkdownViewer } from '/@/components/Markdown';
import { PageWrapper } from '/@/components/Page';
import { Card } from 'ant-design-vue';
import { type Nullable } from '@vben/types';
export default defineComponent({
components: { MarkDown, PageWrapper, MarkdownViewer, ACard: Card },
setup() {
const markDownRef = ref<Nullable<MarkDownActionType>>(null);
const valueRef = ref(`
const markDownRef = ref<Nullable<MarkDownActionType>>(null);
const valueRef = ref(`
# 标题h1
##### 标题h5
@ -71,28 +68,18 @@
| 4 | 5 | 6 |
`);
function toggleTheme() {
const markDown = unref(markDownRef);
if (!markDown) return;
const vditor = markDown.getVditor();
vditor.setTheme('dark', 'dark', 'dracula');
}
function toggleTheme() {
const markDown = unref(markDownRef);
if (!markDown) return;
const vditor = markDown.getVditor();
vditor.setTheme('dark', 'dark', 'dracula');
}
function handleChange(v: string) {
valueRef.value = v;
}
function handleChange(v: string) {
valueRef.value = v;
}
function clearValue() {
valueRef.value = '';
}
return {
value: valueRef,
toggleTheme,
markDownRef,
handleChange,
clearValue,
};
},
});
function clearValue() {
valueRef.value = '';
}
</script>

View File

@ -11,13 +11,13 @@
</CollapseContainer>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, h } from 'vue';
import { BasicForm, FormSchema } from '/@/components/Form/index';
import { CollapseContainer } from '/@/components/Container/index';
import { useMessage } from '/@/hooks/web/useMessage';
import { Tinymce } from '/@/components/Tinymce/index';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { h } from 'vue';
import { BasicForm, FormSchema } from '@/components/Form';
import { CollapseContainer } from '@/components/Container';
import { useMessage } from '@/hooks/web/useMessage';
import { Tinymce } from '@/components/Tinymce';
import { PageWrapper } from '@/components/Page';
const schemas: FormSchema[] = [
{
@ -43,17 +43,9 @@
},
},
];
export default defineComponent({
components: { BasicForm, CollapseContainer, PageWrapper },
setup() {
const { createMessage } = useMessage();
const { createMessage } = useMessage();
return {
schemas,
handleSubmit: (values: any) => {
createMessage.success('click search,values:' + JSON.stringify(values));
},
};
},
});
function handleSubmit(values: any) {
createMessage.success('click search,values:' + JSON.stringify(values));
}
</script>

View File

@ -3,19 +3,13 @@
<Tinymce v-model="value" @change="handleChange" width="100%" />
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { Tinymce } from '/@/components/Tinymce/index';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { ref } from 'vue';
import { Tinymce } from '@/components/Tinymce';
import { PageWrapper } from '@/components/Page';
export default defineComponent({
components: { Tinymce, PageWrapper },
setup() {
const value = ref('hello world!');
function handleChange(value: string) {
console.log(value);
}
return { handleChange, value };
},
});
const value = ref('hello world!');
function handleChange(value: string) {
console.log(value);
}
</script>

View File

@ -9,50 +9,37 @@
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable } from '/@/components/Table';
import { aoaToSheetXlsx } from '/@/components/Excel';
<script lang="ts" setup>
import { BasicTable } from '@/components/Table';
import { aoaToSheetXlsx } from '@/components/Excel';
import { arrHeader, arrData, columns, data } from './data';
import { PageWrapper } from '/@/components/Page';
import { aoaToMultipleSheetXlsx } from '/@/components/Excel/src/Export2Excel';
import { PageWrapper } from '@/components/Page';
import { aoaToMultipleSheetXlsx } from '@/components/Excel/src/Export2Excel';
export default defineComponent({
components: { BasicTable, PageWrapper },
setup() {
function aoaToExcel() {
// dataheader
aoaToSheetXlsx({
function aoaToExcel() {
// dataheader
aoaToSheetXlsx({
data: arrData,
header: arrHeader,
filename: '二维数组方式导出excel.xlsx',
});
}
function aoaToMultipleSheet() {
// dataheader
aoaToMultipleSheetXlsx({
sheetList: [
{
data: arrData,
header: arrHeader,
filename: '二维数组方式导出excel.xlsx',
});
}
function aoaToMultipleSheet() {
// dataheader
aoaToMultipleSheetXlsx({
sheetList: [
{
data: arrData,
header: arrHeader,
sheetName: 'Sheet1',
},
{
data: arrData,
header: arrHeader,
sheetName: 'Sheet2',
},
],
filename: '二维数组方式导出excel-多Sheet示例.xlsx',
});
}
return {
aoaToExcel,
aoaToMultipleSheet,
columns,
data,
};
},
});
sheetName: 'Sheet1',
},
{
data: arrData,
header: arrHeader,
sheetName: 'Sheet2',
},
],
filename: '二维数组方式导出excel-多Sheet示例.xlsx',
});
}
</script>

View File

@ -9,36 +9,22 @@
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable } from '/@/components/Table';
import { jsonToSheetXlsx, ExpExcelModal, ExportModalResult } from '/@/components/Excel';
<script lang="ts" setup>
import { BasicTable } from '@/components/Table';
import { jsonToSheetXlsx, ExpExcelModal, ExportModalResult } from '@/components/Excel';
import { columns, data } from './data';
import { useModal } from '/@/components/Modal';
import { PageWrapper } from '/@/components/Page';
import { useModal } from '@/components/Modal';
import { PageWrapper } from '@/components/Page';
export default defineComponent({
components: { BasicTable, ExpExcelModal, PageWrapper },
setup() {
function defaultHeader({ filename, bookType }: ExportModalResult) {
// Object.keys(data[0])header
jsonToSheetXlsx({
data,
filename,
write2excelOpts: {
bookType,
},
});
}
const [register, { openModal }] = useModal();
return {
defaultHeader,
columns,
data,
register,
openModal,
};
},
});
function defaultHeader({ filename, bookType }: ExportModalResult) {
// Object.keys(data[0])header
jsonToSheetXlsx({
data,
filename,
write2excelOpts: {
bookType,
},
});
}
const [register, { openModal }] = useModal();
</script>

View File

@ -12,46 +12,35 @@
/>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
<script lang="ts" setup>
import { ref } from 'vue';
import { ImpExcel, ExcelData } from '/@/components/Excel';
import { BasicTable, BasicColumn } from '/@/components/Table';
import { PageWrapper } from '/@/components/Page';
import { ImpExcel, ExcelData } from '@/components/Excel';
import { BasicTable, BasicColumn } from '@/components/Table';
import { PageWrapper } from '@/components/Page';
export default defineComponent({
components: { BasicTable, ImpExcel, PageWrapper },
const tableListRef = ref<
{
title: string;
columns?: any[];
dataSource?: any[];
}[]
>([]);
setup() {
const tableListRef = ref<
{
title: string;
columns?: any[];
dataSource?: any[];
}[]
>([]);
function loadDataSuccess(excelDataList: ExcelData[]) {
tableListRef.value = [];
console.log(excelDataList);
for (const excelData of excelDataList) {
const {
header,
results,
meta: { sheetName },
} = excelData;
const columns: BasicColumn[] = [];
for (const title of header) {
columns.push({ title, dataIndex: title });
}
tableListRef.value.push({ title: sheetName, dataSource: results, columns });
}
function loadDataSuccess(excelDataList: ExcelData[]) {
tableListRef.value = [];
console.log(excelDataList);
for (const excelData of excelDataList) {
const {
header,
results,
meta: { sheetName },
} = excelData;
const columns: BasicColumn[] = [];
for (const title of header) {
columns.push({ title, dataIndex: title });
}
return {
loadDataSuccess,
tableListRef,
};
},
});
tableListRef.value.push({ title: sheetName, dataSource: results, columns });
}
}
</script>

View File

@ -10,27 +10,49 @@
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable } from '/@/components/Table';
import { jsonToSheetXlsx } from '/@/components/Excel';
<script lang="ts" setup>
import { BasicTable } from '@/components/Table';
import { jsonToSheetXlsx } from '@/components/Excel';
import { columns, data } from './data';
import { PageWrapper } from '/@/components/Page';
import { jsonToMultipleSheetXlsx } from '/@/components/Excel/src/Export2Excel';
import { PageWrapper } from '@/components/Page';
import { jsonToMultipleSheetXlsx } from '@/components/Excel/src/Export2Excel';
export default defineComponent({
components: { BasicTable, PageWrapper },
setup() {
function defaultHeader() {
// Object.keys(data[0])header
jsonToSheetXlsx({
function defaultHeader() {
// Object.keys(data[0])header
jsonToSheetXlsx({
data,
filename: '使用key作为默认头部.xlsx',
});
}
function customHeader() {
jsonToSheetXlsx({
data,
header: {
id: 'ID',
name: '姓名',
age: '年龄',
no: '编号',
address: '地址',
beginTime: '开始时间',
endTime: '结束时间',
},
filename: '自定义头部.xlsx',
json2sheetOpts: {
//
header: ['name', 'id'],
},
});
}
function handleMultipleSheet() {
jsonToMultipleSheetXlsx({
sheetList: [
{
data,
filename: '使用key作为默认头部.xlsx',
});
}
function customHeader() {
jsonToSheetXlsx({
sheetName: '使用key作为默认头部',
},
{
data,
header: {
id: 'ID',
@ -41,49 +63,14 @@
beginTime: '开始时间',
endTime: '结束时间',
},
filename: '自定义头部.xlsx',
json2sheetOpts: {
//
header: ['name', 'id'],
},
});
}
function handleMultipleSheet() {
jsonToMultipleSheetXlsx({
sheetList: [
{
data,
sheetName: '使用key作为默认头部',
},
{
data,
header: {
id: 'ID',
name: '姓名',
age: '年龄',
no: '编号',
address: '地址',
beginTime: '开始时间',
endTime: '结束时间',
},
json2sheetOpts: {
//
header: ['name', 'id'],
},
sheetName: '自定义头部',
},
],
filename: '多Sheet导出示例.xlsx',
});
}
return {
defaultHeader,
customHeader,
handleMultipleSheet,
columns,
data,
};
},
});
sheetName: '自定义头部',
},
],
filename: '多Sheet导出示例.xlsx',
});
}
</script>

View File

@ -1,4 +1,4 @@
import { BasicColumn } from '/@/components/Table';
import { BasicColumn } from '@/components/Table';
export const columns: BasicColumn[] = [
{

View File

@ -3,7 +3,6 @@
<router-link to="/feat/breadcrumb/children/childrenDetail"> 进入子级详情页 </router-link>
</PageWrapper>
</template>
<script lang="ts" setup>
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
</script>

View File

@ -3,7 +3,6 @@
<div>子级详情页内容在此</div>
</PageWrapper>
</template>
<script lang="ts" setup>
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
</script>

View File

@ -4,5 +4,5 @@
</PageWrapper>
</template>
<script lang="ts" setup>
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
</script>

View File

@ -1,7 +1,10 @@
<template>
<PageWrapper title="点内外部触发事件">
<ClickOutSide @click-outside="handleClickOutside" class="flex justify-center">
<div @click="innerClick" class="demo-box">
<div
@click="innerClick"
class="flex items-center justify-center w-full h-300px border-10px bg-blue-500 text-white text-24px"
>
{{ text }}
</div>
</ClickOutSide>
@ -9,9 +12,8 @@
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { PageWrapper } from '/@/components/Page';
import { ClickOutSide } from '/@/components/ClickOutSide';
import { ClickOutSide } from '@/components/ClickOutSide';
import { PageWrapper } from '@/components/Page';
const text = ref('Click');
@ -23,17 +25,3 @@
text.value = 'Click Inner';
}
</script>
<style lang="less" scoped>
.demo-box {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 300px;
border-radius: 10px;
background-color: #408ede;
color: #fff;
font-size: 24px;
}
</style>

View File

@ -10,14 +10,13 @@
</PageWrapper>
</template>
<script lang="ts" setup>
import { useMessage } from '/@/hooks/web/useMessage';
import { useContextMenu } from '/@/hooks/web/useContextMenu';
import { useContextMenu } from '@/hooks/web/useContextMenu';
import { CollapseContainer } from '@/components/Container';
import { useMessage } from '@/hooks/web/useMessage';
import { PageWrapper } from '@/components/Page';
import { PageWrapper } from '/@/components/Page';
import { CollapseContainer } from '/@/components/Container';
const { createMessage } = useMessage();
const [createContextMenu] = useContextMenu();
const { createMessage } = useMessage();
function handleContext(e: MouseEvent) {
createContextMenu({

View File

@ -2,7 +2,7 @@
<PageWrapper title="文本复制示例">
<CollapseContainer class="w-full h-32 bg-white rounded-md" title="Copy Example">
<div class="flex justify-center">
<a-input placeholder="请输入" v-model:value="copyValue" />
<a-input placeholder="请输入" v-model:value="valueRef" />
<a-button type="primary" @click="handleCopy"> Copy </a-button>
</div>
</CollapseContainer>
@ -10,17 +10,16 @@
</template>
<script lang="ts" setup>
import { unref, ref } from 'vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { copyText } from '/@/utils/copyTextToClipboard';
import { CollapseContainer } from '@/components/Container/index';
import { useMessage } from '@/hooks/web/useMessage';
import { PageWrapper } from '@/components/Page';
import { copyText } from '@/utils/copyTextToClipboard';
import { PageWrapper } from '/@/components/Page';
import { CollapseContainer } from '/@/components/Container/index';
const copyValue = ref('');
const valueRef = ref('');
const { createMessage } = useMessage();
function handleCopy() {
const value = unref(copyValue);
const value = unref(valueRef);
if (!value) {
createMessage.warning('请输入要拷贝的内容!');
return;

View File

@ -1,15 +1,15 @@
<template>
<PageWrapper title="文件下载示例">
<a-alert message="根据后台接口文件流下载" />
<Alert message="根据后台接口文件流下载" />
<a-button type="primary" class="my-4" @click="handleDownByData"> 文件流下载 </a-button>
<a-alert message="根据文件地址下载文件" />
<Alert message="根据文件地址下载文件" />
<a-button type="primary" class="my-4" @click="handleDownloadByUrl"> 文件地址下载 </a-button>
<a-alert message="base64流下载" />
<Alert message="base64流下载" />
<a-button type="primary" class="my-4" @click="handleDownloadByBase64"> base64流下载 </a-button>
<a-alert message="图片Url下载,如果有跨域问题,需要处理图片跨域" />
<Alert message="图片Url下载,如果有跨域问题,需要处理图片跨域" />
<a-button type="primary" class="my-4" @click="handleDownloadByOnlineUrl">
图片Url下载
</a-button>
@ -21,17 +21,14 @@
downloadByData,
downloadByBase64,
downloadByOnlineUrl,
} from '/@/utils/file/download';
} from '@/utils/file/download';
import imgBase64 from './imgBase64';
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
import { Alert } from 'ant-design-vue';
const AAlert = Alert;
function handleDownByData() {
downloadByData('text content', 'testName.txt');
}
function handleDownloadByUrl() {
downloadByUrl({
url: 'https://codeload.github.com/anncwb/vue-vben-admin-doc/zip/master',

View File

@ -23,15 +23,19 @@
</PageWrapper>
</template>
<script lang="ts" setup>
import { PageWrapper } from '/@/components/Page';
import { EllipsisText } from '@/components/EllipsisText';
import { CollapseContainer } from '/@/components/Container/index';
import { ref } from 'vue';
import { CollapseContainer } from '@/components/Container';
import { PageWrapper } from '@/components/Page';
const text = `Vue-Vben-Admin 是一个基于 Vue3.0、Vite、 Ant-Design-Vue、TypeScript 的后台解决方案,目标是为开发中大型项目提供开箱即用的解决方案。
const text = ref(
`
Vue-Vben-Admin 是一个基于 Vue3.0Vite Ant-Design-VueTypeScript 的后台解决方案目标是为开发中大型项目提供开箱即用的解决方案
包括二次封装组件utilshooks动态菜单权限校验按钮级别权限控制等功能项目会使用前端较新的技术栈可以作为项目的启动模版以帮助你快速搭建企业级中后台产品原型
也可以作为一个示例用于学习 vue3vitets 等主流技术该项目会持续跟进最新技术并将其应用在项目中Vue-Vben-Admin 是一个基于 Vue3.0Vite Ant-Design-VueTypeScript 的后台解决方案目标是为开发中大型项目提供开箱即用的解决方案
包括二次封装组件utilshooks动态菜单权限校验按钮级别权限控制等功能项目会使用前端较新的技术栈可以作为项目的启动模版以帮助你快速搭建企业级中后台产品原型
也可以作为一个示例用于学习 vue3vitets 等主流技术该项目会持续跟进最新技术并将其应用在项目中Vue-Vben-Admin 是一个基于 Vue3.0Vite Ant-Design-VueTypeScript 的后台解决方案目标是为开发中大型项目提供开箱即用的解决方案
包括二次封装组件utilshooks动态菜单权限校验按钮级别权限控制等功能项目会使用前端较新的技术栈可以作为项目的启动模版以帮助你快速搭建企业级中后台产品原型
也可以作为一个示例用于学习 vue3vitets 等主流技术该项目会持续跟进最新技术并将其应用在项目中`;
也可以作为一个示例用于学习 vue3vitets 等主流技术该项目会持续跟进最新技术并将其应用在项目中
`,
);
</script>

View File

@ -27,12 +27,11 @@
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { CollapseContainer } from '@/components/Container';
import { useFullscreen } from '@vueuse/core';
import { CollapseContainer } from '/@/components/Container/index';
import { PageWrapper } from '/@/components/Page';
import type { Nullable } from '@vben/types';
import { PageWrapper } from '@/components/Page';
import { type Nullable } from '@vben/types';
const domRef = ref<Nullable<HTMLElement>>(null);

View File

@ -47,11 +47,13 @@
message="推荐使用Iconify组件"
description="Icon组件基本包含所有的图标,在下面网址内你可以查询到你想要的任何图标。并且打包只会打包所用到的图标。"
/>
<a-button type="link" @click="toIconify"> Iconify 图标大全 </a-button>
<a-button type="link" @click="openWindow('https://iconify.design/')">
Iconify 图标大全
</a-button>
</PageWrapper>
</template>
<script lang="ts" setup>
import { CollapseContainer } from '/@/components/Container/index';
import { CollapseContainer } from '@/components/Container';
import { Alert } from 'ant-design-vue';
import {
QqCircleFilled,
@ -62,14 +64,9 @@
TaobaoCircleFilled,
CodepenCircleFilled,
} from '@ant-design/icons-vue';
import { IconPicker, SvgIcon } from '@/components/Icon';
import Icon from '@/components/Icon/Icon.vue';
import { openWindow } from '@/utils';
import { PageWrapper } from '@/components/Page';
import { IconPicker, SvgIcon } from '/@/components/Icon/index';
import Icon from '/@/components/Icon/Icon.vue';
import { openWindow } from '/@/utils';
import { PageWrapper } from '/@/components/Page';
const toIconify = () => {
openWindow('https://iconify.design/');
};
</script>

View File

@ -4,10 +4,9 @@
<a-button @click="openImg" type="primary">无预览图</a-button>
</PageWrapper>
</template>
<script lang="ts" setup>
import { PageWrapper } from '/@/components/Page';
import { createImgPreview, ImagePreview } from '/@/components/Preview/index';
import { createImgPreview, ImagePreview } from '@/components/Preview';
import { PageWrapper } from '@/components/Page';
const imgList = [
'https://picsum.photos/id/66/346/216',

View File

@ -3,8 +3,8 @@
当前参数{{ computedParams }}
<br />
输入参数切换路由
<Input v-model:value="value" placeholder="建议为url标准字符输入后点击切换" />
<a-button type="primary" @click="handleClickGo">切换路由</a-button>
<a-input v-model:value="value" placeholder="建议为url标准字符输入后点击切换" />
<a-button type="primary" class="my-2" @click="handleClickGo">切换路由</a-button>
<br />
切换路由后
<ul>
@ -18,7 +18,7 @@
import { computed, ref, unref } from 'vue';
import { Input } from 'ant-design-vue';
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
const value = ref('');

View File

@ -1,14 +1,14 @@
<template>
<PageWrapper title="消息示例">
<CollapseContainer class="w-full h-32 bg-white 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">
<a-button @click="info('Info message')" class="mr-2"> Info </a-button>
<a-button @click="success('Success message')" class="mr-2" color="success">
Success
</a-button>
<a-button @click="warningMsg('Warning message')" class="mr-2" color="warning">
<a-button @click="warning('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="error('Error message')" class="mr-2" color="error"> Error </a-button>
<a-button @click="handleLoading" class="mr-2" type="primary"> Loading </a-button>
</CollapseContainer>
@ -35,10 +35,9 @@
</PageWrapper>
</template>
<script lang="ts" setup>
import { PageWrapper } from '/@/components/Page';
import { CollapseContainer } from '/@/components/Container/index';
import { useMessage } from '/@/hooks/web/useMessage';
import { CollapseContainer } from '@/components/Container';
import { useMessage } from '@/hooks/web/useMessage';
import { PageWrapper } from '@/components/Page';
const {
createMessage,
@ -50,17 +49,11 @@
notification,
} = useMessage();
const {
info: infoMsg,
success: successMsg,
warning: warningMsg,
error: errorMsg,
} = createMessage;
const { info, success, warning, error } = createMessage;
function handleLoading() {
createMessage.loading('Loading...');
}
function handleConfirm(type: 'warning' | 'error' | 'success' | 'info') {
createConfirm({
iconType: type,
@ -68,23 +61,18 @@
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',

View File

@ -8,11 +8,13 @@
</PageWrapper>
</template>
<script lang="ts" setup>
import { PageWrapper } from '/@/components/Page';
import { CollapseContainer } from '/@/components/Container/index';
import { PageWrapper } from '@/components/Page';
import { CollapseContainer } from '@/components/Container';
import printJS from 'print-js';
defineOptions({ name: 'AppLogo' });
function jsonPrint() {
printJS({
printable: [

View File

@ -1,23 +1,13 @@
<template>
<div class="request-box">
<div class="m-10">
<a-button @click="handleClick" type="primary"> 点击会重新发起请求5次 </a-button>
<p>打开浏览器的network面板可以看到发出了六次请求</p>
<p class="mt-4">打开浏览器的network面板可以看到发出了六次请求</p>
</div>
</template>
<script lang="ts" setup>
import { testRetry } from '/@/api/sys/user';
import { testRetry } from '@/api/sys/user';
// @ts-ignore
const handleClick = async () => {
await testRetry();
};
</script>
<style lang="less">
.request-box {
margin: 50px;
}
p {
margin-top: 10px;
}
</style>

View File

@ -1,31 +1,16 @@
<template>
<PageWrapper title="Ripple示例">
<div class="demo-box" v-ripple>content</div>
<div
class="flex item-center justify-center w-75 h-75 border-2 bg-blue-500 text-white text-24px"
v-ripple
>
content
</div>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import RippleDirective from '/@/directives/ripple';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import RippleDirective from '@/directives/ripple';
import { PageWrapper } from '@/components/Page';
export default defineComponent({
components: { PageWrapper },
directives: {
Ripple: RippleDirective,
},
});
const vRipple = RippleDirective;
</script>
<style lang="less" scoped>
.demo-box {
display: flex;
align-items: center;
justify-content: center;
width: 300px;
height: 300px;
border-radius: 10px;
background-color: #408ede;
color: #fff;
font-size: 24px;
}
</style>

View File

@ -3,26 +3,26 @@
title="登录过期示例"
content="用户登录过期示例,不再跳转登录页,直接生成页面覆盖当前页面,方便保持过期前的用户状态!"
>
<a-card title="请点击下面的按钮访问测试接口" extra="所访问的接口会返回Token过期响应">
<a-card-grid style="width: 50%; text-align: center">
<Card title="请点击下面的按钮访问测试接口" extra="所访问的接口会返回Token过期响应">
<CardGrid style="width: 50%; text-align: center">
<a-button type="primary" @click="test1">HttpStatus == 401</a-button>
</a-card-grid>
<a-card-grid style="width: 50%; text-align: center">
</CardGrid>
<CardGrid style="width: 50%; text-align: center">
<span></span>
<a-button class="ml-4" type="primary" @click="test2">Response.code == 401</a-button>
</a-card-grid>
</a-card>
</CardGrid>
</Card>
</PageWrapper>
</template>
<script lang="ts" setup>
import { PageWrapper } from '/@/components/Page';
import { useUserStore } from '/@/store/modules/user';
import { sessionTimeoutApi, tokenExpiredApi } from '/@/api/demo/account';
import { PageWrapper } from '@/components/Page';
import { useUserStore } from '@/store/modules/user';
import { sessionTimeoutApi, tokenExpiredApi } from '@/api/demo/account';
import { Card } from 'ant-design-vue';
const ACardGrid = Card.Grid;
const ACard = Card;
defineOptions({ name: 'TestSessionTimeout' });
const CardGrid = Card.Grid;
const userStore = useUserStore();
async function test1() {

View File

@ -5,15 +5,16 @@
</template>
<script lang="ts" setup>
import { PageWrapper } from '@/components/Page';
import { useTabs } from '@/hooks/web/useTabs';
import { useRoute } from 'vue-router';
import { useTabs } from '/@/hooks/web/useTabs';
import { PageWrapper } from '/@/components/Page';
defineOptions({ name: 'TabDetail' });
const route = useRoute();
const index = route.params?.id ?? -1;
const { setTitle } = useTabs();
//
setTitle(`No.${index} - 详情信息`);
</script>

View File

@ -1,10 +1,10 @@
<template>
<PageWrapper title="标签页操作示例">
<CollapseContainer title="在下面输入框输入文本,切换后回来内容会保存">
<a-alert banner message="该操作不会影响页面标题仅修改Tab标题" />
<Alert banner message="该操作不会影响页面标题仅修改Tab标题" />
<div class="mt-2 flex flex-grow-0">
<a-button class="mr-2" @click="setTabTitle" type="primary"> 设置Tab标题 </a-button>
<a-input placeholder="请输入" v-model:value="title" class="mr-4 w-12" />
<a-input placeholder="请输入" v-model:value="title" class="mr-4 w-50" />
</div>
</CollapseContainer>
@ -26,24 +26,18 @@
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { useGo } from '/@/hooks/web/usePage';
import { useTabs } from '/@/hooks/web/useTabs';
import { useMessage } from '/@/hooks/web/useMessage';
import { Input, Alert } from 'ant-design-vue';
import { PageWrapper } from '/@/components/Page';
import { CollapseContainer } from '/@/components/Container';
import { CollapseContainer } from '@/components/Container';
import { useTabs } from '@/hooks/web/useTabs';
import { PageWrapper } from '@/components/Page';
import { Alert } from 'ant-design-vue';
import { useMessage } from '@/hooks/web/useMessage';
import { useGo } from '@/hooks/web/usePage';
const AInput = Input;
const AAlert = Alert;
defineOptions({
name: 'TabsDemo',
});
defineOptions({ name: 'TabsDemo' });
const go = useGo();
const title = ref('');
const title = ref<string>('');
const { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage, setTitle } =
useTabs();
const { createMessage } = useMessage();

View File

@ -17,9 +17,9 @@
</template>
<script lang="ts" setup>
import { onUnmounted } from 'vue';
import { CollapseContainer } from '/@/components/Container/index';
import { useWatermark } from '/@/hooks/web/useWatermark';
import { PageWrapper } from '/@/components/Page';
import { CollapseContainer } from '@/components/Container';
import { useWatermark } from '@/hooks/web/useWatermark';
import { PageWrapper } from '@/components/Page';
const { setWatermark, clear, clearAll } = useWatermark();
const { setWatermark: setWatermark2 } = useWatermark();

View File

@ -9,7 +9,7 @@
<hr class="my-4" />
<div class="flex">
<a-input v-model:value="server" addon-before="服务地址" disabled />
<a-input v-model:value="state.server" addon-before="服务地址" disabled />
<a-button :type="getIsOpen ? 'danger' : 'primary'" @click="toggle">
{{ getIsOpen ? '关闭连接' : '开启连接' }}
</a-button>
@ -20,7 +20,7 @@
<InputTextArea
placeholder="需要发送到服务器的内容"
:disabled="!getIsOpen"
v-model:value="sendValue"
v-model:value="state.sendValue"
allowClear
/>
@ -50,76 +50,58 @@
</div>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, reactive, watchEffect, computed, toRefs } from 'vue';
<script lang="ts" setup>
import { reactive, watchEffect, computed } from 'vue';
import { Tag, Input } from 'ant-design-vue';
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
import { useWebSocket } from '@vueuse/core';
import { formatToDateTime } from '/@/utils/dateUtil';
import { formatToDateTime } from '@/utils/dateUtil';
export default defineComponent({
components: {
PageWrapper,
[Input.name]: Input,
InputTextArea: Input.TextArea,
Tag,
},
setup() {
const state = reactive({
server: 'ws://localhost:3300/test',
sendValue: '',
recordList: [] as { id: number; time: number; res: string }[],
});
const InputTextArea = Input.TextArea;
const { status, data, send, close, open } = useWebSocket(state.server, {
autoReconnect: false,
heartbeat: true,
});
watchEffect(() => {
if (data.value) {
try {
const res = JSON.parse(data.value);
state.recordList.push(res);
} catch (error) {
state.recordList.push({
res: data.value,
id: Math.ceil(Math.random() * 1000),
time: new Date().getTime(),
});
}
}
});
const getIsOpen = computed(() => status.value === 'OPEN');
const getTagColor = computed(() => (getIsOpen.value ? 'success' : 'red'));
const getList = computed(() => {
return [...state.recordList].reverse();
});
function handlerSend() {
send(state.sendValue);
state.sendValue = '';
}
function toggle() {
if (getIsOpen.value) {
close();
} else {
open();
}
}
return {
status,
formatToDateTime,
...toRefs(state),
handlerSend,
getList,
toggle,
getIsOpen,
getTagColor,
};
},
const state = reactive({
server: 'ws://localhost:3300/test',
sendValue: '',
recordList: [] as { id: number; time: number; res: string }[],
});
const { status, data, send, close, open } = useWebSocket(state.server, {
autoReconnect: false,
heartbeat: true,
});
watchEffect(() => {
if (data.value) {
try {
const res = JSON.parse(data.value);
state.recordList.push(res);
} catch (error) {
state.recordList.push({
res: data.value,
id: Math.ceil(Math.random() * 1000),
time: new Date().getTime(),
});
}
}
});
const getIsOpen = computed(() => status.value === 'OPEN');
const getTagColor = computed(() => (getIsOpen.value ? 'success' : 'red'));
const getList = computed(() => {
return [...state.recordList].reverse();
});
function handlerSend() {
send(state.sendValue);
state.sendValue = '';
}
function toggle() {
if (getIsOpen.value) {
close();
} else {
open();
}
}
</script>

View File

@ -9,11 +9,10 @@
</CollapseContainer>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
import { CollapseContainer } from '/@/components/Container';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { BasicForm, FormSchema, useForm } from '@/components/Form';
import { CollapseContainer } from '@/components/Container';
import { PageWrapper } from '@/components/Page';
const getSchamas = (): FormSchema[] => {
return [
@ -148,48 +147,39 @@
},
];
}
export default defineComponent({
components: { BasicForm, CollapseContainer, PageWrapper },
setup() {
const [register] = useForm({
labelWidth: 120,
schemas: getSchamas(),
actionColOptions: {
span: 24,
},
compact: true,
showAdvancedButton: true,
});
const extraSchemas: FormSchema[] = [];
for (let i = 14; i < 30; i++) {
extraSchemas.push({
field: 'field' + i,
component: 'Input',
label: '字段' + i,
colProps: {
span: 8,
},
});
}
const [register1] = useForm({
labelWidth: 120,
schemas: [
...getSchamas(),
...getAppendSchemas(),
{ field: '', component: 'Divider', label: '更多字段' },
...extraSchemas,
],
actionColOptions: {
span: 24,
},
compact: true,
showAdvancedButton: true,
alwaysShowLines: 2,
});
return {
register,
register1,
};
const [register] = useForm({
labelWidth: 120,
schemas: getSchamas(),
actionColOptions: {
span: 24,
},
compact: true,
showAdvancedButton: true,
});
const extraSchemas: FormSchema[] = [];
for (let i = 14; i < 30; i++) {
extraSchemas.push({
field: 'field' + i,
component: 'Input',
label: '字段' + i,
colProps: {
span: 8,
},
});
}
const [register1] = useForm({
labelWidth: 120,
schemas: [
...getSchamas(),
...getAppendSchemas(),
{ field: '', component: 'Divider', label: '更多字段' },
...extraSchemas,
],
actionColOptions: {
span: 24,
},
compact: true,
showAdvancedButton: true,
alwaysShowLines: 2,
});
</script>

View File

@ -3,131 +3,122 @@
<CollapseContainer title="表单增删">
<BasicForm @register="register" @submit="handleSubmit">
<template #add="{ field }">
<Button v-if="Number(field) === 0" @click="add">+</Button>
<Button class="ml-2" v-if="Number(field) === 0" @click="batchAdd">
<a-button v-if="Number(field) === 0" @click="add">+</a-button>
<a-button class="ml-2" v-if="Number(field) === 0" @click="batchAdd">
批量添加表单配置
</Button>
<Button v-if="Number(field) > 0" @click="() => del(field)">-</Button>
</a-button>
<a-button v-if="Number(field) > 0" @click="() => del(field)">-</a-button>
</template>
</BasicForm>
</CollapseContainer>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { BasicForm, useForm } from '/@/components/Form/index';
import { CollapseContainer } from '/@/components/Container';
import { Input } from 'ant-design-vue';
import { PageWrapper } from '/@/components/Page';
import { Button } from '/@/components/Button';
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicForm, useForm } from '@/components/Form';
import { CollapseContainer } from '@/components/Container';
import { PageWrapper } from '@/components/Page';
export default defineComponent({
components: { BasicForm, CollapseContainer, PageWrapper, [Input.name]: Input, Button },
setup() {
const [register, { appendSchemaByField, removeSchemaByField, validate }] = useForm({
schemas: [
{
field: 'field0a',
component: 'Input',
label: '字段0',
required: true,
},
{
field: 'field0b',
component: 'Input',
label: '字段0',
required: true,
},
{
field: '0',
component: 'Input',
label: ' ',
slot: 'add',
},
],
labelWidth: 100,
actionColOptions: { span: 24 },
baseColProps: { span: 8 },
});
async function handleSubmit() {
try {
const data = await validate();
console.log(data);
} catch (e) {
console.log(e);
}
}
const n = ref(1);
function add() {
appendSchemaByField(
{
field: `field${n.value}a`,
component: 'Input',
label: '字段' + n.value,
required: true,
},
'',
);
appendSchemaByField(
{
field: `field${n.value}b`,
component: 'Input',
label: '字段' + n.value,
required: true,
},
'',
);
appendSchemaByField(
{
field: `${n.value}`,
component: 'Input',
label: ' ',
slot: 'add',
},
'',
);
n.value++;
}
/**
* @description: 批量添加
*/
function batchAdd() {
appendSchemaByField(
[
{
field: `field${n.value}a`,
component: 'Input',
label: '字段' + n.value,
required: true,
},
{
field: `field${n.value}b`,
component: 'Input',
label: '字段' + n.value,
required: true,
},
{
field: `${n.value}`,
component: 'Input',
label: ' ',
slot: 'add',
},
],
'',
);
n.value++;
}
function del(field: string) {
removeSchemaByField([`field${field}a`, `field${field}b`, `${field}`]);
n.value--;
}
return { register, handleSubmit, add, del, batchAdd };
},
const [register, { appendSchemaByField, removeSchemaByField, validate }] = useForm({
schemas: [
{
field: 'field0a',
component: 'Input',
label: '字段0',
required: true,
},
{
field: 'field0b',
component: 'Input',
label: '字段0',
required: true,
},
{
field: '0',
component: 'Input',
label: ' ',
slot: 'add',
},
],
labelWidth: 100,
actionColOptions: { span: 24 },
baseColProps: { span: 8 },
});
async function handleSubmit() {
try {
const data = await validate();
console.log(data);
} catch (e) {
console.log(e);
}
}
const n = ref(1);
function add() {
appendSchemaByField(
{
field: `field${n.value}a`,
component: 'Input',
label: '字段' + n.value,
required: true,
},
'',
);
appendSchemaByField(
{
field: `field${n.value}b`,
component: 'Input',
label: '字段' + n.value,
required: true,
},
'',
);
appendSchemaByField(
{
field: `${n.value}`,
component: 'Input',
label: ' ',
slot: 'add',
},
'',
);
n.value++;
}
/**
* @description: 批量添加
*/
function batchAdd() {
appendSchemaByField(
[
{
field: `field${n.value}a`,
component: 'Input',
label: '字段' + n.value,
required: true,
},
{
field: `field${n.value}b`,
component: 'Input',
label: '字段' + n.value,
required: true,
},
{
field: `${n.value}`,
component: 'Input',
label: ' ',
slot: 'add',
},
],
'',
);
n.value++;
}
function del(field: string) {
removeSchemaByField([`field${field}a`, `field${field}b`, `${field}`]);
n.value--;
}
</script>

View File

@ -18,13 +18,13 @@
</CollapseContainer>
</PageWrapper>
</template>
<script lang="tsx">
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';
<script lang="tsx" setup>
import { h } from 'vue';
import { BasicForm, FormSchema, useForm } from '@/components/Form';
import { CollapseContainer } from '@/components/Container';
import { useMessage } from '@/hooks/web/useMessage';
import { Input, FormItem, FormItemRest, Select } from 'ant-design-vue';
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
const custom_typeKey2typeValueRules = (model) => {
return [
@ -218,28 +218,20 @@
labelWidth: 200,
},
];
export default defineComponent({
components: { BasicForm, CollapseContainer, PageWrapper, [Input.name]: Input, FormItem },
setup() {
const { createMessage } = useMessage();
const [register, { setProps }] = useForm({
labelWidth: 120,
schemas,
actionColOptions: {
span: 24,
},
});
return {
register,
schemas,
handleSubmit: (values: any) => {
console.log('submit values', values);
createMessage.success('click search,values:' + JSON.stringify(values));
},
setProps,
};
const { createMessage } = useMessage();
const [register] = useForm({
labelWidth: 120,
schemas,
actionColOptions: {
span: 24,
},
});
function handleSubmit(values: any) {
console.log('submit values', values);
createMessage.success('click search,values:' + JSON.stringify(values));
}
</script>
<style lang="less" scoped>
:deep(.local_form) .local_typeValue {

View File

@ -15,11 +15,10 @@
</CollapseContainer>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
import { CollapseContainer } from '/@/components/Container/index';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { BasicForm, FormSchema, useForm } from '@/components/Form';
import { CollapseContainer } from '@/components/Container';
import { PageWrapper } from '@/components/Page';
const schemas: FormSchema[] = [
{
@ -178,69 +177,53 @@
},
];
export default defineComponent({
components: { BasicForm, CollapseContainer, PageWrapper },
setup() {
const [register, { setProps, updateSchema, appendSchemaByField, removeSchemaByField }] =
useForm({
labelWidth: 120,
schemas,
actionColOptions: {
span: 24,
},
});
const [register1] = useForm({
labelWidth: 120,
schemas: schemas1,
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() {
removeSchemaByField('field11');
}
return {
register,
register1,
schemas,
setProps,
changeLabel3,
changeLabel34,
appendField,
deleteField,
};
const [register, { updateSchema, appendSchemaByField, removeSchemaByField }] = useForm({
labelWidth: 120,
schemas,
actionColOptions: {
span: 24,
},
});
const [register1] = useForm({
labelWidth: 120,
schemas: schemas1,
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() {
removeSchemaByField('field11');
}
</script>

View File

@ -64,12 +64,12 @@
</CollapseContainer>
</PageWrapper>
</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';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicForm, FormSchema, FormActionType, FormProps } from '@/components/Form';
import { CollapseContainer } from '@/components/Container';
import { useMessage } from '@/hooks/web/useMessage';
import { PageWrapper } from '@/components/Page';
import { type Nullable } from '@vben/types';
const schemas: FormSchema[] = [
@ -167,23 +167,16 @@
},
];
export default defineComponent({
components: { BasicForm, CollapseContainer, PageWrapper },
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);
},
};
},
});
const formElRef = ref<Nullable<FormActionType>>(null);
const { createMessage } = useMessage();
function handleSubmit(values: any) {
createMessage.success('click search,values:' + JSON.stringify(values));
}
function setProps(props: FormProps) {
const formEl = formElRef.value;
if (!formEl) return;
formEl.setProps(props);
}
</script>

View File

@ -12,13 +12,12 @@
</CollapseContainer>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
import { CollapseContainer } from '/@/components/Container';
import { useMessage } from '/@/hooks/web/useMessage';
import { PageWrapper } from '/@/components/Page';
import { isAccountExist } from '/@/api/demo/system';
<script lang="ts" setup>
import { BasicForm, FormSchema, useForm } from '@/components/Form';
import { CollapseContainer } from '@/components/Container';
import { useMessage } from '@/hooks/web/useMessage';
import { PageWrapper } from '@/components/Page';
import { isAccountExist } from '@/api/demo/system';
const schemas: FormSchema[] = [
{
@ -208,57 +207,42 @@
},
];
export default defineComponent({
components: { BasicForm, CollapseContainer, PageWrapper },
setup() {
const { createMessage } = useMessage();
const [
register,
{ validateFields, clearValidate, getFieldsValue, resetFields, 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,
field4: ['1'],
field5: ['1'],
field7: '1',
field33: '2020-12-12',
field3: '2020-12-12',
});
}
return {
register,
schemas,
handleSubmit: (values: any) => {
createMessage.success('click search,values:' + JSON.stringify(values));
},
getFormValues,
setFormValues,
validateForm,
resetValidate,
resetFields,
};
},
});
const { createMessage } = useMessage();
const [register, { validateFields, clearValidate, getFieldsValue, resetFields, 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,
field4: ['1'],
field5: ['1'],
field7: '1',
field33: '2020-12-12',
field3: '2020-12-12',
});
}
function handleSubmit(values: any) {
createMessage.success('click search,values:' + JSON.stringify(values));
}
</script>

View File

@ -19,118 +19,104 @@
</PageWrapper>
</template>
<script lang="ts">
import { ref, defineComponent } from 'vue';
<script lang="ts" setup>
import { ref } from 'vue';
import { Tabs } from 'ant-design-vue';
import { PageWrapper } from '/@/components/Page';
import { CollapseContainer } from '/@/components/Container';
import { useMessage } from '/@/hooks/web/useMessage';
import { PageWrapper } from '@/components/Page';
import { CollapseContainer } from '@/components/Container';
import { useMessage } from '@/hooks/web/useMessage';
import { omit } from 'lodash-es';
import { deepMerge } from '/@/utils';
import { BasicForm, FormSchema, useForm, FormProps, UseFormReturnType } from '/@/components/Form';
import { deepMerge } from '@/utils';
import { BasicForm, FormSchema, useForm, FormProps, UseFormReturnType } from '@/components/Form';
export default defineComponent({
name: 'TabsFormDemo',
components: { Tabs, TabPane: Tabs.TabPane, PageWrapper, CollapseContainer, BasicForm },
setup() {
type TabsFormType = {
key: string;
tab: string;
forceRender?: boolean;
Form: UseFormReturnType;
};
defineOptions({ name: 'TabsFormDemo' });
const { createMessage } = useMessage();
const activeKey = ref('tabs2');
const loading = ref(false);
const tabsFormSchema: TabsFormType[] = [];
const TabPane = Tabs.TabPane;
type TabsFormType = {
key: string;
tab: string;
forceRender?: boolean;
Form: UseFormReturnType;
};
//
const baseFormConfig: Partial<FormProps> = {
showActionButtonGroup: false,
labelWidth: 100,
};
const { createMessage } = useMessage();
const activeKey = ref('tabs2');
const loading = ref(false);
const tabsFormSchema: TabsFormType[] = [];
// , { tabs1: { field1: '', field2: '' }, tabs2: { field1: '' }, ... }
const mockDefaultValue: Recordable = {};
//
const baseFormConfig: Partial<FormProps> = {
showActionButtonGroup: false,
labelWidth: 100,
};
// 5
for (let i = 1; i <= 5; ++i) {
const tabsKey = `tabs${i}`;
// , { tabs1: { field1: '', field2: '' }, tabs2: { field1: '' }, ... }
const mockDefaultValue: Recordable = {};
// 8
const schemas: FormSchema[] = [];
const row: Recordable = {};
// 5
for (let i = 1; i <= 5; ++i) {
const tabsKey = `tabs${i}`;
for (let j = 1; j <= 8; ++j) {
schemas.push({
field: `${tabsKey}.field${j}`,
label: `${tabsKey}-field${j}`,
component: 'Input',
colProps: { span: 24 },
});
row[`field${j}`] = `field: ${tabsKey}.field${j}, default value`;
}
// 8
const schemas: FormSchema[] = [];
const row: Recordable = {};
mockDefaultValue[tabsKey] = row;
for (let j = 1; j <= 8; ++j) {
schemas.push({
field: `${tabsKey}.field${j}`,
label: `${tabsKey}-field${j}`,
component: 'Input',
colProps: { span: 24 },
});
row[`field${j}`] = `field: ${tabsKey}.field${j}, default value`;
}
tabsFormSchema.push({
key: tabsKey,
tab: tabsKey,
forceRender: true,
Form: useForm(Object.assign({ schemas }, baseFormConfig) as FormProps),
});
mockDefaultValue[tabsKey] = row;
tabsFormSchema.push({
key: tabsKey,
tab: tabsKey,
forceRender: true,
Form: useForm(Object.assign({ schemas }, baseFormConfig) as FormProps),
});
}
async function handleReset() {
for (const item of tabsFormSchema) {
const { resetFields } = item.Form[1];
await resetFields();
}
}
async function handleSubmit() {
let lastKey = '';
loading.value = true;
try {
const values: Recordable = {};
for (const item of tabsFormSchema) {
lastKey = item.key;
const { validate, getFieldsValue } = item.Form[1];
await validate();
// key
deepMerge(values, getFieldsValue());
}
async function handleReset() {
for (const item of tabsFormSchema) {
const { resetFields } = item.Form[1];
await resetFields();
}
}
console.log('submit values: ', values);
createMessage.success('提交成功!请打开控制台查看');
} catch (e) {
//
activeKey.value = lastKey;
console.log(e);
} finally {
loading.value = false;
}
}
async function handleSubmit() {
let lastKey = '';
loading.value = true;
try {
const values: Recordable = {};
for (const item of tabsFormSchema) {
lastKey = item.key;
const { validate, getFieldsValue } = item.Form[1];
await validate();
// key
deepMerge(values, getFieldsValue());
}
console.log('submit values: ', values);
createMessage.success('提交成功!请打开控制台查看');
} catch (e) {
//
activeKey.value = lastKey;
console.log(e);
} finally {
loading.value = false;
}
}
async function handleSetValues() {
console.log('默认值为: ', mockDefaultValue);
for (const item of tabsFormSchema) {
const { setFieldsValue } = item.Form[1];
await setFieldsValue(mockDefaultValue);
}
}
return {
omit,
loading,
activeKey,
tabsFormSchema,
handleReset,
handleSubmit,
handleSetValues,
};
},
});
async function handleSetValues() {
console.log('默认值为: ', mockDefaultValue);
for (const item of tabsFormSchema) {
const { setFieldsValue } = item.Form[1];
await setFieldsValue(mockDefaultValue);
}
}
</script>
<style scoped></style>

View File

@ -2,7 +2,7 @@
<PageWrapper title="UseForm操作示例">
<a-button class="mb-4" type="primary" @click="showDrawer"> 更改设置 </a-button>
<Drawer v-model:open="visible" title="更改设置" placement="right">
<Drawer v-model:open="open" title="更改设置" placement="right">
<BasicForm ref="settingFormRef" @register="registerSetting" @submit="handleSubmitSetting">
<template #other>
<Space>
@ -34,13 +34,13 @@
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
<script lang="ts" setup>
import { ref } from 'vue';
import { Drawer, Space } from 'ant-design-vue';
import { BasicForm, FormSchema, useForm, type FormProps } from '/@/components/Form';
import { CollapseContainer } from '/@/components/Container';
import { PageWrapper } from '/@/components/Page';
import { areaRecord } from '/@/api/demo/cascader';
import { BasicForm, FormSchema, useForm, type FormProps } from '@/components/Form';
import { CollapseContainer } from '@/components/Container';
import { PageWrapper } from '@/components/Page';
import { areaRecord } from '@/api/demo/cascader';
const sizeList = [
{ value: 'large', label: 'large' },
@ -426,93 +426,68 @@
},
];
export default defineComponent({
components: {
BasicForm,
CollapseContainer,
PageWrapper,
Drawer,
Space,
},
setup() {
const visible = ref<boolean>(false);
const settingFormRef = ref();
const [registerSetting] = useForm({
size: 'small',
schemas: formSchemas,
compact: true,
actionColOptions: { span: 24 },
showActionButtonGroup: false,
});
const resetSettings = async () => {
setProps({ resetButtonOptions: { disabled: false, text: '重置' } });
setProps({ submitButtonOptions: { disabled: false, loading: false } });
await setFieldsValue({ field9: [] });
await settingFormRef.value?.resetFields();
};
const handleSubmitSetting = async (values) => {
console.log(values);
await setProps(values);
visible.value = false;
};
const [register, { setProps, setFieldsValue, updateSchema }] = useForm({
labelWidth: 120,
schemas,
actionColOptions: { span: 24 },
fieldMapToTime: [['fieldTime', ['startTime', 'endTime'], 'YYYY-MM']],
});
async function handleLoad() {
const promiseFn = function () {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
field9: ['430000', '430100', '430102'],
province: '湖南省',
city: '长沙市',
district: '岳麓区',
});
}, 1000);
});
};
const item = await promiseFn();
const { field9, province, city, district } = item as any;
await updateSchema({
field: 'field9',
componentProps: {
displayRenderArray: [province, city, district],
},
});
await setFieldsValue({ field9 });
visible.value = false;
}
const showDrawer = () => {
visible.value = true;
};
const onSettings = () => {
settingFormRef.value?.submit();
};
const withClose = (formProps: Partial<FormProps>) => {
setProps(formProps);
visible.value = false;
};
return {
register,
schemas,
handleSubmit: (values) => {
console.log(values);
},
setProps,
handleLoad,
visible,
showDrawer,
settingFormRef,
withClose,
onSettings,
resetSettings,
registerSetting,
handleSubmitSetting,
};
},
const open = ref<boolean>(false);
const settingFormRef = ref();
const [registerSetting] = useForm({
size: 'small',
schemas: formSchemas,
compact: true,
actionColOptions: { span: 24 },
showActionButtonGroup: false,
});
const resetSettings = async () => {
setProps({ resetButtonOptions: { disabled: false, text: '重置' } });
setProps({ submitButtonOptions: { disabled: false, loading: false } });
await setFieldsValue({ field9: [] });
await settingFormRef.value?.resetFields();
};
const handleSubmitSetting = async (values) => {
console.log(values);
await setProps(values);
open.value = false;
};
const [register, { setProps, setFieldsValue, updateSchema }] = useForm({
labelWidth: 120,
schemas,
actionColOptions: { span: 24 },
fieldMapToTime: [['fieldTime', ['startTime', 'endTime'], 'YYYY-MM']],
});
async function handleLoad() {
const promiseFn = function () {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
field9: ['430000', '430100', '430102'],
province: '湖南省',
city: '长沙市',
district: '岳麓区',
});
}, 1000);
});
};
const item = await promiseFn();
const { field9, province, city, district } = item as any;
await updateSchema({
field: 'field9',
componentProps: {
displayRenderArray: [province, city, district],
},
});
await setFieldsValue({ field9 });
open.value = false;
}
const showDrawer = () => {
open.value = true;
};
const onSettings = () => {
settingFormRef.value?.submit();
};
const withClose = (formProps: Partial<FormProps>) => {
setProps(formProps);
open.value = false;
};
function handleSubmit(values) {
console.log(values);
}
</script>

View File

@ -10,7 +10,7 @@
@reset="handleReset"
>
<template #selectA="{ model, field }">
<a-select
<Select
:options="optionsA"
mode="multiple"
v-model:value="model[field]"
@ -19,7 +19,7 @@
/>
</template>
<template #selectB="{ model, field }">
<a-select
<Select
:options="optionsB"
mode="multiple"
v-model:value="model[field]"
@ -48,29 +48,28 @@
labelField="name"
valueField="id"
:params="searchParams"
@search="onSearch"
@search="useDebounceFn(onSearch, 300)"
/>
</template>
</BasicForm>
</CollapseContainer>
</PageWrapper>
</template>
<script lang="ts">
<script lang="ts" setup>
import { type Recordable } from '@vben/types';
import { computed, defineComponent, unref, ref } from 'vue';
import { BasicForm, FormSchema, ApiSelect } from '/@/components/Form/index';
import { CollapseContainer } from '/@/components/Container';
import { useMessage } from '/@/hooks/web/useMessage';
import { PageWrapper } from '/@/components/Page';
import { computed, unref, ref } from 'vue';
import { BasicForm, FormSchema, ApiSelect } from '@/components/Form';
import { CollapseContainer } from '@/components/Container';
import { useMessage } from '@/hooks/web/useMessage';
import { PageWrapper } from '@/components/Page';
import { optionsListApi } from '/@/api/demo/select';
import { optionsListApi } from '@/api/demo/select';
import { useDebounceFn } from '@vueuse/core';
import { treeOptionsListApi } from '/@/api/demo/tree';
import { treeOptionsListApi } from '@/api/demo/tree';
import { Select, type SelectProps } from 'ant-design-vue';
import { cloneDeep } from 'lodash-es';
import { areaRecord } from '/@/api/demo/cascader';
import { uploadApi } from '/@/api/sys/upload';
// import { isArray } from '/@/utils/is';
import { areaRecord } from '@/api/demo/cascader';
import { uploadApi } from '@/api/sys/upload';
const valueSelectA = ref<string[]>([]);
const valueSelectB = ref<string[]>([]);
@ -784,37 +783,22 @@
},
];
export default defineComponent({
components: { BasicForm, CollapseContainer, PageWrapper, ApiSelect, ASelect: Select },
setup() {
const check = ref(null);
const { createMessage } = useMessage();
const keyword = ref<string>('');
const searchParams = computed<Recordable<string>>(() => {
return { keyword: unref(keyword) };
});
function onSearch(value: string) {
keyword.value = value;
}
return {
schemas,
optionsListApi,
optionsA,
optionsB,
valueSelectA,
valueSelectB,
onSearch: useDebounceFn(onSearch, 300),
searchParams,
handleReset: () => {
keyword.value = '';
},
handleSubmit: (values: any) => {
console.log('values', values);
createMessage.success('click search,values:' + JSON.stringify(values));
},
check,
};
},
const { createMessage } = useMessage();
const keyword = ref<string>('');
const searchParams = computed<Recordable<string>>(() => {
return { keyword: unref(keyword) };
});
function onSearch(value: string) {
keyword.value = value;
}
function handleReset() {
keyword.value = '';
}
function handleSubmit(values: any) {
console.log('values', values);
createMessage.success('click search,values:' + JSON.stringify(values));
}
</script>

View File

@ -2,12 +2,9 @@
<div class="p-5">
多层级缓存-页面1-1-1
<br />
<Input />
<a-input />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { Input } from 'ant-design-vue';
export default defineComponent({ name: 'Menu111Demo', components: { Input } });
<script lang="ts" setup>
defineOptions({ name: 'Menu111Demo' });
</script>

View File

@ -2,12 +2,9 @@
<div class="p-5">
多层级缓存-页面1-2
<br />
<Input />
<a-input />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { Input } from 'ant-design-vue';
export default defineComponent({ name: 'Menu12Demo', components: { Input } });
<script lang="ts" setup>
defineOptions({ name: 'Menu12Demo' });
</script>

View File

@ -2,15 +2,9 @@
<div class="p-5">
多层级缓存-页面2
<br />
<Input />
<a-input />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { Input } from 'ant-design-vue';
export default defineComponent({
name: 'Menu2Demo',
components: { Input },
});
<script lang="ts" setup>
defineOptions({ name: 'Menu2Demo' });
</script>

View File

@ -1,8 +1,8 @@
<template>
<List :class="prefixCls">
<a-row :gutter="16">
<template v-for="item in list" :key="item.title">
<a-col :span="6">
<Row :gutter="16">
<template v-for="item in applicationList" :key="item.title">
<Col :span="6">
<ListItem>
<Card :hoverable="true" :class="`${prefixCls}__card`">
<div :class="`${prefixCls}__card-title`">
@ -22,33 +22,19 @@
/>
</Card>
</ListItem>
</a-col>
</Col>
</template>
</a-row>
</Row>
</List>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
<script lang="ts" setup>
import { List, Card, Row, Col } from 'ant-design-vue';
import Icon from '@/components/Icon/Icon.vue';
import { applicationList } from './data';
export default defineComponent({
components: {
List,
ListItem: List.Item,
Card,
Icon,
[Row.name]: Row,
[Col.name]: Col,
},
setup() {
return {
prefixCls: 'account-center-application',
list: applicationList,
};
},
});
const ListItem = List.Item;
const prefixCls = 'account-center-application';
</script>
<style lang="less">
.account-center-application {

View File

@ -1,6 +1,6 @@
<template>
<List item-layout="vertical" :class="prefixCls">
<template v-for="item in list" :key="item.title">
<template v-for="item in articleList" :key="item.title">
<ListItem>
<ListItemMeta>
<template #description>
@ -39,28 +39,15 @@
</template>
</List>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
<script lang="ts" setup>
import { List, Tag } from 'ant-design-vue';
import Icon from '@/components/Icon/Icon.vue';
import { actions, articleList } from './data';
export default defineComponent({
components: {
List,
ListItem: List.Item,
ListItemMeta: List.Item.Meta,
Tag,
Icon,
},
setup() {
return {
prefixCls: 'account-center-article',
list: articleList,
actions,
};
},
});
const ListItem = List.Item;
const ListItemMeta = List.Item.Meta;
const prefixCls = 'account-center-article';
</script>
<style lang="less" scoped>
.account-center-article {

View File

@ -1,8 +1,8 @@
<template>
<List :class="prefixCls">
<a-row :gutter="16">
<template v-for="item in list" :key="item.title">
<a-col :span="6">
<Row :gutter="16">
<template v-for="item in projectList" :key="item.title">
<Col :span="6">
<ListItem>
<Card :hoverable="true" :class="`${prefixCls}__card`">
<img :src="demoImg" />
@ -14,33 +14,19 @@
</div>
</Card>
</ListItem>
</a-col>
</Col>
</template>
</a-row>
</Row>
</List>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
<script lang="ts" setup>
import { List, Card, Row, Col } from 'ant-design-vue';
import demoImg from '/@/assets/images/demo.png';
import demoImg from '@/assets/images/demo.png';
import { projectList } from './data';
export default defineComponent({
components: {
List,
ListItem: List.Item,
Card,
[Row.name]: Row,
[Col.name]: Col,
},
setup() {
return {
prefixCls: 'account-center-project',
list: projectList,
demoImg,
};
},
});
const ListItem = List.Item;
const prefixCls = 'account-center-project';
</script>
<style lang="less">
.account-center-project {

View File

@ -55,15 +55,15 @@
<script lang="ts">
import { Tag, Tabs, Row, Col } from 'ant-design-vue';
import { defineComponent, computed } from 'vue';
import { CollapseContainer } from '/@/components/Container/index';
import { CollapseContainer } from '@/components/Container';
import Icon from '@/components/Icon/Icon.vue';
import Article from './Article.vue';
import Application from './Application.vue';
import Project from './Project.vue';
import headerImg from '/@/assets/images/header.jpg';
import headerImg from '@/assets/images/header.jpg';
import { tags, teams, details, achieveList } from './data';
import { useUserStore } from '/@/store/modules/user';
import { useUserStore } from '@/store/modules/user';
export default defineComponent({
components: {

View File

@ -1,7 +1,7 @@
<template>
<CollapseContainer title="账号绑定" :canExpan="false">
<List>
<template v-for="item in list" :key="item.key">
<template v-for="item in accountBindList" :key="item.key">
<ListItem>
<ListItemMeta>
<template #avatar>
@ -22,28 +22,15 @@
</List>
</CollapseContainer>
</template>
<script lang="ts">
<script lang="ts" setup>
import { List } from 'ant-design-vue';
import { defineComponent } from 'vue';
import { CollapseContainer } from '/@/components/Container/index';
import { CollapseContainer } from '@/components/Container';
import Icon from '@/components/Icon/Icon.vue';
import { accountBindList } from './data';
export default defineComponent({
components: {
CollapseContainer,
List,
ListItem: List.Item,
ListItemMeta: List.Item.Meta,
Icon,
},
setup() {
return {
list: accountBindList,
};
},
});
const ListItem = List.Item;
const ListItemMeta = List.Item.Meta;
</script>
<style lang="less" scoped>
.avatar {

View File

@ -1,14 +1,14 @@
<template>
<CollapseContainer title="基本设置" :canExpan="false">
<a-row :gutter="24">
<a-col :span="14">
<Row :gutter="24">
<Col :span="14">
<BasicForm @register="register" />
</a-col>
<a-col :span="10">
</Col>
<Col :span="10">
<div class="change-avatar">
<div class="mb-2">头像</div>
<CropperAvatar
:uploadApi="uploadApi"
:uploadApi="uploadApi as any"
:value="avatar"
btnText="更换头像"
:btnProps="{ preIcon: 'ant-design:cloud-upload-outlined' }"
@ -16,74 +16,56 @@
width="150"
/>
</div>
</a-col>
</a-row>
<Button type="primary" @click="handleSubmit"> 更新基本信息 </Button>
</Col>
</Row>
<a-button type="primary" @click="handleSubmit"> 更新基本信息 </a-button>
</CollapseContainer>
</template>
<script lang="ts">
import { Button, Row, Col } from 'ant-design-vue';
import { computed, defineComponent, onMounted } from 'vue';
import { BasicForm, useForm } from '/@/components/Form/index';
import { CollapseContainer } from '/@/components/Container';
import { CropperAvatar } from '/@/components/Cropper';
<script lang="ts" setup>
import { Row, Col } from 'ant-design-vue';
import { computed, onMounted } from 'vue';
import { BasicForm, useForm } from '@/components/Form';
import { CollapseContainer } from '@/components/Container';
import { CropperAvatar } from '@/components/Cropper';
import { useMessage } from '/@/hooks/web/useMessage';
import { useMessage } from '@/hooks/web/useMessage';
import headerImg from '/@/assets/images/header.jpg';
import { accountInfoApi } from '/@/api/demo/account';
import headerImg from '@/assets/images/header.jpg';
import { accountInfoApi } from '@/api/demo/account';
import { baseSetschemas } from './data';
import { useUserStore } from '/@/store/modules/user';
import { uploadApi } from '/@/api/sys/upload';
import { useUserStore } from '@/store/modules/user';
import { uploadApi } from '@/api/sys/upload';
export default defineComponent({
components: {
BasicForm,
CollapseContainer,
Button,
ARow: Row,
ACol: Col,
CropperAvatar,
},
setup() {
const { createMessage } = useMessage();
const userStore = useUserStore();
const { createMessage } = useMessage();
const userStore = useUserStore();
const [register, { setFieldsValue }] = useForm({
labelWidth: 120,
schemas: baseSetschemas,
showActionButtonGroup: false,
});
onMounted(async () => {
const data = await accountInfoApi();
setFieldsValue(data);
});
const avatar = computed(() => {
const { avatar } = userStore.getUserInfo;
console.log(avatar);
return avatar || headerImg;
});
function updateAvatar({ src, data }) {
const userinfo = userStore.getUserInfo;
userinfo.avatar = src;
userStore.setUserInfo(userinfo);
console.log('data', data);
}
return {
avatar,
register,
uploadApi: uploadApi as any,
updateAvatar,
handleSubmit: () => {
createMessage.success('更新成功!');
},
};
},
const [register, { setFieldsValue }] = useForm({
labelWidth: 120,
schemas: baseSetschemas,
showActionButtonGroup: false,
});
onMounted(async () => {
const data = await accountInfoApi();
setFieldsValue(data);
});
const avatar = computed(() => {
const { avatar } = userStore.getUserInfo;
console.log(avatar);
return avatar || headerImg;
});
function updateAvatar({ src, data }) {
const userinfo = userStore.getUserInfo;
userinfo.avatar = src;
userStore.setUserInfo(userinfo);
console.log('data', data);
}
function handleSubmit() {
createMessage.success('更新成功!');
}
</script>
<style lang="less" scoped>

View File

@ -1,13 +1,13 @@
<template>
<CollapseContainer title="新消息通知" :canExpan="false">
<List>
<template v-for="item in list" :key="item.key">
<template v-for="item in msgNotifyList" :key="item.key">
<ListItem>
<ListItemMeta>
<template #title>
{{ item.title }}
<Switch
class="extra"
class="float-right mt-10px mr-30px"
checked-children="开"
un-checked-children="关"
default-checked
@ -22,32 +22,11 @@
</List>
</CollapseContainer>
</template>
<script lang="ts">
<script lang="ts" setup>
import { List, Switch } from 'ant-design-vue';
import { defineComponent } from 'vue';
import { CollapseContainer } from '/@/components/Container/index';
import { CollapseContainer } from '@/components/Container';
import { msgNotifyList } from './data';
export default defineComponent({
components: {
CollapseContainer,
List,
ListItem: List.Item,
ListItemMeta: List.Item.Meta,
Switch,
},
setup() {
return {
list: msgNotifyList,
};
},
});
const ListItem = List.Item;
const ListItemMeta = List.Item.Meta;
</script>
<style lang="less" scoped>
.extra {
margin-top: 10px;
margin-right: 30px;
float: right;
}
</style>

View File

@ -1,12 +1,15 @@
<template>
<CollapseContainer title="安全设置" :canExpan="false">
<List>
<template v-for="item in list" :key="item.key">
<template v-for="item in secureSettingList" :key="item.key">
<ListItem>
<ListItemMeta>
<template #title>
{{ item.title }}
<div class="extra" v-if="item.extra">
<div
class="float-right mt-10px mr-30px text-blue-500 text-font-normal cursor-pointer"
v-if="item.extra"
>
{{ item.extra }}
</div>
</template>
@ -19,29 +22,11 @@
</List>
</CollapseContainer>
</template>
<script lang="ts">
<script lang="ts" setup>
import { List } from 'ant-design-vue';
import { defineComponent } from 'vue';
import { CollapseContainer } from '/@/components/Container/index';
import { CollapseContainer } from '@/components/Container';
import { secureSettingList } from './data';
export default defineComponent({
components: { CollapseContainer, List, ListItem: List.Item, ListItemMeta: List.Item.Meta },
setup() {
return {
list: secureSettingList,
};
},
});
const ListItem = List.Item;
const ListItemMeta = List.Item.Meta;
</script>
<style lang="less" scoped>
.extra {
margin-top: 10px;
margin-right: 30px;
float: right;
color: #1890ff;
font-weight: normal;
cursor: pointer;
}
</style>

View File

@ -1,4 +1,4 @@
import { FormSchema } from '/@/components/Form/index';
import { FormSchema } from '@/components/Form';
export interface ListItem {
key: string;

View File

@ -16,7 +16,7 @@
import { defineComponent } from 'vue';
import { Tabs } from 'ant-design-vue';
import { ScrollContainer } from '/@/components/Container/index';
import { ScrollContainer } from '@/components/Container';
import { settingList } from './data';
import BaseSetting from './BaseSetting.vue';

View File

@ -1,6 +1,6 @@
import { DescItem } from '/@/components/Description/index';
import { BasicColumn } from '/@/components/Table/src/types/table';
import { Button } from '/@/components/Button';
import { DescItem } from '@/components/Description';
import { BasicColumn } from '@/components/Table/src/types/table';
import { Button } from '@/components/Button';
import { Badge } from 'ant-design-vue';

View File

@ -8,7 +8,7 @@
:data="refundData"
:schema="refundSchema"
/>
<a-divider />
<Divider />
<Description
size="middle"
title="用户信息"
@ -17,18 +17,17 @@
:data="personData"
:schema="personSchema"
/>
<a-divider />
<Divider />
<BasicTable @register="registerRefundTable" />
<a-divider />
<Divider />
<BasicTable @register="registerTimeTable" />
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { Description } from '/@/components/Description/index';
import { BasicTable, useTable } from '/@/components/Table';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { Description } from '@/components/Description';
import { BasicTable, useTable } from '@/components/Table';
import { PageWrapper } from '@/components/Page';
import { Divider } from 'ant-design-vue';
import {
@ -42,54 +41,41 @@
refundTimeTableData,
} from './data';
export default defineComponent({
components: { Description, BasicTable, PageWrapper, [Divider.name]: Divider },
setup() {
const [registerRefundTable] = useTable({
title: '退货商品',
dataSource: refundTableData,
columns: refundTableSchema,
pagination: false,
showIndexColumn: false,
scroll: { y: 300 },
showSummary: true,
summaryFunc: handleSummary,
});
const [registerTimeTable] = useTable({
title: '退货进度',
columns: refundTimeTableSchema,
pagination: false,
dataSource: refundTimeTableData,
showIndexColumn: false,
scroll: { y: 300 },
});
function handleSummary(tableData: any[]) {
let totalT5 = 0;
let totalT6 = 0;
tableData.forEach((item) => {
totalT5 += item.t5;
totalT6 += item.t6;
});
return [
{
t1: '总计',
t5: totalT5,
t6: totalT6,
},
];
}
return {
registerRefundTable,
registerTimeTable,
refundSchema,
refundData,
personSchema,
personData,
};
},
const [registerRefundTable] = useTable({
title: '退货商品',
dataSource: refundTableData,
columns: refundTableSchema,
pagination: false,
showIndexColumn: false,
scroll: { y: 300 },
showSummary: true,
summaryFunc: handleSummary,
});
const [registerTimeTable] = useTable({
title: '退货进度',
columns: refundTimeTableSchema,
pagination: false,
dataSource: refundTimeTableData,
showIndexColumn: false,
scroll: { y: 300 },
});
function handleSummary(tableData: any[]) {
let totalT5 = 0;
let totalT6 = 0;
tableData.forEach((item) => {
totalT5 += item.t5;
totalT6 += item.t6;
});
return [
{
t1: '总计',
t5: totalT5,
t6: totalT6,
},
];
}
</script>
<style lang="less" scoped>
.desc-wrap {

View File

@ -1,4 +1,4 @@
import { BasicColumn } from '/@/components/Table/src/types/table';
import { BasicColumn } from '@/components/Table/src/types/table';
import { Badge } from 'ant-design-vue';

View File

@ -7,126 +7,104 @@
</template>
<template #footer>
<a-tabs default-active-key="1">
<a-tab-pane key="1" tab="详情" />
<a-tab-pane key="2" tab="规则" />
</a-tabs>
<Tabs default-active-key="1">
<Tabs.TabPane key="1" tab="详情" />
<Tabs.TabPane key="2" tab="规则" />
</Tabs>
</template>
<div class="pt-4 m-4 desc-wrap">
<a-descriptions size="small" :column="2">
<a-descriptions-item label="创建人"> 曲丽丽 </a-descriptions-item>
<a-descriptions-item label="订购产品"> XX 服务 </a-descriptions-item>
<a-descriptions-item label="创建时间"> 2017-01-10 </a-descriptions-item>
<a-descriptions-item label="关联单据">
<Descriptions size="small" :column="2">
<Descriptions.Item label="创建人"> 曲丽丽 </Descriptions.Item>
<Descriptions.Item label="订购产品"> XX 服务 </Descriptions.Item>
<Descriptions.Item label="创建时间"> 2017-01-10 </Descriptions.Item>
<Descriptions.Item label="关联单据">
<a>12421</a>
</a-descriptions-item>
<a-descriptions-item label="生效日期"> 2017-07-07 ~ 2017-08-08 </a-descriptions-item>
<a-descriptions-item label="备注"> 请于两个工作日内确认 </a-descriptions-item>
</a-descriptions>
<a-card title="流程进度" :bordered="false">
<a-steps :current="1" progress-dot size="small">
<a-step title="创建项目">
</Descriptions.Item>
<Descriptions.Item label="生效日期"> 2017-07-07 ~ 2017-08-08 </Descriptions.Item>
<Descriptions.Item label="备注"> 请于两个工作日内确认 </Descriptions.Item>
</Descriptions>
<Card title="流程进度" :bordered="false">
<Steps :current="1" progress-dot size="small">
<Steps.Step title="创建项目">
<template #description>
<div>Vben</div>
<p>2016-12-12 12:32</p>
</template>
</a-step>
<a-step title="部门初审">
</Steps.Step>
<Steps.Step title="部门初审">
<template #description>
<p>Chad</p>
</template>
</a-step>
<a-step title="财务复核" />
<a-step title="完成" />
</a-steps>
</a-card>
</Steps.Step>
<Steps.Step title="财务复核" />
<Steps.Step title="完成" />
</Steps>
</Card>
<a-card title="用户信息" :bordered="false" class="mt-5">
<a-descriptions :column="3">
<a-descriptions-item label="用户姓名"> 付小小 </a-descriptions-item>
<a-descriptions-item label="会员卡号"> XX 32943898021309809423 </a-descriptions-item>
<a-descriptions-item label="身份证"> 3321944288191034921 </a-descriptions-item>
<a-descriptions-item label="联系方式"> 18112345678 </a-descriptions-item>
<a-descriptions-item label="联系地址" :span="2">
<Card title="用户信息" :bordered="false" class="mt-5">
<Descriptions :column="3">
<Descriptions.Item label="用户姓名"> 付小小 </Descriptions.Item>
<Descriptions.Item label="会员卡号"> XX 32943898021309809423 </Descriptions.Item>
<Descriptions.Item label="身份证"> 3321944288191034921 </Descriptions.Item>
<Descriptions.Item label="联系方式"> 18112345678 </Descriptions.Item>
<Descriptions.Item label="联系地址" :span="2">
曲丽丽 18100000000 浙江省杭州市西湖区黄姑山路工专路交叉路口
</a-descriptions-item>
</a-descriptions>
</Descriptions.Item>
</Descriptions>
<a-descriptions title="信息组" :column="3">
<a-descriptions-item label="某某数据"> 111 </a-descriptions-item>
<a-descriptions-item label="该数据更新时间"> 2017-08-08 </a-descriptions-item>
<a-descriptions-item label="某某数据"> 725 </a-descriptions-item>
<a-descriptions-item label="该数据更新时间"> 2017-08-08 </a-descriptions-item>
</a-descriptions>
<Descriptions title="信息组" :column="3">
<Descriptions.Item label="某某数据"> 111 </Descriptions.Item>
<Descriptions.Item label="该数据更新时间"> 2017-08-08 </Descriptions.Item>
<Descriptions.Item label="某某数据"> 725 </Descriptions.Item>
<Descriptions.Item label="该数据更新时间"> 2017-08-08 </Descriptions.Item>
</Descriptions>
<h4>信息组</h4>
<a-card title="多层级信息组">
<a-descriptions title="组名称" :column="3">
<a-descriptions-item label="负责人"> 林东东 </a-descriptions-item>
<a-descriptions-item label="角色码"> 1234567 </a-descriptions-item>
<a-descriptions-item label="所属部门"> XX公司 - YY部 </a-descriptions-item>
<a-descriptions-item label="过期时间"> 2017-08-08 </a-descriptions-item>
<a-descriptions-item label="描述" :span="2">
<Card title="多层级信息组">
<Descriptions title="组名称" :column="3">
<Descriptions.Item label="负责人"> 林东东 </Descriptions.Item>
<Descriptions.Item label="角色码"> 1234567 </Descriptions.Item>
<Descriptions.Item label="所属部门"> XX公司 - YY部 </Descriptions.Item>
<Descriptions.Item label="过期时间"> 2017-08-08 </Descriptions.Item>
<Descriptions.Item label="描述" :span="2">
这段描述很长很长很长很长很长很长很长很长很长很长很长很长很长很长...
</a-descriptions-item>
</a-descriptions>
<a-divider />
<a-descriptions title="组名称" :column="1">
<a-descriptions-item label="学名">
</Descriptions.Item>
</Descriptions>
<Divider />
<Descriptions title="组名称" :column="1">
<Descriptions.Item label="学名">
Citrullus lanatus (Thunb.) Matsum. et
Nakai一年生蔓生藤本枝粗壮具明显的棱卷须较粗..
</a-descriptions-item>
</a-descriptions>
<a-divider />
<a-descriptions title="组名称" :column="1">
<a-descriptions-item label="负责人"> 付小小 </a-descriptions-item>
<a-descriptions-item label="角色码"> 1234568 </a-descriptions-item>
</a-descriptions>
</a-card>
</a-card>
<a-card title="用户近半年来电记录" class="my-5">
</Descriptions.Item>
</Descriptions>
<Divider />
<Descriptions title="组名称" :column="1">
<Descriptions.Item label="负责人"> 付小小 </Descriptions.Item>
<Descriptions.Item label="角色码"> 1234568 </Descriptions.Item>
</Descriptions>
</Card>
</Card>
<Card title="用户近半年来电记录" class="my-5">
<Empty />
</a-card>
</Card>
<BasicTable @register="registerTimeTable" />
</div>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, useTable } from '/@/components/Table';
import { PageWrapper } from '/@/components/Page';
<script lang="ts" setup>
import { BasicTable, useTable } from '@/components/Table';
import { PageWrapper } from '@/components/Page';
import { Divider, Card, Empty, Descriptions, Steps, Tabs } from 'ant-design-vue';
import { refundTimeTableSchema, refundTimeTableData } from './data';
export default defineComponent({
components: {
BasicTable,
PageWrapper,
[Divider.name]: Divider,
[Card.name]: Card,
Empty,
[Descriptions.name]: Descriptions,
[Descriptions.Item.name]: Descriptions.Item,
[Steps.name]: Steps,
[Steps.Step.name]: Steps.Step,
[Tabs.name]: Tabs,
[Tabs.TabPane.name]: Tabs.TabPane,
},
setup() {
const [registerTimeTable] = useTable({
title: '退货进度',
columns: refundTimeTableSchema,
pagination: false,
dataSource: refundTimeTableData,
showIndexColumn: false,
scroll: { y: 300 },
});
return {
registerTimeTable,
};
},
const [registerTimeTable] = useTable({
title: '退货进度',
columns: refundTimeTableSchema,
pagination: false,
dataSource: refundTimeTableData,
showIndexColumn: false,
scroll: { y: 300 },
});
</script>

View File

@ -1,4 +1,4 @@
import { FormSchema } from '/@/components/Form';
import { FormSchema } from '@/components/Form';
const colProps = {
span: 8,

View File

@ -8,58 +8,53 @@
<BasicForm @register="register" />
</PageWrapper>
</template>
<script lang="ts">
import { BasicForm, useForm } from '/@/components/Form';
import { defineComponent } from 'vue';
<script lang="ts" setup>
import { BasicForm, useForm } from '@/components/Form';
import { schemas } from './data';
import { useMessage } from '/@/hooks/web/useMessage';
import { PageWrapper } from '/@/components/Page';
import { useMessage } from '@/hooks/web/useMessage';
import { PageWrapper } from '@/components/Page';
export default defineComponent({
name: 'FormBasicPage',
components: { BasicForm, PageWrapper },
setup() {
const { createMessage } = useMessage();
const [register, { validate, setProps }] = useForm({
labelCol: {
span: 8,
},
wrapperCol: {
span: 15,
},
schemas: schemas,
actionColOptions: {
offset: 8,
span: 23,
},
submitButtonOptions: {
text: '提交',
},
submitFunc: customSubmitFunc,
});
defineOptions({ name: 'FormBasicPage' });
async function customSubmitFunc() {
try {
await validate();
setProps({
submitButtonOptions: {
loading: true,
},
});
setTimeout(() => {
setProps({
submitButtonOptions: {
loading: false,
},
});
createMessage.success('提交成功!');
}, 2000);
} catch (error) {}
}
return { register };
const { createMessage } = useMessage();
const [register, { validate, setProps }] = useForm({
labelCol: {
span: 8,
},
wrapperCol: {
span: 15,
},
schemas: schemas,
actionColOptions: {
offset: 8,
span: 23,
},
submitButtonOptions: {
text: '提交',
},
submitFunc: customSubmitFunc,
});
async function customSubmitFunc() {
try {
await validate();
setProps({
submitButtonOptions: {
loading: true,
},
});
setTimeout(() => {
setProps({
submitButtonOptions: {
loading: false,
},
});
createMessage.success('提交成功!');
}, 2000);
} catch (error) {
console.error(error);
}
}
</script>
<style lang="less" scoped>
.form-wrap {

View File

@ -10,8 +10,7 @@
<a-button block class="mt-5" type="dashed" @click="handleAdd"> 新增成员 </a-button>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
<script lang="ts" setup>
import {
BasicTable,
useTable,
@ -19,7 +18,7 @@
BasicColumn,
ActionItem,
EditRecordRow,
} from '/@/components/Table';
} from '@/components/Table';
const columns: BasicColumn[] = [
{
@ -56,92 +55,78 @@
dept: 'New York No. 3Lake Park',
},
];
export default defineComponent({
components: { BasicTable, TableAction },
setup() {
const [registerTable, { getDataSource }] = useTable({
columns: columns,
showIndexColumn: false,
dataSource: data,
actionColumn: {
width: 160,
title: '操作',
dataIndex: 'action',
// slots: { customRender: 'action' },
},
scroll: { y: '100%' },
pagination: false,
});
function handleEdit(record: EditRecordRow) {
record.onEdit?.(true);
}
function handleCancel(record: EditRecordRow) {
record.onEdit?.(false);
if (record.isNew) {
const data = getDataSource();
const index = data.findIndex((item) => item.key === record.key);
data.splice(index, 1);
}
}
function handleSave(record: EditRecordRow) {
record.onEdit?.(false, true);
}
function handleEditChange(data: Recordable) {
console.log(data);
}
function handleAdd() {
const data = getDataSource();
const addRow: EditRecordRow = {
name: '',
no: '',
dept: '',
editable: true,
isNew: true,
key: `${Date.now()}`,
};
data.push(addRow);
}
function createActions(record: EditRecordRow): ActionItem[] {
if (!record.editable) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
label: '删除',
},
];
}
return [
{
label: '保存',
onClick: handleSave.bind(null, record),
},
{
label: '取消',
popConfirm: {
title: '是否取消编辑',
confirm: handleCancel.bind(null, record),
},
},
];
}
return {
registerTable,
handleEdit,
createActions,
handleAdd,
getDataSource,
handleEditChange,
};
const [registerTable, { getDataSource }] = useTable({
columns: columns,
showIndexColumn: false,
dataSource: data,
actionColumn: {
width: 160,
title: '操作',
dataIndex: 'action',
// slots: { customRender: 'action' },
},
scroll: { y: '100%' },
pagination: false,
});
function handleEdit(record: EditRecordRow) {
record.onEdit?.(true);
}
function handleCancel(record: EditRecordRow) {
record.onEdit?.(false);
if (record.isNew) {
const data = getDataSource();
const index = data.findIndex((item) => item.key === record.key);
data.splice(index, 1);
}
}
function handleSave(record: EditRecordRow) {
record.onEdit?.(false, true);
}
function handleEditChange(data: Recordable) {
console.log(data);
}
function handleAdd() {
const data = getDataSource();
const addRow: EditRecordRow = {
name: '',
no: '',
dept: '',
editable: true,
isNew: true,
key: `${Date.now()}`,
};
data.push(addRow);
}
function createActions(record: EditRecordRow): ActionItem[] {
if (!record.editable) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
label: '删除',
},
];
}
return [
{
label: '保存',
onClick: handleSave.bind(null, record),
},
{
label: '取消',
popConfirm: {
title: '是否取消编辑',
confirm: handleCancel.bind(null, record),
},
},
];
}
</script>

View File

@ -1,4 +1,4 @@
import { FormSchema } from '/@/components/Form';
import { FormSchema } from '@/components/Form';
const basicOptions: LabelValueOptions = [
{

View File

@ -4,67 +4,63 @@
title="高级表单"
content=" 高级表单常见于一次性输入和提交大批量数据的场景。"
>
<a-card title="仓库管理" :bordered="false">
<Card title="仓库管理" :bordered="false">
<BasicForm @register="register" />
</a-card>
<a-card title="任务管理" :bordered="false" class="!mt-5">
</Card>
<Card title="任务管理" :bordered="false" class="!mt-5">
<BasicForm @register="registerTask" />
</a-card>
<a-card title="成员管理" :bordered="false" class="!mt-5">
</Card>
<Card title="成员管理" :bordered="false" class="!mt-5">
<PersonTable ref="tableRef" />
</a-card>
</Card>
<template #rightFooter>
<a-button type="primary" @click="submitAll"> 提交 </a-button>
</template>
</PageWrapper>
</template>
<script lang="ts">
import { BasicForm, useForm } from '/@/components/Form';
import { defineComponent, ref } from 'vue';
<script lang="ts" setup>
import { BasicForm, useForm } from '@/components/Form';
import { ref } from 'vue';
import PersonTable from './PersonTable.vue';
import { PageWrapper } from '/@/components/Page';
import { PageWrapper } from '@/components/Page';
import { schemas, taskSchemas } from './data';
import { Card } from 'ant-design-vue';
export default defineComponent({
name: 'FormHightPage',
components: { BasicForm, PersonTable, PageWrapper, [Card.name]: Card },
setup() {
const tableRef = ref<{ getDataSource: () => any } | null>(null);
defineOptions({ name: 'FormHightPage' });
const [register, { validate }] = useForm({
layout: 'vertical',
baseColProps: {
span: 6,
},
schemas: schemas,
showActionButtonGroup: false,
});
const tableRef = ref<{ getDataSource: () => any } | null>(null);
const [registerTask, { validate: validateTaskForm }] = useForm({
layout: 'vertical',
baseColProps: {
span: 6,
},
schemas: taskSchemas,
showActionButtonGroup: false,
});
const [register, { validate }] = useForm({
layout: 'vertical',
baseColProps: {
span: 6,
},
schemas: schemas,
showActionButtonGroup: false,
});
async function submitAll() {
try {
if (tableRef.value) {
console.log('table data:', tableRef.value.getDataSource());
}
const [registerTask, { validate: validateTaskForm }] = useForm({
layout: 'vertical',
baseColProps: {
span: 6,
},
schemas: taskSchemas,
showActionButtonGroup: false,
});
const [values, taskValues] = await Promise.all([validate(), validateTaskForm()]);
console.log('form data:', values, taskValues);
} catch (error) {}
async function submitAll() {
try {
if (tableRef.value) {
console.log('table data:', tableRef.value.getDataSource());
}
return { register, registerTask, submitAll, tableRef };
},
});
const [values, taskValues] = await Promise.all([validate(), validateTaskForm()]);
console.log('form data:', values, taskValues);
} catch (error) {
console.log(error);
}
}
</script>
<style lang="less" scoped>
.high-form {

View File

@ -3,17 +3,17 @@
<div class="step1-form">
<BasicForm @register="register">
<template #fac="{ model, field }">
<a-input-group compact>
<a-select v-model:value="model['pay']" class="pay-select">
<a-select-option value="zfb"> 支付宝 </a-select-option>
<a-select-option value="yl"> 银联 </a-select-option>
</a-select>
<Input.Group compact>
<Select v-model:value="model['pay']" class="pay-select">
<Select.Option value="zfb"> 支付宝 </Select.Option>
<Select.Option value="yl"> 银联 </Select.Option>
</Select>
<a-input class="pay-input" v-model:value="model[field]" />
</a-input-group>
</Input.Group>
</template>
</BasicForm>
</div>
<a-divider />
<Divider />
<h3>说明</h3>
<h4>转账到支付宝账户</h4>
<p>
@ -26,49 +26,35 @@
</p>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicForm, useForm } from '/@/components/Form';
<script lang="ts" setup>
import { BasicForm, useForm } from '@/components/Form';
import { step1Schemas } from './data';
import { Select, Input, Divider } from 'ant-design-vue';
export default defineComponent({
components: {
BasicForm,
[Select.name]: Select,
ASelectOption: Select.Option,
[Input.name]: Input,
[Input.Group.name]: Input.Group,
[Divider.name]: Divider,
},
emits: ['next'],
setup(_, { emit }) {
const [register, { validate }] = useForm({
labelWidth: 100,
schemas: step1Schemas,
actionColOptions: {
span: 14,
},
showResetButton: false,
submitButtonOptions: {
text: '下一步',
},
submitFunc: customSubmitFunc,
});
const emit = defineEmits(['next']);
async function customSubmitFunc() {
try {
const values = await validate();
emit('next', values);
} catch (error) {
//
}
}
return { register };
const [register, { validate }] = useForm({
labelWidth: 100,
schemas: step1Schemas,
actionColOptions: {
span: 14,
},
showResetButton: false,
submitButtonOptions: {
text: '下一步',
},
submitFunc: customSubmitFunc,
});
async function customSubmitFunc() {
try {
const values = await validate();
emit('next', values);
} catch (error) {
//
}
}
</script>
<style lang="less" scoped>
.step1 {

View File

@ -1,78 +1,61 @@
<template>
<div class="step2">
<a-alert message="确认转账后,资金将直接打入对方账户,无法退回。" show-icon />
<a-descriptions :column="1" class="mt-5">
<a-descriptions-item label="付款账户"> ant-design@alipay.com </a-descriptions-item>
<a-descriptions-item label="收款账户"> test@example.com </a-descriptions-item>
<a-descriptions-item label="收款人姓名"> Vben </a-descriptions-item>
<a-descriptions-item label="转账金额"> 500 </a-descriptions-item>
</a-descriptions>
<a-divider />
<div class="w-120 m-auto">
<Alert message="确认转账后,资金将直接打入对方账户,无法退回。" show-icon />
<Descriptions :column="1" class="mt-5">
<Descriptions.Item label="付款账户"> ant-design@alipay.com </Descriptions.Item>
<Descriptions.Item label="收款账户"> test@example.com </Descriptions.Item>
<Descriptions.Item label="收款人姓名"> Vben </Descriptions.Item>
<Descriptions.Item label="转账金额"> 500 </Descriptions.Item>
</Descriptions>
<Divider />
<BasicForm @register="register" />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicForm, useForm } from '/@/components/Form';
<script lang="ts" setup>
import { BasicForm, useForm } from '@/components/Form';
import { step2Schemas } from './data';
import { Alert, Divider, Descriptions } from 'ant-design-vue';
export default defineComponent({
components: {
BasicForm,
[Alert.name]: Alert,
[Divider.name]: Divider,
[Descriptions.name]: Descriptions,
[Descriptions.Item.name]: Descriptions.Item,
const emit = defineEmits(['next', 'prev']);
const [register, { validate, setProps }] = useForm({
labelWidth: 80,
schemas: step2Schemas,
actionColOptions: {
span: 14,
},
emits: ['next', 'prev'],
setup(_, { emit }) {
const [register, { validate, setProps }] = useForm({
labelWidth: 80,
schemas: step2Schemas,
actionColOptions: {
span: 14,
},
resetButtonOptions: {
text: '上一步',
},
submitButtonOptions: {
text: '提交',
},
resetFunc: customResetFunc,
submitFunc: customSubmitFunc,
});
async function customResetFunc() {
emit('prev');
}
async function customSubmitFunc() {
try {
const values = await validate();
setProps({
submitButtonOptions: {
loading: true,
},
});
setTimeout(() => {
setProps({
submitButtonOptions: {
loading: false,
},
});
emit('next', values);
}, 1500);
} catch (error) {}
}
return { register };
resetButtonOptions: {
text: '上一步',
},
submitButtonOptions: {
text: '提交',
},
resetFunc: customResetFunc,
submitFunc: customSubmitFunc,
});
</script>
<style lang="less" scoped>
.step2 {
width: 450px;
margin: 0 auto;
async function customResetFunc() {
emit('prev');
}
</style>
async function customSubmitFunc() {
try {
const values = await validate();
setProps({
submitButtonOptions: {
loading: true,
},
});
setTimeout(() => {
setProps({
submitButtonOptions: {
loading: false,
},
});
emit('next', values);
}, 1500);
} catch (error) {
console.error(error);
}
}
</script>

View File

@ -1,50 +1,23 @@
<template>
<div class="step3">
<a-result status="success" title="操作成功" sub-title="预计两小时内到账">
<div class="w-150 m-auto">
<Result status="success" title="操作成功" sub-title="预计两小时内到账">
<template #extra>
<a-button type="primary" @click="redo"> 再转一笔 </a-button>
<a-button type="primary" @click="emit('redo')"> 再转一笔 </a-button>
<a-button> 查看账单 </a-button>
</template>
</a-result>
<div class="desc-wrap">
<a-descriptions :column="1" class="mt-5">
<a-descriptions-item label="付款账户"> ant-design@alipay.com </a-descriptions-item>
<a-descriptions-item label="收款账户"> test@example.com </a-descriptions-item>
<a-descriptions-item label="收款人姓名"> Vben </a-descriptions-item>
<a-descriptions-item label="转账金额"> 500 </a-descriptions-item>
</a-descriptions>
</Result>
<div class="mt-6 px-6 py-8 bg-white">
<Descriptions :column="1" class="mt-5">
<Descriptions.Item label="付款账户"> ant-design@alipay.com </Descriptions.Item>
<Descriptions.Item label="收款账户"> test@example.com </Descriptions.Item>
<Descriptions.Item label="收款人姓名"> Vben </Descriptions.Item>
<Descriptions.Item label="转账金额"> 500 </Descriptions.Item>
</Descriptions>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
<script lang="ts" setup>
import { Result, Descriptions } from 'ant-design-vue';
export default defineComponent({
components: {
[Result.name]: Result,
[Descriptions.name]: Descriptions,
[Descriptions.Item.name]: Descriptions.Item,
},
emits: ['redo'],
setup(_, { emit }) {
return {
redo: () => {
emit('redo');
},
};
},
});
const emit = defineEmits(['redo']);
</script>
<style lang="less" scoped>
.step3 {
width: 600px;
margin: 0 auto;
}
.desc-wrap {
margin-top: 24px;
padding: 24px 40px;
background-color: @background-color-light;
}
</style>

View File

@ -1,4 +1,4 @@
import { FormSchema } from '/@/components/Form';
import { FormSchema } from '@/components/Form';
export const step1Schemas: FormSchema[] = [
{

Some files were not shown because too many files have changed in this diff Show More