Mn zhu/feat userhead mobile1 (#12)

* feat(userhead): 增加移动端头像组件

Signed-off-by: MNZhu <zhumaonan@aliyun.com>

* feat(userhead): 增加移动端头像组件

Signed-off-by: MNZhu <zhumaonan@aliyun.com>

---------

Signed-off-by: MNZhu <zhumaonan@aliyun.com>
This commit is contained in:
jacknan 2023-02-23 15:46:29 +08:00 committed by GitHub
parent e2b1cce6d2
commit 49a2d1f9a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 532 additions and 12 deletions

View File

@ -0,0 +1,56 @@
<template>
<div class="demo-content">
<div class="title">尺寸</div>
<div class="item-content">
<tiny-user-head type="label" v-model="name" :size="80" round></tiny-user-head>
<tiny-user-head type="label" v-model="name" size="large" round></tiny-user-head>
<tiny-user-head type="label" v-model="name" size="medium" round></tiny-user-head>
<tiny-user-head type="label" v-model="namePrefix" size="small" round></tiny-user-head>
</div>
<div class="title">类型</div>
<div class="item-content">
<tiny-user-head type="label" v-model="name" :size="80"></tiny-user-head>
<tiny-user-head type="icon" :size="80"></tiny-user-head>
<tiny-user-head type="image" modelValue="static/images/fruit.jpg" :size="80"></tiny-user-head>
</div>
<div class="title">自定义</div>
<div class="item-content">
<tiny-user-head type="icon" :size="80" backgroundColor="red"></tiny-user-head>
<tiny-user-head type="icon" :size="80" backgroundColor="red" round></tiny-user-head>
<tiny-user-head type="label" v-model="name" :size="80" messageTotal="20"></tiny-user-head>
<tiny-user-head type="label" v-model="name" :size="40" messageTotal="20"></tiny-user-head>
</div>
</div>
</template>
<script>
import { UserHead } from '@opentiny/vue'
export default {
components: {
TinyUserHead: UserHead
},
data() {
return {
name: '小明',
namePrefix: '小'
}
}
}
</script>
<style lang="less" scoped>
.title {
margin: 20px 0 10px 0;
}
.item-content {
display: flex;
align-items: center;
.tiny-mobile-user-head {
margin-right: 20px;
}
}
</style>

View File

@ -0,0 +1,16 @@
<template>
<div>
<tiny-user-head class="head-item" type="label" value="Ai" background-color="#40a9ff" color="#fa8c16"></tiny-user-head>
<tiny-user-head class="head-item" type="icon" :background-color="'rgb(250, 140, 22)'" color="rgb(64, 169, 255)"></tiny-user-head>
</div>
</template>
<script>
import { UserHead } from '@opentiny/vue'
export default {
components: {
TinyUserHead: UserHead
}
}
</script>

View File

@ -0,0 +1,13 @@
<template>
<tiny-user-head type="icon" background-color="var(--ti-common-color-line-active)"></tiny-user-head>
</template>
<script>
import { UserHead } from '@opentiny/vue'
export default {
components: {
TinyUserHead: UserHead
}
}
</script>

View File

@ -0,0 +1,39 @@
<template>
<tiny-user-head>
<div class="content">
<span>
<icon-mail></icon-mail>
</span>
Mail
</div>
</tiny-user-head>
</template>
<script>
import { UserHead } from '@opentiny/vue'
import { iconMail } from '@opentiny/vue-icon'
export default {
components: {
TinyUserHead: UserHead,
IconMail: iconMail()
}
}
</script>
<style scoped>
.content {
fill: var(--ti-common-color-line-active);
display: flex;
flex-direction: column;
height: 100%;
font-style: oblique;
font-weight: 600;
font-size: 2em;
}
.content svg {
width: 1.5em;
height: 1.5em;
}
</style>

View File

@ -0,0 +1,19 @@
<template>
<tiny-user-head type="icon" :value="IconSmile"></tiny-user-head>
</template>
<script>
import { UserHead } from '@opentiny/vue'
import { iconSmile } from '@opentiny/vue-icon'
export default {
components: {
TinyUserHead: UserHead
},
data() {
return {
IconSmile: iconSmile()
}
}
}
</script>

View File

@ -0,0 +1,18 @@
<template>
<tiny-user-head type="image" :modelValue="imgUrl"></tiny-user-head>
</template>
<script>
import { UserHead } from '@opentiny/vue'
export default {
components: {
TinyUserHead: UserHead
},
data() {
return {
imgUrl: 'static/images/fruit.jpg'
}
}
}
</script>

View File

@ -0,0 +1,18 @@
<template>
<tiny-user-head class="head-item" type="label" round v-model="text"></tiny-user-head>
</template>
<script>
import { UserHead } from '@opentiny/vue'
export default {
components: {
TinyUserHead: UserHead
},
data() {
return {
text: '文字'
}
}
}
</script>

View File

@ -0,0 +1,13 @@
<template>
<tiny-user-head :message-total="100" :message-upper-limit="99" type="icon"></tiny-user-head>
</template>
<script>
import { UserHead } from '@opentiny/vue'
export default {
components: {
TinyUserHead: UserHead
}
}
</script>

View File

@ -0,0 +1,13 @@
<template>
<tiny-user-head :message-total="100" type="icon"></tiny-user-head>
</template>
<script>
import { UserHead } from '@opentiny/vue'
export default {
components: {
TinyUserHead: UserHead
}
}
</script>

View File

@ -0,0 +1,13 @@
<template>
<tiny-user-head :message-total="100" message-type="basic" type="icon"></tiny-user-head>
</template>
<script>
import { UserHead } from '@opentiny/vue'
export default {
components: {
TinyUserHead: UserHead
}
}
</script>

View File

@ -0,0 +1,13 @@
<template>
<tiny-user-head type="icon" min></tiny-user-head>
</template>
<script>
import { UserHead } from '@opentiny/vue'
export default {
components: {
TinyUserHead: UserHead
}
}
</script>

View File

@ -0,0 +1,130 @@
<template>
<tiny-grid :data="tableData" border :edit-config="{ trigger: 'click', mode: 'cell', showStatus: true }">
<tiny-grid-column type="index" width="60"></tiny-grid-column>
<tiny-grid-column type="selection" width="60"></tiny-grid-column>
<tiny-grid-column field="employees" title="公司员工数" :renderer="renderUserHead"></tiny-grid-column>
<tiny-grid-column field="created_date" title="创建日期"></tiny-grid-column>
<tiny-grid-column field="city" title="城市"></tiny-grid-column>
<tiny-grid-column field="boole" title="布尔值" align="center" format-text="boole" :editor="checkboxEdit"></tiny-grid-column>
</tiny-grid>
</template>
<script lang="jsx">
import { Grid, GridColumn, UserHead } from '@opentiny/vue'
export default {
components: {
TinyGrid: Grid,
TinyGridColumn: GridColumn
},
data() {
const mockData = [
{
id: '1',
name: 'GFD科技公司',
city: '福州',
employees: 800,
created_date: '2014-04-30 00:56:00',
boole: false
},
{
id: '2',
name: 'WWW科技公司',
city: '深圳',
employees: 300,
created_date: '2016-07-08 12:36:22',
boole: true
},
{
id: '3',
name: 'RFV有限责任公司',
city: '中山',
employees: 1300,
created_date: '2014-02-14 14:14:14',
boole: false
},
{
id: '4',
name: 'TGB科技公司',
city: '龙岩',
employees: 360,
created_date: '2013-01-13 13:13:13',
boole: true
},
{
id: '5',
name: 'YHN科技公司',
city: '韶关',
employees: 810,
created_date: '2012-12-12 12:12:12',
boole: true
},
{
id: '6',
name: 'WSX科技公司',
city: '黄冈',
employees: 800,
created_date: '2011-11-11 11:11:11',
boole: true
},
{
id: '7',
name: 'KBG物业公司',
city: '赤壁',
employees: 400,
created_date: '2016-04-30 23:56:00',
boole: false
},
{
id: '8',
name: 'SZ市福德宝网络技术公司',
boole: true,
city: '厦门',
created_date: '2016-06-03 13:53:25',
employees: 540
}
]
return {
tableData: mockData
}
},
methods: {
checkboxEdit(h, { row, column }) {
return (
<input
type="checkbox"
checked={row.boole}
onChange={(event) => {
row[column.property] = event.target.checked
}}
/>
)
},
renderUserHead(h, { row }) {
const UserHeadImg = UserHead
return (
<span>
<UserHeadImg class="demo-user-head" type="icon" round min messageTotal={row.employees} />
{row.name}
</span>
)
}
}
}
</script>
<style scoped>
.hae-user-head .message {
width: 35px;
}
.tiny-grid-body__row {
height: 50px;
}
.demo-user-head {
float: left;
margin-right: 10px;
}
</style>

View File

@ -0,0 +1,13 @@
<template>
<tiny-user-head type="icon" round></tiny-user-head>
</template>
<script>
import { UserHead } from '@opentiny/vue'
export default {
components: {
TinyUserHead: UserHead
}
}
</script>

View File

@ -900,16 +900,48 @@
] ]
}, },
{ {
"path": "/mobile-avatar", "path": "/user-head",
"name": "Avatar 头像", "name": "UserHead 用户头像",
"children": [ "children": [
{ {
"path": "/mobile-avatar/avatar-size", "path": "/user-head/min-user-head",
"name": "设置头像大小" "name": "小头像"
}, },
{ {
"path": "/mobile-avatar/avatar-src-set", "path": "/user-head/round-user-head",
"name": "设置头像" "name": "圆形头像"
},
{
"path": "/user-head/label-user-head",
"name": "文字头像"
},
{
"path": "/user-head/icon-user-head",
"name": "图标头像"
},
{
"path": "/user-head/image-user-head",
"name": "图片头像"
},
{
"path": "/user-head/message-count",
"name": "消息计数"
},
{
"path": "/user-head/custom-color",
"name": "自定义颜色"
},
{
"path": "/user-head/custom-background-color",
"name": "自定义背景颜色"
},
{
"path": "/user-head/custom-user-head-content",
"name": "自定义图像内容"
},
{
"path": "/user-head/render-user-head-in-grid",
"name": "Grid单元格展示头像"
} }
] ]
}, },

