committed by
GitHub
67 changed files with 5217 additions and 4647 deletions
@ -0,0 +1,4 @@ |
|||
import { withInstall } from '/@/utils'; |
|||
import cardList from './src/CardList.vue'; |
|||
|
|||
export const CardList = withInstall(cardList); |
|||
@ -0,0 +1,178 @@ |
|||
<template> |
|||
<div class="p-2"> |
|||
<div class="bg-white mb-2 p-4"> |
|||
<BasicForm @register="registerForm" /> |
|||
</div> |
|||
{{ sliderProp.width }} |
|||
<div class="bg-white p-2"> |
|||
<List |
|||
:grid="{ gutter: 5, xs: 1, sm: 2, md: 4, lg: 4, xl: 6, xxl: grid }" |
|||
:data-source="data" |
|||
:pagination="paginationProp" |
|||
> |
|||
<template #header> |
|||
<div class="flex justify-end space-x-2" |
|||
><slot name="header"></slot> |
|||
<Tooltip> |
|||
<template #title> |
|||
<div class="w-50">每行显示数量</div |
|||
><Slider |
|||
id="slider" |
|||
v-bind="sliderProp" |
|||
v-model:value="grid" |
|||
@change="sliderChange" |
|||
/></template> |
|||
<Button><TableOutlined /></Button> |
|||
</Tooltip> |
|||
<Tooltip @click="fetch"> |
|||
<template #title>刷新</template> |
|||
<Button><RedoOutlined /></Button> |
|||
</Tooltip> |
|||
</div> |
|||
</template> |
|||
<template #renderItem="{ item }"> |
|||
<ListItem> |
|||
<Card> |
|||
<template #title></template> |
|||
<template #cover> |
|||
<div :class="height"> |
|||
<Image :src="item.imgs[0]" /> |
|||
</div> |
|||
</template> |
|||
<template class="ant-card-actions" #actions> |
|||
<!-- <SettingOutlined key="setting" />--> |
|||
<EditOutlined key="edit" /> |
|||
<Dropdown |
|||
:trigger="['hover']" |
|||
:dropMenuList="[ |
|||
{ |
|||
text: '删除', |
|||
event: '1', |
|||
popConfirm: { |
|||
title: '是否确认删除', |
|||
confirm: handleDelete.bind(null, item.id), |
|||
}, |
|||
}, |
|||
]" |
|||
popconfirm |
|||
> |
|||
<EllipsisOutlined key="ellipsis" /> |
|||
</Dropdown> |
|||
</template> |
|||
|
|||
<CardMeta> |
|||
<template #title> |
|||
<TypographyText :content="item.name" :ellipsis="{ tooltip: item.address }" /> |
|||
</template> |
|||
<template #avatar> |
|||
<Avatar :src="item.avatar" /> |
|||
</template> |
|||
<template #description>{{ item.time }}</template> |
|||
</CardMeta> |
|||
</Card> |
|||
</ListItem> |
|||
</template> |
|||
</List> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script lang="ts" setup> |
|||
import { computed, onMounted, ref } from 'vue'; |
|||
import { |
|||
EditOutlined, |
|||
EllipsisOutlined, |
|||
RedoOutlined, |
|||
TableOutlined, |
|||
} from '@ant-design/icons-vue'; |
|||
import { List, Card, Image, Typography, Tooltip, Slider, Avatar } from 'ant-design-vue'; |
|||
import { Dropdown } from '/@/components/Dropdown'; |
|||
import { BasicForm, useForm } from '/@/components/Form'; |
|||
import { propTypes } from '/@/utils/propTypes'; |
|||
import { Button } from '/@/components/Button'; |
|||
import { isFunction } from '/@/utils/is'; |
|||
import { useSlider, grid } from './data'; |
|||
const ListItem = List.Item; |
|||
const CardMeta = Card.Meta; |
|||
const TypographyText = Typography.Text; |
|||
// 获取slider属性 |
|||
const sliderProp = computed(() => useSlider(4)); |
|||
// 组件接收参数 |
|||
const props = defineProps({ |
|||
// 请求API的参数 |
|||
params: propTypes.object.def({}), |
|||
//api |
|||
api: propTypes.func, |
|||
}); |
|||
//暴露内部方法 |
|||
const emit = defineEmits(['getMethod', 'delete']); |
|||
//数据 |
|||
const data = ref([]); |
|||
// 切换每行个数 |
|||
// cover图片自适应高度 |
|||
//修改pageSize并重新请求数据 |
|||
|
|||
const height = computed(() => { |
|||
return `h-${120 - grid.value * 6}`; |
|||
}); |
|||
//表单 |
|||
const [registerForm, { validate }] = useForm({ |
|||
schemas: [{ field: 'type', component: 'Input', label: '类型' }], |
|||
labelWidth: 80, |
|||
baseColProps: { span: 6 }, |
|||
actionColOptions: { span: 24 }, |
|||
autoSubmitOnEnter: true, |
|||
submitFunc: handleSubmit, |
|||
}); |
|||
//表单提交 |
|||
async function handleSubmit() { |
|||
const data = await validate(); |
|||
await fetch(data); |
|||
} |
|||
function sliderChange(n) { |
|||
pageSize.value = n * 4; |
|||
fetch(); |
|||
} |
|||
|
|||
// 自动请求并暴露内部方法 |
|||
onMounted(() => { |
|||
fetch(); |
|||
emit('getMethod', fetch); |
|||
}); |
|||
|
|||
async function fetch(p = {}) { |
|||
const { api, params } = props; |
|||
if (api && isFunction(api)) { |
|||
const res = await api({ ...params, page: page.value, pageSize: pageSize.value, ...p }); |
|||
data.value = res.items; |
|||
total.value = res.total; |
|||
} |
|||
} |
|||
//分页相关 |
|||
const page = ref(1); |
|||
const pageSize = ref(36); |
|||
const total = ref(0); |
|||
const paginationProp = ref({ |
|||
showSizeChanger: false, |
|||
showQuickJumper: true, |
|||
pageSize, |
|||
current: page, |
|||
total, |
|||
showTotal: (total) => `总 ${total} 条`, |
|||
onChange: pageChange, |
|||
onShowSizeChange: pageSizeChange, |
|||
}); |
|||
|
|||
function pageChange(p, pz) { |
|||
page.value = p; |
|||
pageSize.value = pz; |
|||
fetch(); |
|||
} |
|||
function pageSizeChange(current, size) { |
|||
pageSize.value = size; |
|||
fetch(); |
|||
} |
|||
|
|||
async function handleDelete(id) { |
|||
emit('delete', id); |
|||
} |
|||
</script> |
|||
@ -0,0 +1,25 @@ |
|||
import { ref } from 'vue'; |
|||
//每行个数
|
|||
export const grid = ref(12); |
|||
// slider属性
|
|||
export const useSlider = (min = 6, max = 12) => { |
|||
// 每行显示个数滑动条
|
|||
const getMarks = () => { |
|||
const l = {}; |
|||
for (let i = min; i < max + 1; i++) { |
|||
l[i] = { |
|||
style: { |
|||
color: '#fff', |
|||
}, |
|||
label: i, |
|||
}; |
|||
} |
|||
return l; |
|||
}; |
|||
return { |
|||
min, |
|||
max, |
|||
marks: getMarks(), |
|||
step: 1, |
|||
}; |
|||
}; |
|||
@ -0,0 +1,5 @@ |
|||
export enum MODE { |
|||
JSON = 'application/json', |
|||
HTML = 'htmlmixed', |
|||
JS = 'javascript', |
|||
} |
|||
@ -1,5 +1,7 @@ |
|||
import { withInstall } from '/@/utils'; |
|||
import markDown from './src/Markdown.vue'; |
|||
import markDownViewer from './src/MarkdownViewer.vue'; |
|||
|
|||
export const MarkDown = withInstall(markDown); |
|||
export const MarkdownViewer = withInstall(markDownViewer); |
|||
export * from './src/typing'; |
|||
|
|||
@ -0,0 +1,22 @@ |
|||
<template> |
|||
<div v-html="getHtmlData" :class="$props.class" class="markdown-viewer"></div> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { computed } from 'vue'; |
|||
import showdown from 'showdown'; |
|||
|
|||
const converter = new showdown.Converter(); |
|||
converter.setOption('tables', true); |
|||
const props = defineProps({ |
|||
value: { type: String }, |
|||
class: { type: String }, |
|||
}); |
|||
const getHtmlData = computed(() => converter.makeHtml(props.value || '')); |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.markdown-viewer { |
|||
width: 100%; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,32 @@ |
|||
<template> |
|||
<PageWrapper title="卡片列表示例" content="基础封装"> |
|||
<CardList :params="params" :api="demoListApi" @getMethod="getMethod" @delete="handleDel"> |
|||
<template #header> |
|||
<Button type="primary" color="error"> 按钮1 </Button> |
|||
<Button type="primary" color="success"> 按钮2 </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'; |
|||
const { notification } = useMessage(); |
|||
// 请求api时附带参数 |
|||
const params = {}; |
|||
|
|||
let reload = () => {}; |
|||
// 获取内部fetch方法; |
|||
function getMethod(m: any) { |
|||
reload = m; |
|||
} |
|||
//删除按钮事件 |
|||
function handleDel(id) { |
|||
console.log(id); |
|||
notification.success({ message: `成功删除${id}` }); |
|||
reload(); |
|||
} |
|||
</script> |
|||
File diff suppressed because it is too large
Loading…
Reference in new issue