init
This commit is contained in:
25
uni_modules/nutui-uni/components/avatar/avatar.ts
Normal file
25
uni_modules/nutui-uni/components/avatar/avatar.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
import { commonProps, makeNumericProp, makeStringProp } from '../_utils'
|
||||
import type { AvatarShape, AvatarSize } from './type'
|
||||
|
||||
export const avatarProps = {
|
||||
...commonProps,
|
||||
/**
|
||||
* @description 头像的大小,可选值为:`large`、`normal`、`small`,支持直接输入数字
|
||||
*/
|
||||
size: makeNumericProp<AvatarSize | string | number | undefined>(undefined),
|
||||
/**
|
||||
* @description 头像的形状,可选值为:`square`、`round`
|
||||
*/
|
||||
shape: makeStringProp<AvatarShape | undefined>(undefined),
|
||||
/**
|
||||
* @description 背景色
|
||||
*/
|
||||
bgColor: makeStringProp('#eee'),
|
||||
/**
|
||||
* @description 字体颜色
|
||||
*/
|
||||
customColor: makeStringProp('#666'),
|
||||
}
|
||||
|
||||
export type AvatarProps = ExtractPropTypes<typeof avatarProps>
|
||||
139
uni_modules/nutui-uni/components/avatar/avatar.vue
Normal file
139
uni_modules/nutui-uni/components/avatar/avatar.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<script setup lang="ts">
|
||||
import type { CSSProperties } from 'vue'
|
||||
import { computed, defineComponent, getCurrentInstance, ref, watch } from 'vue'
|
||||
import { PREFIX } from '../_constants'
|
||||
import { useInject } from '../_hooks'
|
||||
import { getMainClass, getMainStyle, pxCheck } from '../_utils'
|
||||
import type { AvatarGroupProps } from '../avatargroup'
|
||||
import { AVATAR_GROUP_KEY } from '../avatargroup'
|
||||
import { avatarProps } from './avatar'
|
||||
import type { AvatarFinalSize, AvatarShape, AvatarSize } from './type'
|
||||
import { avatarSize } from './type'
|
||||
|
||||
const props = defineProps(avatarProps)
|
||||
|
||||
const instance = getCurrentInstance()
|
||||
|
||||
const { parent } = useInject<{ props: Required<AvatarGroupProps> }>(AVATAR_GROUP_KEY)
|
||||
|
||||
const show = ref(true)
|
||||
|
||||
const innerZIndex = ref<number | undefined>(undefined)
|
||||
|
||||
watch(() => ({
|
||||
maxCount: parent?.props.maxCount,
|
||||
children: parent?.internalChildren,
|
||||
}), ({ maxCount, children }) => {
|
||||
if (maxCount == null || Number(maxCount) <= 0 || children == null || instance == null) {
|
||||
show.value = true
|
||||
innerZIndex.value = undefined
|
||||
return
|
||||
}
|
||||
|
||||
const index = children.findIndex((item) => {
|
||||
return item.uid === instance.uid && !(item.props.customClass as string)?.includes('avatar-fold')
|
||||
})
|
||||
|
||||
if (index < 0) {
|
||||
show.value = true
|
||||
innerZIndex.value = undefined
|
||||
return
|
||||
}
|
||||
|
||||
show.value = index < Number(maxCount)
|
||||
|
||||
if (parent?.props.zIndex === 'right')
|
||||
innerZIndex.value = children.length - index
|
||||
else
|
||||
innerZIndex.value = undefined
|
||||
}, {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
})
|
||||
|
||||
function getTrulySize() {
|
||||
if (props.size != null)
|
||||
return props.size
|
||||
|
||||
if (parent != null && parent.props.size != null)
|
||||
return parent.props.size
|
||||
|
||||
return 'normal'
|
||||
}
|
||||
|
||||
const finalSize = computed<AvatarFinalSize>(() => {
|
||||
const size: string | number = getTrulySize()
|
||||
|
||||
const preset: boolean = avatarSize.includes(size as AvatarSize)
|
||||
|
||||
return {
|
||||
preset,
|
||||
value: preset ? (size as AvatarSize) : pxCheck(size),
|
||||
}
|
||||
})
|
||||
|
||||
const finalShape = computed<AvatarShape>(() => {
|
||||
if (props.shape != null)
|
||||
return props.shape
|
||||
|
||||
if (parent != null && parent.props.shape != null)
|
||||
return parent.props.shape
|
||||
|
||||
return 'round'
|
||||
})
|
||||
|
||||
const classes = computed(() => {
|
||||
const value: Record<string, boolean> = {
|
||||
[`nut-avatar-${finalShape.value}`]: true,
|
||||
'nut-hidden': !show.value,
|
||||
}
|
||||
|
||||
if (finalSize.value.preset)
|
||||
value[`nut-avatar-${finalSize.value.value}`] = true
|
||||
|
||||
return getMainClass(props, componentName, value)
|
||||
})
|
||||
|
||||
const styles = computed(() => {
|
||||
const value: CSSProperties = {
|
||||
backgroundColor: props.bgColor,
|
||||
color: props.customColor,
|
||||
}
|
||||
|
||||
if (!finalSize.value.preset) {
|
||||
value.width = finalSize.value.value
|
||||
value.height = finalSize.value.value
|
||||
}
|
||||
|
||||
if (parent?.props.span)
|
||||
value.marginLeft = pxCheck(parent?.props.span)
|
||||
|
||||
if (innerZIndex.value !== undefined)
|
||||
value.zIndex = innerZIndex.value
|
||||
|
||||
return getMainStyle(props, value)
|
||||
})
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
const componentName = `${PREFIX}-avatar`
|
||||
|
||||
export default defineComponent({
|
||||
name: componentName,
|
||||
options: {
|
||||
virtualHost: true,
|
||||
addGlobalClass: true,
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view :style="styles" :class="classes">
|
||||
<slot />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import './index';
|
||||
</style>
|
||||
55
uni_modules/nutui-uni/components/avatar/index.scss
Normal file
55
uni_modules/nutui-uni/components/avatar/index.scss
Normal file
@@ -0,0 +1,55 @@
|
||||
.nut-avatar {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
flex: 0 0 auto; // 防止被压缩
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 100% 100%;
|
||||
|
||||
image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.nut-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
background-size: 100% 100%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.nut-avatar-large {
|
||||
width: $avatar-large-width;
|
||||
height: $avatar-large-height;
|
||||
line-height: $avatar-large-height;
|
||||
}
|
||||
|
||||
.nut-avatar-normal {
|
||||
width: $avatar-normal-width;
|
||||
height: $avatar-normal-height;
|
||||
line-height: $avatar-normal-height;
|
||||
}
|
||||
|
||||
.nut-avatar-small {
|
||||
width: $avatar-small-width;
|
||||
height: $avatar-small-height;
|
||||
line-height: $avatar-small-height;
|
||||
}
|
||||
|
||||
.nut-avatar-square {
|
||||
border-radius: $avatar-square;
|
||||
}
|
||||
|
||||
.nut-avatar-round {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.nut-avatar-square,
|
||||
.nut-avatar-round {
|
||||
overflow: hidden;
|
||||
}
|
||||
2
uni_modules/nutui-uni/components/avatar/index.ts
Normal file
2
uni_modules/nutui-uni/components/avatar/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './avatar'
|
||||
export * from './type'
|
||||
16
uni_modules/nutui-uni/components/avatar/type.ts
Normal file
16
uni_modules/nutui-uni/components/avatar/type.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export const avatarSize = ['large', 'normal', 'small'] as const
|
||||
export type AvatarSize = (typeof avatarSize)[number]
|
||||
|
||||
export const avatarShape = ['round', 'square'] as const
|
||||
export type AvatarShape = (typeof avatarShape)[number]
|
||||
|
||||
export interface AvatarFinalSize {
|
||||
/**
|
||||
* 是否为预设尺寸
|
||||
*/
|
||||
preset: boolean
|
||||
/**
|
||||
* 尺寸值
|
||||
*/
|
||||
value: string
|
||||
}
|
||||
Reference in New Issue
Block a user