搜索结果列表页面开发

This commit is contained in:
付民康
2025-03-12 18:41:20 +08:00
commit 7cebe8fc00
739 changed files with 88149 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
# IssueItem
### 说明
- IssueItem组件为issue卡片或列表展示时使用
``` js
// tempalte
<issue-item
:data="IssueItemData"
:hideChecked="false"
:key="updateCheckedKey"
@updateChecked="updateChecked"
@handleComments="handleComments"
@handleAvatar="handleAvatar"
>
</issue-item>
// script
const IssueItemData = [
{
checked: true,
isOpen: true,
title: 'Import Bug Fix',
tags: ['线上故障', '功能优化', '线上故障', '功能优化', '线上故障', '功能优化', '线上故障', '功能优化', '线上故障', '功能优化', '线上故障', '功能优化'],
index: 1,
userName: '李轩杨',
createdTime: '2023-07-22',
milestoneName: '里程碑名称',
midNum: 1,
commentsNum: 23,
updateTime: '2023-07-23',
statusIcon: 'icon-infomation',
statusIconColor: 'red',
avatarArr: [
{
imgSrc: 'https://avatars.githubusercontent.com/u/48074435?v=4'
},
{
imgSrc: 'https://avatars.githubusercontent.com/u/40119767?v=4'
},
{
imgSrc: 'https://avatars.githubusercontent.com/u/48074435?v=4'
}
]
},
{
checked: false,
isOpen: false,
title: 'Import Bug Fix',
tags: ['线上故障', '功能优化', '线上故障', '功能优化', '线上故障', '功能优化', '线上故障', '功能优化', '线上故障', '功能优化', '线上故障', '功能优化'],
index: 1,
userName: '李轩杨',
createdTime: '2023-07-22',
milestoneName: '里程碑名称',
midNum: 1,
commentsNum: 23,
updateTime: '2023-07-23'
}
];
const updateCheckedKey = ref(0);
const updateChecked = (checked:boolean, item:object, index:number) => {
IssueItemData[index].checked = checked;
updateCheckedKey.value += 1;
};
const handleComments = (item:object, index:number) => {
};
const handleAvatar = (item:object, index:number) => {
};
```
### Props
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| ------------ | ------------ | --------------------------------- | ------ | ------ |
| data | 列表数据 | arrayrow参数见下表props(data) | | [] |
| hideChecked? | 隐藏checkbox | boolean | | false |
### Props(data)
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|-----------|------------------------|----------------------------|----------|-----------|
| checked? | 是否选中 | boolean | | false |
| isOpen? | 是否开启 | boolean | | false |
| title | 标题 | string | | |
| tags | 标签数组 | array | | |
| indexLabel? | index自定义名称 | string \| number | | |
| userName | 用户名 | string | | |
| createdTime | 创建时间 | string | | |
| milestoneName | 里程碑名称 | string | | |
| midNum? | 中间布局数值 | string \| number | | |
| commentsNum | 评论数 | string \| number | | |
| updateTime | 更新时间 | string | | |
| statusIcon? | 状态颜色 | string | | |
| statusIconColor? | 状态icon | string | | |
| avatarArr? | 右侧头像列表 | array | 例如:[{imgSrc:'xxx'}] | |
### Emits
| 方法 | 说明 | 返回值 |
|-----------------|------------------------------------|---------------------|
| updateChecked | 点击checkbox触发 | checked, item, index分别为是否选中当前行对象index索引 |
| handleComments | 点击评论数触发 | item, index分别为当前行对象index索引 |
| handleMidNum | 点击中间数字触发 | item, index分别为当前行对象index索引 |
| handleAvatar | 点击头像区域触发 | item, index分别为当前行对象index索引 |
| handleTitle | 点击标题触发 | item, index分别为当前行对象index索引 |
### Slots
| 名称 | 说明 |
|---------------------|---------------------------------------------|
| checkbox | checkbox区域插槽 |
| tags | 标签区域插槽 |
| status | 索引前icon区域插槽 |
| midNum | 中间列区域插槽 |
| right | 右侧区域插槽 |
| avatar | 头像列表区域插槽 |

View File

