搜索结果列表页面开发
This commit is contained in:
68
src/components/MemberAvatarList/README.md
Normal file
68
src/components/MemberAvatarList/README.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# MemberAvatarList组件
|
||||
|
||||
### 说明
|
||||
- 通用的用户头像列表组件,demo如下
|
||||
|
||||
``` js
|
||||
// template
|
||||
<member-avatar-list :data="userAvatarList2" hideBottomMore more-icon='icon-op-list' type-icon="icon-homepage" :count="127" :isRound="true" :showHover="false" title="成员" :to-more="`/home`" />
|
||||
// script
|
||||
const userAvatarList2: Array<userAvatarListRow> = [
|
||||
{
|
||||
avatar: 'https://avatars.githubusercontent.com/u/40119767?v=4',
|
||||
name: '曾恒瑶'
|
||||
},
|
||||
{
|
||||
avatar: 'https://avatars.githubusercontent.com/u/40119767?v=4',
|
||||
name: '曾恒瑶'
|
||||
},
|
||||
{
|
||||
avatar: 'https://avatars.githubusercontent.com/u/40119767?v=4',
|
||||
name: '曾恒瑶'
|
||||
}
|
||||
];
|
||||
```
|
||||
### Props
|
||||
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
| -------------- | -------------------- | ------- | ----------------- | ------ |
|
||||
| data | 头像列表 | array | 见下表 | [] |
|
||||
| title | 标题 | string | — | — |
|
||||
| toMore | 查看全部路由path | string | — | — |
|
||||
| isRound | 是否圆形 | boolean | false则为圆角矩形 | true |
|
||||
| showHover | 展示hover | boolean | — | false |
|
||||
| hideNum | 隐藏标签数字 | boolean | — | false |
|
||||
| hideBottomMore | 隐藏底部查看全部按钮 | boolean | — | false |
|
||||
| hideRightMore | 隐藏右上角全部按钮 | boolean | — | false |
|
||||
| type-icon | 标题前的类型图标 | string | — | — |
|
||||
| more-icon | 更多按钮图标 | string | — | — |
|
||||
| count | 成员数 | number | | 0 |
|
||||
|
||||
### Props(data)
|
||||
|
||||
注意:有头像src优先会显示,没有src则显示name,若设置了customText则优先显示自定义的文案
|
||||
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
|----------------|-------------------------|-------------------------------|-----------|-------|
|
||||
| avatar | 头像src | string | — | — |
|
||||
| name | 用户名 | string | — | — |
|
||||
| customText | 自定义文案 | string | — | — |
|
||||
|
||||
|
||||
### Emits
|
||||
|
||||
注意:以下事件都是组件内部对应的按钮点击触发,如果用插槽自定义对应区域的内容的话,事件自行监听即可
|
||||
|
||||
| 方法 | 说明 | 返回值 |
|
||||
|-----------|--------|-----------------------|
|
||||
| handleMore | 点击更多触发 | |
|
||||
|
||||
### Slots
|
||||
|
||||
| 名称 | 说明 |
|
||||
|--------------------|-------------------------------|
|
||||
| title | |
|
||||
| content | |
|
||||
| more | |
|
||||
| bottomMore | |
|
||||
|
||||
168
src/components/MemberAvatarList/index.vue
Normal file
168
src/components/MemberAvatarList/index.vue
Normal file
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<div class="g-member-avatar">
|
||||
<d-row justify="between" v-if="!hideTop">
|
||||
<d-col class="flex">
|
||||
<slot name="title">
|
||||
<Icon class="g-member-avatar-icon" :name="typeIcon"></Icon>
|
||||
<div class="g-member-avatar-title ml-2 text-G900 text-sm">{{ title }}</div>
|
||||
<span class="g-member-avatar-num ml-2 text-CG600 " v-if="!hideNum">{{ count }}</span>
|
||||
</slot>
|
||||
</d-col>
|
||||
<d-col v-if="!hideRightMore && data.length" @click="emits('handleMore')">
|
||||
<slot name="more">
|
||||
<router-link :to="toMore">
|
||||
<Icon :name="moreIcon" color="#707A8"></Icon>
|
||||
</router-link>
|
||||
</slot>
|
||||
</d-col>
|
||||
</d-row>
|
||||
<div class="g-member-avatar-list">
|
||||
<slot name="content">
|
||||
<template v-for="(item, index) in userData.slice(0, 25)" :key="index">
|
||||
<d-tooltip :content="item.name" :disabled="!showHover">
|
||||
<GAvatar class="mb-2" :class="{ 'g-member-avatar-list-rounded': !isRound }"
|
||||
:name="item.name" :is_round="isRound"
|
||||
:src="item.avatar"></GAvatar>
|
||||
</d-tooltip>
|
||||
</template>
|
||||
<!-- <template v-if="showBlank">
|
||||
<template v-for="(item, index) in (25 - userData.slice(0, 25).length)" :key="index">
|
||||
<div class="g-member-avatar-list-empty mb-2" :class="{ 'g-member-avatar-list-rounded': !isRound }"></div>
|
||||
</template>
|
||||
</template> -->
|
||||
</slot>
|
||||
</div>
|
||||
<router-link :to="toMore" v-if="!hideBottomMore && data.length">
|
||||
<div class="g-member-avatar-more" @click="emits('handleMore')">
|
||||
<slot name="bottomMore">
|
||||
查看全部{{ title }}
|
||||
</slot>
|
||||
</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
interface userAvatarListRow {
|
||||
username:string;
|
||||
iam_id:string;
|
||||
name?: string;
|
||||
avatar?:string;
|
||||
avatar_url?:string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
data?: Array<userAvatarListRow>;
|
||||
title?: string;
|
||||
hideNum?: boolean;
|
||||
count?: number;
|
||||
hideTop?: boolean;
|
||||
hideRightMore?: boolean;
|
||||
hideBottomMore?: boolean;
|
||||
toMore?: string
|
||||
isRound?: boolean
|
||||
showHover: boolean
|
||||
moreIcon?: string
|
||||
typeIcon?: string
|
||||
showBlank?: boolean
|
||||
}>(), {
|
||||
data: () => [],
|
||||
title: '组织成员',
|
||||
toMore: '',
|
||||
hideNum: false,
|
||||
count: 0,
|
||||
hideTop: false,
|
||||
hideRightMore: false,
|
||||
hideBottomMore: false,
|
||||
isRound: true,
|
||||
showHover: false,
|
||||
moreIcon: 'gt-all',
|
||||
typeIcon: 'gt-organizations-c',
|
||||
showBlank: true
|
||||
});
|
||||
const emits = defineEmits(['handleMore']);
|
||||
|
||||
const userData = ref<userAvatarListRow[]>([]);
|
||||
|
||||
watch(() => props.data, (val) => {
|
||||
init();
|
||||
}, {
|
||||
deep: true
|
||||
});
|
||||
|
||||
const init = async() => {
|
||||
userData.value = JSON.parse(JSON.stringify(props.data || []));
|
||||
// for (let [i, len] = [0, data.length]; i < len; i++) {
|
||||
// const item = data[i];
|
||||
// if (!item.avatar) {
|
||||
// item.noAvatar = true;
|
||||
// break;
|
||||
// // return false;
|
||||
// }
|
||||
// try {
|
||||
// await fetch(item.avatar);
|
||||
// } catch {
|
||||
// item.noAvatar = true;
|
||||
// }
|
||||
// }
|
||||
// userData.value = data;
|
||||
};
|
||||
init();
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
$g-member-avatar-border-color: rgba(0, 0, 0, 0.1);
|
||||
|
||||
.g-member-avatar {
|
||||
width: 100%;
|
||||
|
||||
&-icon {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
&-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 12px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&-empty {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid $g-member-avatar-border-color;
|
||||
border-radius: 50%;
|
||||
z-index: -1;
|
||||
margin-right: -4px;
|
||||
}
|
||||
|
||||
&-round {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
:deep(.devui-avatar) {
|
||||
margin-right: -4px;
|
||||
img {
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
&-rounded {
|
||||
border-radius: 4px !important;
|
||||
:deep(img) {
|
||||
border-radius: 4px !important;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.devui-icon__container) {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&-more {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user