View File

@ -1145,6 +1145,61 @@ const router = [
meta: { title: 'mobilepopover 气泡组件 - 类型', lang: 'zh-CN' }, meta: { title: 'mobilepopover 气泡组件 - 类型', lang: 'zh-CN' },
component: () => import(/* webpackChunkName: "mobileComp" */ './docs/mobile/popover/direction.md') component: () => import(/* webpackChunkName: "mobileComp" */ './docs/mobile/popover/direction.md')
}, },
{
path: 'user-head',
meta: { title: '其他组件-UserHead 用户头像', lang: 'zh-CN', sign: 'component' },
component: () => import(/* webpackChunkName: 'v3-user-head' */ './docs/zh-CN/user-head/basic-usage.md')
},
{
path: 'user-head/min-user-head',
meta: { title: '其他组件-UserHead 用户头像-小头像', lang: 'zh-CN', sign: 'component' },
component: () => import(/* webpackChunkName: 'v3-user-head' */ './docs/zh-CN/user-head/min-user-head.md')
},
{
path: 'user-head/round-user-head',
meta: { title: '其他组件-UserHead 用户头像-圆形头像', lang: 'zh-CN', sign: 'component' },
component: () => import(/* webpackChunkName: 'v3-user-head' */ './docs/zh-CN/user-head/round-user-head.md')
},
{
path: 'user-head/label-user-head',
meta: { title: '其他组件-UserHead 用户头像-文字头像', lang: 'zh-CN', sign: 'component' },
component: () => import(/* webpackChunkName: 'v3-user-head' */ './docs/zh-CN/user-head/label-user-head.md')
},
{
path: 'user-head/icon-user-head',
meta: { title: '其他组件-UserHead 用户头像-图标头像', lang: 'zh-CN', sign: 'component' },
component: () => import(/* webpackChunkName: 'v3-user-head' */ './docs/zh-CN/user-head/icon-user-head.md')
},
{
path: 'user-head/image-user-head',
meta: { title: '其他组件-UserHead 用户头像-图片头像', lang: 'zh-CN', sign: 'component' },
component: () => import(/* webpackChunkName: 'v3-user-head' */ './docs/zh-CN/user-head/image-user-head.md')
},
{
path: 'user-head/message-count',
meta: { title: '其他组件-UserHead 用户头像-消息计数', lang: 'zh-CN', sign: 'component' },
component: () => import(/* webpackChunkName: 'v3-user-head' */ './docs/zh-CN/user-head/message-count.md')
},
{
path: 'user-head/custom-color',
meta: { title: '其他组件-UserHead 用户头像-自定义颜色', lang: 'zh-CN', sign: 'component' },
component: () => import(/* webpackChunkName: 'v3-user-head' */ './docs/zh-CN/user-head/custom-color.md')
},
{
path: 'user-head/custom-background-color',
meta: { title: '其他组件-UserHead 用户头像-自定义背景颜色', lang: 'zh-CN', sign: 'component' },
component: () => import(/* webpackChunkName: 'v3-user-head' */ './docs/zh-CN/user-head/custom-background-color.md')
},
{
path: 'user-head/custom-user-head-content',
meta: { title: '其他组件-UserHead 用户头像-自定义图像内容', lang: 'zh-CN', sign: 'component' },
component: () => import(/* webpackChunkName: 'v3-user-head' */ './docs/zh-CN/user-head/custom-user-head-content.md')
},
{
path: 'user-head/render-user-head-in-grid',
meta: { title: '其他组件-UserHead 用户头像-Grid单元格展示头像', lang: 'zh-CN', sign: 'component' },
component: () => import(/* webpackChunkName: 'v3-user-head' */ './docs/zh-CN/user-head/render-user-head-in-grid.md')
},
{ {
path: 'table', path: 'table',
meta: { title: 'table 表格组件 - 类型', lang: 'zh-CN' }, meta: { title: 'table 表格组件 - 类型', lang: 'zh-CN' },

View File

@ -10,7 +10,6 @@
* *
*/ */
import UserHead from './src/index' import UserHead from './src/index'
import '@opentiny/vue-theme/user-head/index.css'
/* istanbul ignore next */ /* istanbul ignore next */
UserHead.install = function (Vue) { UserHead.install = function (Vue) {

View File

@ -11,8 +11,13 @@
*/ */
import { $props, $prefix, $setup } from '@opentiny/vue-common' import { $props, $prefix, $setup } from '@opentiny/vue-common'
import PCTemplate from './pc' import PCTemplate from './pc'
import MobileTemplate from './mobile'
const template = () => PCTemplate const template = (mode) => {
if (process.env.TINY_MODE === 'pc') return PCTemplate
else if (process.env.TINY_MODE === 'mobile') return MobileTemplate
else return mode === 'mobile' ? MobileTemplate : PCTemplate
}
export default { export default {
name: $prefix + 'UserHead', name: $prefix + 'UserHead',
@ -40,10 +45,7 @@ export default {
/** /**
* @property {String} [backgroundColor=#BBBBBB] - 背景色 * @property {String} [backgroundColor=#BBBBBB] - 背景色
*/ */
backgroundColor: { backgroundColor: String,
type: String,
default: '#BBBBBB'
},
/** /**
* @property {String} [type=label] - 头像类型icon|image|label 可选 * @property {String} [type=label] - 头像类型icon|image|label 可选
@ -83,6 +85,17 @@ export default {
messageUpperLimit: { messageUpperLimit: {
type: Number, type: Number,
default: 0 default: 0
},
/**
* @property {String, Number} [size=normal] - 头像尺寸
*/
size: {
type: [Number, String],
default: 'medium',
validator(val) {
return typeof val === 'string' ? ~['large', 'medium', 'small'].indexOf(val) : typeof val === 'number'
}
} }
}, },
setup(props, context) { setup(props, context) {

View File

@ -0,0 +1,46 @@
<!--
* Copyright (c) 2022 - present TinyVue Authors.
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
-->
<template>
<div class="tiny-mobile-user-head">
<div :style="{ ...state.style, width: `${state.size}px`, height: `${state.size}px` }" :class="['tiny-mobile-user-head__portrait', { min, round }, type]">
<slot>
<component v-if="type === 'icon'" :is="state.internalValue" class="tiny-mobile-svg-size" />
<span v-if="type === 'label'" :style="{ fontSize: `${state.size * 0.3}px` }" :title="state.internalValue">{{ state.label }}</span>
</slot>
</div>
<div
v-if="messageTotal"
:style="{ left: `${state.size * 0.9}px` }"
:class="['tiny-mobile-user-head__message', { min, round, basic: messageType === 'basic' || messageType === 'icon' }]"
>
{{ state.message }}
</div>
</div>
</template>
<script>
import { renderless, api } from '@opentiny/vue-renderless/user-head/vue'
import { props, setup } from '@opentiny/vue-common'
import { iconUser } from '@opentiny/vue-icon'
import '@opentiny/vue-theme-mobile/user-head/index.css'
export default {
components: {
IconUser: iconUser()
},
props: [...props, 'min', 'round', 'color', 'backgroundColor', 'type', 'modelValue', 'messageTotal', 'messageType', 'messageUpperLimit', 'size'],
setup(props, context) {
return setup({ props, context, renderless, api })
}
}
</script>

View File

@ -28,6 +28,7 @@
import { renderless, api } from '@opentiny/vue-renderless/user-head/vue' import { renderless, api } from '@opentiny/vue-renderless/user-head/vue'
import { props, setup } from '@opentiny/vue-common' import { props, setup } from '@opentiny/vue-common'
import { iconUser } from '@opentiny/vue-icon' import { iconUser } from '@opentiny/vue-icon'
import '@opentiny/vue-theme/user-head/index.css'
export default { export default {
components: { components: {