提交 | 用户 | age
|
0f5ddb
|
1 |
<template> |
J |
2 |
<div class="p-2"> |
a248e2
|
3 |
<div class="p-4 mb-2 bg-white"> |
0f5ddb
|
4 |
<BasicForm @register="registerForm" /> |
J |
5 |
</div> |
|
6 |
{{ sliderProp.width }} |
a248e2
|
7 |
<div class="p-2 bg-white"> |
628e82
|
8 |
<List |
0f5ddb
|
9 |
:grid="{ gutter: 5, xs: 1, sm: 2, md: 4, lg: 4, xl: 6, xxl: grid }" |
J |
10 |
:data-source="data" |
|
11 |
:pagination="paginationProp" |
|
12 |
> |
|
13 |
<template #header> |
|
14 |
<div class="flex justify-end space-x-2" |
|
15 |
><slot name="header"></slot> |
|
16 |
<Tooltip> |
|
17 |
<template #title> |
|
18 |
<div class="w-50">每行显示数量</div |
|
19 |
><Slider |
|
20 |
id="slider" |
|
21 |
v-bind="sliderProp" |
|
22 |
v-model:value="grid" |
|
23 |
@change="sliderChange" |
|
24 |
/></template> |
|
25 |
<Button><TableOutlined /></Button> |
|
26 |
</Tooltip> |
|
27 |
<Tooltip @click="fetch"> |
|
28 |
<template #title>刷新</template> |
|
29 |
<Button><RedoOutlined /></Button> |
|
30 |
</Tooltip> |
|
31 |
</div> |
|
32 |
</template> |
|
33 |
<template #renderItem="{ item }"> |
|
34 |
<ListItem> |
|
35 |
<Card> |
|
36 |
<template #title></template> |
|
37 |
<template #cover> |
|
38 |
<div :class="height"> |
|
39 |
<Image :src="item.imgs[0]" /> |
|
40 |
</div> |
|
41 |
</template> |
|
42 |
<template class="ant-card-actions" #actions> |
|
43 |
<!-- <SettingOutlined key="setting" />--> |
|
44 |
<EditOutlined key="edit" /> |
|
45 |
<Dropdown |
|
46 |
:trigger="['hover']" |
|
47 |
:dropMenuList="[ |
|
48 |
{ |
|
49 |
text: '删除', |
|
50 |
event: '1', |
|
51 |
popConfirm: { |
|
52 |
title: '是否确认删除', |
|
53 |
confirm: handleDelete.bind(null, item.id), |
|
54 |
}, |
|
55 |
}, |
|
56 |
]" |
|
57 |
popconfirm |
|
58 |
> |
|
59 |
<EllipsisOutlined key="ellipsis" /> |
|
60 |
</Dropdown> |
|
61 |
</template> |
|
62 |
|
|
63 |
<CardMeta> |
|
64 |
<template #title> |
|
65 |
<TypographyText :content="item.name" :ellipsis="{ tooltip: item.address }" /> |
|
66 |
</template> |
|
67 |
<template #avatar> |
|
68 |
<Avatar :src="item.avatar" /> |
|
69 |
</template> |
|
70 |
<template #description>{{ item.time }}</template> |
|
71 |
</CardMeta> |
|
72 |
</Card> |
|
73 |
</ListItem> |
|
74 |
</template> |
628e82
|
75 |
</List> |
无 |
76 |
</div> |
0f5ddb
|
77 |
</div> |
J |
78 |
</template> |
|
79 |
<script lang="ts" setup> |
|
80 |
import { computed, onMounted, ref } from 'vue'; |
|
81 |
import { |
|
82 |
EditOutlined, |
|
83 |
EllipsisOutlined, |
|
84 |
RedoOutlined, |
|
85 |
TableOutlined, |
|
86 |
} from '@ant-design/icons-vue'; |
628e82
|
87 |
import { List, Card, Image, Typography, Tooltip, Slider, Avatar } from 'ant-design-vue'; |
0f5ddb
|
88 |
import { Dropdown } from '/@/components/Dropdown'; |
J |
89 |
import { BasicForm, useForm } from '/@/components/Form'; |
|
90 |
import { propTypes } from '/@/utils/propTypes'; |
|
91 |
import { Button } from '/@/components/Button'; |
|
92 |
import { isFunction } from '/@/utils/is'; |
|
93 |
import { useSlider, grid } from './data'; |
628e82
|
94 |
const ListItem = List.Item; |
无 |
95 |
const CardMeta = Card.Meta; |
|
96 |
const TypographyText = Typography.Text; |
0f5ddb
|
97 |
// 获取slider属性 |
J |
98 |
const sliderProp = computed(() => useSlider(4)); |
|
99 |
// 组件接收参数 |
|
100 |
const props = defineProps({ |
|
101 |
// 请求API的参数 |
|
102 |
params: propTypes.object.def({}), |
|
103 |
//api |
|
104 |
api: propTypes.func, |
|
105 |
}); |
|
106 |
//暴露内部方法 |
|
107 |
const emit = defineEmits(['getMethod', 'delete']); |
|
108 |
//数据 |
|
109 |
const data = ref([]); |
|
110 |
// 切换每行个数 |
|
111 |
// cover图片自适应高度 |
|
112 |
//修改pageSize并重新请求数据 |
|
113 |
|
|
114 |
const height = computed(() => { |
|
115 |
return `h-${120 - grid.value * 6}`; |
|
116 |
}); |
|
117 |
//表单 |
|
118 |
const [registerForm, { validate }] = useForm({ |
|
119 |
schemas: [{ field: 'type', component: 'Input', label: '类型' }], |
|
120 |
labelWidth: 80, |
|
121 |
baseColProps: { span: 6 }, |
|
122 |
actionColOptions: { span: 24 }, |
|
123 |
autoSubmitOnEnter: true, |
|
124 |
submitFunc: handleSubmit, |
|
125 |
}); |
|
126 |
//表单提交 |
|
127 |
async function handleSubmit() { |
|
128 |
const data = await validate(); |
|
129 |
await fetch(data); |
|
130 |
} |
|
131 |
function sliderChange(n) { |
|
132 |
pageSize.value = n * 4; |
|
133 |
fetch(); |
|
134 |
} |
|
135 |
|
|
136 |
// 自动请求并暴露内部方法 |
|
137 |
onMounted(() => { |
|
138 |
fetch(); |
|
139 |
emit('getMethod', fetch); |
|
140 |
}); |
|
141 |
|
|
142 |
async function fetch(p = {}) { |
|
143 |
const { api, params } = props; |
|
144 |
if (api && isFunction(api)) { |
|
145 |
const res = await api({ ...params, page: page.value, pageSize: pageSize.value, ...p }); |
|
146 |
data.value = res.items; |
|
147 |
total.value = res.total; |
|
148 |
} |
|
149 |
} |
|
150 |
//分页相关 |
|
151 |
const page = ref(1); |
|
152 |
const pageSize = ref(36); |
|
153 |
const total = ref(0); |
|
154 |
const paginationProp = ref({ |
|
155 |
showSizeChanger: false, |
|
156 |
showQuickJumper: true, |
|
157 |
pageSize, |
|
158 |
current: page, |
|
159 |
total, |
|
160 |
showTotal: (total) => `总 ${total} 条`, |
|
161 |
onChange: pageChange, |
|
162 |
onShowSizeChange: pageSizeChange, |
|
163 |
}); |
|
164 |
|
|
165 |
function pageChange(p, pz) { |
|
166 |
page.value = p; |
|
167 |
pageSize.value = pz; |
|
168 |
fetch(); |
|
169 |
} |
a248e2
|
170 |
function pageSizeChange(_current, size) { |
0f5ddb
|
171 |
pageSize.value = size; |
J |
172 |
fetch(); |
|
173 |
} |
|
174 |
|
|
175 |
async function handleDelete(id) { |
|
176 |
emit('delete', id); |
|
177 |
} |
|
178 |
</script> |