@@ -0,0 +1,184 @@
<template>
<section >
<div class="g-issue-item" v-for="(item,index) in data" :key="index">
<div class="g-issue-item-card">
<div class="g-issue-item-card-checked" v-if="!hideChecked">
<slot name="checkbox">
<d-checkbox v-model="item.checked" @change="emits('updateChecked',item.checked,item,index)" />
</slot>
</div>
<div class="g-issue-item-left">
<div class="g-issue-item-left-header">
<div class="g-issue-item-left-header-title">
<d-icon name="icon-lock-private" v-if="!item.isOpen"></d-icon>
<slot name="title"></slot>
<p v-if='!$slots.title' @click="emits('handleTitle',item.checked,item,index)">{{item.title}}</p>
<slot name="tags">
<template v-for="(tag,index) in item.tags" :key="index">
<custom-tag
color="#ffffff"
border-color="#606060"
bg-color="#606060"
:title="tag"
/>
</template>
</slot>
</div>
</div>
<div class="g-issue-item-left-content">
<span>
<slot name="status">
<d-icon :color="item.statusIconColor" :name="item.statusIcon ? item.statusIcon : 'icon-start-use'"></d-icon> {{ item.indexLabel || `#${index + 1}` }}
</slot>
</span>
<span class="g-issue-item-dot">
</span>
<span>
{{item.userName}} <Time :time="item.createdTime"/>创建
</span>
<template v-if="item.milestoneName">
<span class="g-issue-item-dot"></span>
<span><d-icon name="icon-milestone"></d-icon> {{ item.milestoneName }}</span>
</template>
</div>
</div>
</div>
<div class="g-issue-item-right">
<slot name="right">
<div class="g-issue-item-right-num" @click="emits('handleMidNum',item,index)">
<slot name="midNum">
<d-icon name="icon-merge-request"></d-icon> {{ item.midNum }}
</slot>
</div>
<div class="g-issue-item-right-time">
<span class="g-issue-item-right-handle" >
<div class="g-issue-item-right-avatar" @click="emits('handleAvatar',item,index)">
<slot name="avatar">
<template v-for="(head,index) in item.avatarArr && item.avatarArr.slice(0,3)" :key="index">
<GAvatar :src="head.imgSrc" :width="20" :height="20"></GAvatar>
</template>
</slot>
</div>
<span @click="emits('handleComments',item,index)">
<d-icon name="icon-message"></d-icon> {{ item.commentsNum }}
</span>
</span>
<span>
<Time :time="item.updateTime"/>更新
</span>
</div>
</slot>
</div>
</div>
</section>
</template>
<script lang="ts" setup>
import type { IssueItemRow } from '@/components/IssueItem/types';
import CustomTag from '@/components/CustomTag/index.vue';
import Time from '@/components/Time/index.vue';
withDefaults(defineProps<{
data: IssueItemRow[];
hideChecked: boolean
}>(), {
data: () => [],
hideChecked: false
});
const emits = defineEmits(['updateChecked', 'handleTitle', 'handleComments', 'handleMidNum', 'handleAvatar']);
</script>
<style scoped lang="scss">
$g-issue-item-border-radius: 4px;
$g-issue-item-text-color: #606060;
.g-issue-item {
width: 100%;
display: flex;
justify-content: space-between;
.devui-icon__container {
vertical-align: middle;
}
&:last-of-type {
border-bottom: none;
}
&-dot {
width: 2px;
height: 2px;
background-color: $g-issue-item-text-color;
border-radius: 50%;
margin-top: 8px;
}
&-card {
display: flex;
&-checked {
margin: 20px 16px auto 0;
}
}
&-left {
&-header {
&-title {
font-size: 18px;
margin-right: 16px;
display: inline-flex;
flex-wrap: wrap;
.g-custom-tag {
margin-bottom: 8px;
}
.devui-icon__container {
margin-right: 4px;
}
p{
margin-top: -2px;
margin-right: 16px;
}
}
}
&-content {
display: flex;
margin-top: 12px;
span {
display: block;
margin-right: 16px;
color: $g-issue-item-text-color;
}
}
}
&-right {
display: flex;
color: $g-issue-item-text-color;
flex-shrink: 0;
&-num {
margin: 20px 48px;
}
&-handle {
display: flex;
margin-bottom: 8px;
cursor: pointer;
.devui-avatar {
display: flex;
margin-left: -8px;
}
}
&-avatar {
display: flex;
margin-right: 8px;
width: 40px;
flex-flow: row-reverse;
}
&-time {
margin-top: 10px;
text-align: right;
min-width: 100px;
}
}
}
</style>

View File

@@ -0,0 +1,20 @@
type avatarObj = {
imgSrc: string
}
export type IssueItemRow = {
checked: boolean,
isOpen?: boolean,
title?: string
tags: Array<string>,
indexLabel?: string | number,
userName: string
createdTime: string
milestoneName: string
midNum?:string | number
commentsNum: string | number
updateTime: string
statusIcon?: string
statusIconColor?: string
avatarArr?: Array<avatarObj>
}