forked from ccsens_fe/tall-mui-3
35 changed files with 1348 additions and 317 deletions
@ -0,0 +1,25 @@ |
|||
@font-face { |
|||
font-family: 'custom-icon'; /* Project id 2685595 */ |
|||
src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAVsAAsAAAAACgAAAAUfAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFQGYACDHAqGfIV2ATYCJAMQCwoABCAFhQsHURurCMiuMYUxPrWYbZJ11AENNuDWinu9B3343wTPy36/c+WrJmkq4NUbnswqIdo6oyVCh0pjZM3kN/Sb+9vabmY0s5OZwYtCdsO5QNnpi6ia8CLyL4qgGGt7b54+glfxrBKtmXWGqFaCp0B7SiATEr1ANPXvGzvOkmQsS994MvzlXijX3tRv70+uPsD5P2a6+rgS+DYAiUqMLBrYLNryeeZlUwrdgcsp3zK86iB34z4IiBvJJR7XVDYCxyMKmYEvKb1YEAXLkZ6hgJKT8gqiiArC0K2pSryAEPRW3AB48n5e/iSGEiqUpF9oa4fQglNvlF+/krv/O0w+Mra/NDxdQQgY6M1MLnvV2nOSwNYjES+ySM0BlCVK0Wvbz9vn/6foq+JGjX95YJRAMnRukoAZju0YzSLB8HWdBMXXc/oJcJ3MjoIIpAsgJwhUvkUYmwyUFcbgMUNP8NZs7bxRHjnzp3oxW69OvXx796hdkdpN5y5Ebxkdwyy0i/vNo9wbK1Xk1tF54gvn5PfeNWr37ctTr8YwJ4XR/NAFC9xLZaNP2FbujgGf9ZwyD3DnQc33oheKon7aLHNKrdlOcW+0bV5gW7ibN8+jySFrJfPtigKKzb6vTcXsU1BaIFpe6HwCu/HkmhO2hddjq6Os03jJqjnAq0/wSUKsCLT6KWyVajV+esn9acKTJM832i45UpN9vEPRUT/rJt1Vl7sTtltjd1k1fPmx0O7qFsi9o/lcd+Piclq/x9+580euFfJOCmlCHm/aHdDEN/PVN2zf9aPirdu0KH7P0SfDgoYGPQFri6pmqOdydenxe+I+WE4sH5ScnFTZJ+RLfZZHvhxl+quLBcFV4bqiUqj8l3pCPinq2zdJobhZQax0/jn2f2PJLqEkFUKCDGdd67Hz6D/QX4mH+54XSbEkO1wwcsrateiYAnm2zJj4XzyIP9iZJnPb2yQxR7jJ0iyxJGZOZNQb5edFksqISkmx1C8hrsyzYxI92fKrJEUZRVVE8EfIvDkhSo+Dj/vvmGKPBEm+ISJUYzGXqGI63CfMLYviAmXcHlXBldMNmsSZESsm7p81fsPwjGLxrMnDPa52Cvf9K/u+bBkq9nogPMTf6hWWem4in+r5+O+msp5NnqCxc74uZw8BPnaYGyL7iGpFM6qiCGYIzm4BL6ccX5slzxpOHy1i2UhUcchS+VJUpKlS3BzxfVT8lW8BEVPoJtfHVEeU/vg2X8xlNFB4xED/XyMHq8EtAARbEjtvdvYsqQWCpGk26h+cxt/IEQ39nbL/c1x/46efq5IwYTz+IRqY+sd54MMBnGyKATz1lKgWBcCVmPYRGLYoiBsK+MVckPekD2HhPTpEQiGCKqIGTUId6WCEDIFlZBiswbiuOkpvs4eRkFQeNMzEUJTthyrtDZqy+0gHXxEhbMiQYeAH4w4i4biERkws4iCFoBZrGYzpadasM6MQ3WlBrAnXOtdDptNIcUJ6aG6GnEWPS7EEdXyBswSaIdfdCksXk4iQDtNxrAnT9HsxaDSyWDvHtkEaqVsRas+Mi9MVvYmaZk2gCAeiIJAWpsVgGD0ay0znHEJonSwQlgle8XvqQYxORhSuOo8CSzOI47h6MhhMArV4GLKEa4ZmneEqiy6MRAiig1lcrp0eo5mzGjIaNhamvXhSG4iGqLW2sLTLFEcK6aBc9bh80wWvAeL0m3okIhmpSIuvI0TRrSZoRvYm1gwH06zRuOFr7IrwlkFGnIPazkEAAAA=') |
|||
format('woff2'); |
|||
} |
|||
|
|||
.custom-icon { |
|||
font-family: 'custom-icon' !important; |
|||
font-size: 16px; |
|||
font-style: normal; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
} |
|||
|
|||
.custom-icon-attachment:before { |
|||
content: '\e7e1'; |
|||
} |
|||
|
|||
.custom-icon-moneycollect:before { |
|||
content: '\e7cd'; |
|||
} |
|||
|
|||
.custom-icon-C-bxl-redux:before { |
|||
content: '\e608'; |
|||
} |
Binary file not shown.
@ -0,0 +1,58 @@ |
|||
<template> |
|||
<view class="m-2"> |
|||
<u-card margin="0" :show-head="false" :show-foot="false" border-radius="25" :style="{ height: isShrink ? '96rpx' : '300rpx' }"> |
|||
<!-- <u-card margin="0" :show-head="false" :show-foot="false" border-radius="25" style="height: 300rpx"> --> |
|||
<view slot="body"> |
|||
<scroll-view :scrollY="true" :style="{ height: isShrink ? '40rpx' : '240rpx' }"> |
|||
<view class="u-col-between p-0 u-skeleton"> |
|||
<view class="u-line-2 u-skeleton-rect"> 瓶身描绘的牡丹一如你初妆</view> |
|||
<view class="u-line-2 u-skeleton-rect mt-2"> 瓶身描绘的牡丹一如你初妆</view> |
|||
<view class="u-line-2 u-skeleton-rect mt-2"> 瓶身描绘的牡丹一如你初妆</view> |
|||
<view class="u-line-2 u-skeleton-rect mt-2"> 瓶身描绘的牡丹一如你初妆</view> |
|||
<view class="u-line-2 u-skeleton-rect mt-2"> 瓶身描绘的牡丹一如你初妆</view> |
|||
<view class="u-line-2 u-skeleton-rect mt-2"> 瓶身描绘的牡丹一如你初妆</view> |
|||
<view class="u-line-2 u-skeleton-rect mt-2"> 瓶身描绘的牡丹一如你初妆</view> |
|||
<view class="u-line-2 u-skeleton-rect mt-2"> 瓶身描绘的牡丹一如你初妆</view> |
|||
<view class="u-line-2 u-skeleton-rect mt-2"> 瓶身描绘的牡丹一如你初妆</view> |
|||
<view class="u-line-2 u-skeleton-rect mt-2"> 瓶身描绘的牡丹一如你初妆</view> |
|||
<view class="u-line-2 u-skeleton-rect mt-2"> 瓶身描绘的牡丹一如你初妆</view> |
|||
<view class="u-line-2 u-skeleton-rect mt-2"> 瓶身描绘的牡丹一如你初妆222</view> |
|||
</view> |
|||
</scroll-view> |
|||
</view> |
|||
</u-card> |
|||
<!-- <u-skeleton :animation="true" :loading="true" bgcolor="#fff"></u-skeleton> --> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapState } from 'vuex'; |
|||
export default { |
|||
name: 'Global', |
|||
data() { |
|||
return {}; |
|||
}, |
|||
computed: mapState('home', ['isShrink']), |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.u-card-wrap { |
|||
background-color: $u-bg-color; |
|||
padding: 1px; |
|||
} |
|||
|
|||
.u-body-item { |
|||
font-size: 32rpx; |
|||
color: #333; |
|||
padding: 20rpx 10rpx; |
|||
} |
|||
|
|||
.u-body-item image { |
|||
width: 120rpx; |
|||
flex: 0 0 120rpx; |
|||
height: 120rpx; |
|||
border-radius: 8rpx; |
|||
margin-left: 12rpx; |
|||
} |
|||
</style> |
@ -1,47 +0,0 @@ |
|||
<!-- |
|||
* @Author: aBin |
|||
* @email: binbin0314@126.com |
|||
* @Date: 2021-07-19 10:52:05 |
|||
* @LastEditors: aBin |
|||
* @LastEditTime: 2021-07-19 11:09:23 |
|||
--> |
|||
<template> |
|||
<view> |
|||
<u-card margin="0" :show-head="false" :show-foot="false"> |
|||
<view slot="body"> |
|||
<view class="u-flex u-col-between p-0"> |
|||
<view class="u-body-item-title u-line-2">瓶身描绘的牡丹一如你初妆,冉冉檀香透过窗心事我了然,宣纸上走笔至此搁一半</view> |
|||
</view> |
|||
</view> |
|||
</u-card> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: 'Global', |
|||
data() { |
|||
return {}; |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.u-card-wrap { |
|||
background-color: $u-bg-color; |
|||
padding: 1px; |
|||
} |
|||
|
|||
.u-body-item { |
|||
font-size: 32rpx; |
|||
color: #333; |
|||
padding: 20rpx 10rpx; |
|||
} |
|||
|
|||
.u-body-item image { |
|||
width: 120rpx; |
|||
flex: 0 0 120rpx; |
|||
height: 120rpx; |
|||
border-radius: 8rpx; |
|||
margin-left: 12rpx; |
|||
} |
|||
</style> |
@ -0,0 +1,22 @@ |
|||
<template> |
|||
<view class="wrap"> |
|||
<time-bar /> |
|||
<view class="container p-2"> |
|||
<time-line /> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import TimeBar from './component/TimeBar'; |
|||
import TimeLine from './component/TimeLine'; |
|||
|
|||
export default { |
|||
name: 'Project', |
|||
components: { TimeBar, TimeLine }, |
|||
data() { |
|||
return {}; |
|||
}, |
|||
methods: {}, |
|||
}; |
|||
</script> |
@ -0,0 +1,37 @@ |
|||
<template> |
|||
<view class> |
|||
<!-- :class="{ active: cycleTasks.time.start === filter.startTime }" --> |
|||
<view class="cycle-time active"> |
|||
<!-- {{ $util.formatStartTimeToCycleTime(filter.time, cycleTasks.time.start) }} --> |
|||
2021年30周 |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'TimeBar', |
|||
data() { |
|||
return {}; |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.cycle-time { |
|||
padding: 8rpx 16rpx; |
|||
margin-bottom: 16rpx; |
|||
background: #fafafc; |
|||
color: $uni-text-color; |
|||
font-size: 14px; |
|||
position: sticky; |
|||
top: -1px; |
|||
left: 0; |
|||
z-index: 99; |
|||
|
|||
&.active { |
|||
background: $uni-color-primary; |
|||
color: $uni-text-color-inverse; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,80 @@ |
|||
<template> |
|||
<u-time-line> |
|||
<u-time-line-item nodeTop="2"> |
|||
<!-- 此处自定义了左边内容,用一个图标替代 --> |
|||
<template v-slot:node> |
|||
<view class="u-node state"> |
|||
<!-- 此处为uView的icon组件 --> |
|||
<!-- <u-icon :size="24" color="#fff" name="play-right-fill"></u-icon> --> |
|||
<u-circle-progress :percent="100" active-color="#2979ff" borderWidth="4" width="66"> |
|||
<view class="u-progress-content"> |
|||
<view class="u-progress-dot"></view> |
|||
<text class="u-progress-info"> |
|||
<u-icon name="checkmark" size="30"></u-icon> |
|||
</text> |
|||
</view> |
|||
</u-circle-progress> |
|||
</view> |
|||
</template> |
|||
<template v-slot:content> |
|||
<view> |
|||
<view class="u-order-title">待取件</view> |
|||
<view class="u-order-desc">[自提柜]您的快件已放在楼下侧门,直走前方53.6米。</view> |
|||
<view class="u-order-time">2019-05-08 12:12</view> |
|||
</view> |
|||
</template> |
|||
</u-time-line-item> |
|||
<u-time-line-item> |
|||
<!-- 此处没有自定义左边的内容,会默认显示一个点 --> |
|||
<template v-slot:content> |
|||
<view> |
|||
<view class="u-order-desc">【深圳市】日照香炉生紫烟,遥看瀑布挂前川,飞流直下三千尺,疑是银河落九天。</view> |
|||
<view class="u-order-time">2019-12-06 22:30</view> |
|||
</view> |
|||
</template> |
|||
</u-time-line-item> |
|||
</u-time-line> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'TimeLine', |
|||
data() { |
|||
return {}; |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.u-node { |
|||
width: 44rpx; |
|||
height: 44rpx; |
|||
border-radius: 100rpx; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
background: #d0d0d0; |
|||
} |
|||
|
|||
.state { |
|||
border: 2px solid #999; |
|||
background: #fff; |
|||
} |
|||
|
|||
.u-order-title { |
|||
color: #333333; |
|||
font-weight: bold; |
|||
font-size: 32rpx; |
|||
} |
|||
|
|||
.u-order-desc { |
|||
color: rgb(150, 150, 150); |
|||
font-size: 28rpx; |
|||
margin-bottom: 6rpx; |
|||
} |
|||
|
|||
.u-order-time { |
|||
color: rgb(200, 200, 200); |
|||
font-size: 26rpx; |
|||
} |
|||
</style> |
@ -0,0 +1,20 @@ |
|||
<template> |
|||
<view class="wrap bg-white px-2"> |
|||
<role-list /> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import RoleList from './component/RoleList'; |
|||
|
|||
export default { |
|||
name: 'Roles', |
|||
components: { RoleList }, |
|||
data() { |
|||
return {}; |
|||
}, |
|||
methods: {}, |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped lang="scss"></style> |
@ -0,0 +1,180 @@ |
|||
<template> |
|||
<view class="wrap"> |
|||
<view class="homeBox"> |
|||
<scroll-view :enable-flex="true" :scroll-left="scrollLeft" :throttle="false" scroll-with-animation scroll-x> |
|||
<view class="tabBox"> |
|||
<view :key="index" @click="changeIndex(index)" class="tab-item" v-for="(item, index) in roles"> |
|||
<view :class="setColor(item.mine, tabIndex, index)" class="tab-children u-skeleton-rect">{{ item.name }}</view> |
|||
</view> |
|||
</view> |
|||
<u-skeleton :animation="true" :loading="loading" bgcolor="#fff"></u-skeleton> |
|||
</scroll-view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'RoleList', |
|||
data() { |
|||
return { |
|||
tabIndex: 0, //当前访问的 index 默认为0 |
|||
tabList: [], //tab dom节点集合 |
|||
scrollLeft: 0, //scrollview需要滚动的距离 |
|||
roles: [ |
|||
{ id: 1, name: '项目经理', mine: 0, pm: 1, sequence: 1 }, |
|||
{ id: 2, name: '运维', mine: 0, pm: 0, sequence: 2 }, |
|||
{ id: 3, name: '导师一', mine: 1, pm: 0, sequence: 3 }, |
|||
{ id: 4, name: '导师二', mine: 1, pm: 0, sequence: 4 }, |
|||
{ id: 5, name: '导师三', mine: 1, pm: 0, sequence: 5 }, |
|||
{ id: 6, name: '导师四', mine: 1, pm: 0, sequence: 6 }, |
|||
{ id: 7, name: '导师五', mine: 1, pm: 0, sequence: 7 }, |
|||
{ id: 8, name: '导师六', mine: 1, pm: 0, sequence: 8 }, |
|||
{ id: 9, name: '导师七', mine: 1, pm: 0, sequence: 9 }, |
|||
{ id: 10, name: '导师八', mine: 1, pm: 0, sequence: 10 }, |
|||
], |
|||
loading: true, // 是否显示骨架屏组件 |
|||
}; |
|||
}, |
|||
|
|||
mounted() { |
|||
this.init(); |
|||
setTimeout(() => { |
|||
this.loading = false; |
|||
console.log('this.loading: ', this.loading); |
|||
}, 5000); |
|||
}, |
|||
|
|||
methods: { |
|||
init() { |
|||
const data = document.getElementsByClassName('tab-children'); |
|||
// TODO 第一步 获取当前所以子元素 并插入到 tabList 列表中 |
|||
data.forEach(item => { |
|||
this.tabList.push({ width: item.clientWidth, left: item.offsetLeft }); |
|||
}); |
|||
}, |
|||
|
|||
changeIndex(index) { |
|||
//改变index 即手动点击切换 我在此时将当前元素赋值给左边距 实现自动滚动 |
|||
this.tabIndex = index; |
|||
//当前滚动的位置 |
|||
let left = 0; |
|||
let screenWidth = window.screen.width; |
|||
for (let i = 0; i < index; i++) { |
|||
left += this.tabList[i].width + this.tabList[i].left * 2; |
|||
} |
|||
left += this.tabList[index].width; |
|||
this.scrollLeft = left - screenWidth / 2; |
|||
}, |
|||
|
|||
// 设置文字颜色 |
|||
setColor(mine, tabIndex, index) { |
|||
if (mine === 1 && tabIndex === index) { |
|||
return 'default-tab-choice'; |
|||
} |
|||
if (mine === 1 && tabIndex !== index) { |
|||
return 'default-tab-item'; |
|||
} |
|||
if (mine === 0 && tabIndex === index) { |
|||
return 'tab-choice'; |
|||
} |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
// 这是最外层盒子 |
|||
.wrap { |
|||
position: relative; |
|||
background: #f7f7f7; |
|||
} |
|||
|
|||
.homeBox { |
|||
// 对此盒子进行 sticky 粘性定位 |
|||
position: sticky; |
|||
top: 0; |
|||
background: #fff; //设置背景 否则会透明 |
|||
/* #ifdef H5 */ |
|||
//粘性定位 在h5下 加 原生头部高度 44px |
|||
top: 88rpx; |
|||
|
|||
/* #endif */ |
|||
.tabBox { |
|||
position: relative; |
|||
white-space: nowrap; |
|||
// height: 88rpx; |
|||
|
|||
/* #ifdef MP-TOUTIAO */ |
|||
/* #endif */ |
|||
.tab-item { |
|||
padding: 20rpx 24rpx; |
|||
position: relative; |
|||
display: inline-block; |
|||
text-align: center; |
|||
font-size: 30rpx; |
|||
transition-property: background-color, width; |
|||
} |
|||
|
|||
.default-tab-item { |
|||
color: $roleChoiceColor; |
|||
} |
|||
|
|||
.default-tab-choice { |
|||
//当前选中 基于此类名给与底部选中框 |
|||
position: relative; |
|||
color: $roleChoiceColor; |
|||
font-weight: 600; |
|||
} |
|||
.default-tab-choice:before { |
|||
content: ''; |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: -20rpx; |
|||
width: 100%; |
|||
height: 6rpx; |
|||
border-radius: 2rpx; |
|||
background: $roleChoiceColor; |
|||
} |
|||
|
|||
.tab-choice { |
|||
//当前选中 基于此类名给与底部选中框 |
|||
position: relative; |
|||
color: $uni-color-primary; |
|||
font-weight: 600; |
|||
} |
|||
|
|||
.tab-choice:before { |
|||
content: ''; |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: -20rpx; |
|||
width: 100%; |
|||
height: 6rpx; |
|||
border-radius: 2rpx; |
|||
background: $uni-color-primary; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// // 删除 底部滚动条 |
|||
/* #ifndef APP-NVUE */ |
|||
::-webkit-scrollbar, |
|||
::-webkit-scrollbar, |
|||
::-webkit-scrollbar { |
|||
display: none; |
|||
width: 0 !important; |
|||
height: 0 !important; |
|||
-webkit-appearance: none; |
|||
background: transparent; |
|||
} |
|||
|
|||
/* #endif */ |
|||
/* #ifdef H5 */ |
|||
// 通过样式穿透,隐藏H5下,scroll-view下的滚动条 |
|||
scroll-view ::v-deep ::-webkit-scrollbar { |
|||
display: none; |
|||
} |
|||
|
|||
/* #endif */ |
|||
</style> |
@ -0,0 +1,183 @@ |
|||
<template> |
|||
<view class="wrap"> |
|||
<view class="homeBox"> |
|||
<scroll-view :enable-flex="true" :scroll-left="scrollLeft" :throttle="false" scroll-with-animation scroll-x> |
|||
<view class="tabBox u-skeleton"> |
|||
<view :key="index" @click="changeIndex(index)" class="tab-item" v-for="(item, index) in roles"> |
|||
<view :class="setColor(item.isMine, tabIndex, index)" class="tab-children u-skeleton-rect">{{ item.value }}</view> |
|||
</view> |
|||
</view> |
|||
<u-skeleton :animation="true" :loading="loading" bgcolor="#fff"></u-skeleton> |
|||
</scroll-view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'RoleList', |
|||
data() { |
|||
return { |
|||
tabIndex: 0, //当前访问的 index 默认为0 |
|||
tabList: [], //tab dom节点集合 |
|||
scrollLeft: 0, //scrollview需要滚动的距离 |
|||
roles: [ |
|||
{ id: 1, value: '项目经理', isMine: 0 }, |
|||
{ id: 2, value: '运维', isMine: 0 }, |
|||
{ id: 3, value: '导师一', isMine: 1 }, |
|||
{ id: 4, value: '导师二', isMine: 1 }, |
|||
{ id: 5, value: '导师三', isMine: 1 }, |
|||
{ id: 6, value: '导师四', isMine: 1 }, |
|||
{ id: 7, value: '导师五', isMine: 1 }, |
|||
{ id: 8, value: '导师六', isMine: 1 }, |
|||
{ id: 9, value: '导师七', isMine: 1 }, |
|||
{ id: 10, value: '导师八', isMine: 1 }, |
|||
], |
|||
loading: true, // 是否显示骨架屏组件 |
|||
}; |
|||
}, |
|||
|
|||
mounted() { |
|||
this.init(); |
|||
setTimeout(() => { |
|||
this.loading = false; |
|||
console.log('this.loading: ', this.loading); |
|||
}, 5000); |
|||
}, |
|||
|
|||
methods: { |
|||
init() { |
|||
const data = document.getElementsByClassName('tab-children'); |
|||
// TODO 第一步 获取当前所以子元素 并插入到 tabList 列表中 |
|||
data.forEach(item => { |
|||
this.tabList.push({ width: item.clientWidth, left: item.offsetLeft }); |
|||
}); |
|||
}, |
|||
|
|||
changeIndex(index) { |
|||
//改变index 即手动点击切换 我在此时将当前元素赋值给左边距 实现自动滚动 |
|||
this.tabIndex = index; |
|||
//当前滚动的位置 |
|||
let left = 0; |
|||
let screenWidth = window.screen.width; |
|||
for (let i = 0; i < index; i++) { |
|||
left += this.tabList[i].width + this.tabList[i].left * 2; |
|||
} |
|||
left += this.tabList[index].width; |
|||
this.scrollLeft = left - screenWidth / 2; |
|||
}, |
|||
|
|||
// 设置文字颜色 |
|||
setColor(isMine, tabIndex, index) { |
|||
if (isMine === 1 && tabIndex === index) { |
|||
return 'default-tab-choice'; |
|||
} |
|||
if (isMine === 1 && tabIndex !== index) { |
|||
return 'default-tab-item'; |
|||
} |
|||
if (isMine === 0 && tabIndex === index) { |
|||
return 'tab-choice'; |
|||
} |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
$tabChoiceColor: #f40; //设置选中文字和底部下划线背景颜色 |
|||
$max: 100%; |
|||
|
|||
// 这是最外层盒子 |
|||
.wrap { |
|||
position: relative; |
|||
background: #f7f7f7; |
|||
} |
|||
|
|||
.homeBox { |
|||
// 对此盒子进行 sticky 粘性定位 |
|||
position: sticky; |
|||
top: 0; |
|||
background: #fff; //设置背景 否则会透明 |
|||
/* #ifdef H5 */ |
|||
//粘性定位 在h5下 加 原生头部高度 44px |
|||
top: 88rpx; |
|||
|
|||
/* #endif */ |
|||
.tabBox { |
|||
position: relative; |
|||
white-space: nowrap; |
|||
// height: 88rpx; |
|||
|
|||
/* #ifdef MP-TOUTIAO */ |
|||
/* #endif */ |
|||
.tab-item { |
|||
padding: 15rpx 24rpx; |
|||
position: relative; |
|||
display: inline-block; |
|||
text-align: center; |
|||
font-size: 30rpx; |
|||
transition-property: background-color, width; |
|||
} |
|||
|
|||
.default-tab-item { |
|||
color: $tabChoiceColor; |
|||
} |
|||
|
|||
.default-tab-choice { |
|||
//当前选中 基于此类名给与底部选中框 |
|||
position: relative; |
|||
color: $tabChoiceColor; |
|||
font-weight: 600; |
|||
} |
|||
.default-tab-choice:before { |
|||
content: ''; |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: -14rpx; |
|||
width: 100%; |
|||
height: 6rpx; |
|||
border-radius: 2rpx; |
|||
background: $tabChoiceColor; |
|||
} |
|||
|
|||
.tab-choice { |
|||
//当前选中 基于此类名给与底部选中框 |
|||
position: relative; |
|||
color: $uni-color-primary; |
|||
font-weight: 600; |
|||
} |
|||
|
|||
.tab-choice:before { |
|||
content: ''; |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: -14rpx; |
|||
width: 100%; |
|||
height: 6rpx; |
|||
border-radius: 2rpx; |
|||
background: $uni-color-primary; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// // 删除 底部滚动条 |
|||
/* #ifndef APP-NVUE */ |
|||
::-webkit-scrollbar, |
|||
::-webkit-scrollbar, |
|||
::-webkit-scrollbar { |
|||
display: none; |
|||
width: 0 !important; |
|||
height: 0 !important; |
|||
-webkit-appearance: none; |
|||
background: transparent; |
|||
} |
|||
|
|||
/* #endif */ |
|||
/* #ifdef H5 */ |
|||
// 通过样式穿透,隐藏H5下,scroll-view下的滚动条 |
|||
scroll-view ::v-deep ::-webkit-scrollbar { |
|||
display: none; |
|||
} |
|||
|
|||
/* #endif */ |
|||
</style> |
@ -0,0 +1,56 @@ |
|||
<!-- |
|||
* @Author: aBin |
|||
* @email: binbin0314@126.com |
|||
* @Date: 2021-07-19 14:15:35 |
|||
* @LastEditors: aBin |
|||
* @LastEditTime: 2021-07-20 14:22:11 |
|||
--> |
|||
<template> |
|||
<!-- <Barrier /> --> |
|||
<scroll-view |
|||
:lower-threshold="300" |
|||
:scrollTop="top" |
|||
:scrollY="true" |
|||
:upper-threshold="300" |
|||
@scroll="scroll" |
|||
@scrolltolower="handleScrollBottom" |
|||
@scrolltoupper="handleScrollTop" |
|||
> |
|||
<TimeBox ref="child" /> |
|||
</scroll-view> |
|||
</template> |
|||
|
|||
<script> |
|||
// import Barrier from './component/Barrier.vue'; |
|||
import { mapState, mapMutations } from 'vuex'; |
|||
import TimeBox from './component/TimeBox.vue'; |
|||
export default { |
|||
name: 'TimeLine', |
|||
components: { TimeBox }, |
|||
data() { |
|||
return { top: 0 }; |
|||
}, |
|||
computed: mapState('home', ['scrollTop', 'showTips']), |
|||
methods: { |
|||
...mapMutations('home', ['setScrollTop', 'setShrink']), |
|||
// 滚动 |
|||
scroll(e) { |
|||
this.top = e.detail.scrollTop; |
|||
this.setShrink(this.top > this.scrollTop); |
|||
this.setScrollTop(this.top); |
|||
}, |
|||
|
|||
// 滚动到顶部 |
|||
handleScrollTop() { |
|||
console.log('滚动到顶部'); |
|||
this.$refs.child.addTopList(); |
|||
}, |
|||
|
|||
// 滚动到底部 |
|||
handleScrollBottom() { |
|||
console.log('滚动到底部'); |
|||
this.$refs.child.addBottomList(); |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
@ -0,0 +1,42 @@ |
|||
<!-- |
|||
* @Author: aBin |
|||
* @email: binbin0314@126.com |
|||
* @Date: 2021-07-19 14:22:54 |
|||
* @LastEditors: aBin |
|||
* @LastEditTime: 2021-07-20 11:46:04 |
|||
--> |
|||
<template> |
|||
<view class> |
|||
<!-- :class="{ active: cycleTasks.time.start === filter.startTime }" --> |
|||
<view class="cycle-time active"> |
|||
<!-- {{ $util.formatStartTimeToCycleTime(filter.time, cycleTasks.time.start) }} --> |
|||
2021年30周 |
|||
</view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: 'Barrier', |
|||
data() { |
|||
return {}; |
|||
}, |
|||
}; |
|||
</script> |
|||
<style scoped lang="scss"> |
|||
.cycle-time { |
|||
padding: 8rpx 16rpx; |
|||
margin-bottom: 16rpx; |
|||
background: #fafafc; |
|||
color: $uni-text-color; |
|||
font-size: 28rpx; |
|||
position: sticky; |
|||
top: -1px; |
|||
left: 0; |
|||
z-index: 99; |
|||
|
|||
&.active { |
|||
background: $uni-color-primary; |
|||
color: $uni-text-color-inverse; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,69 @@ |
|||
<!-- |
|||
* @Author: aBin |
|||
* @email: binbin0314@126.com |
|||
* @Date: 2021-07-19 15:36:28 |
|||
* @LastEditors: aBin |
|||
* @LastEditTime: 2021-07-19 18:54:55 |
|||
--> |
|||
<template> |
|||
<view class="px-3 pb-10"> |
|||
<view :key="index" v-for="(item, index) in list"> |
|||
<view class="flex items-center"> |
|||
<TimeStatus :status="item" :content="JSON.stringify(item)" /> |
|||
<view class="flex-1 ml-2 flex justify-between"> |
|||
<view>任务时间栏</view> |
|||
<view> |
|||
<view class="flex justify-between" style="min-width: 180rpx"> |
|||
<u-icon custom-prefix="custom-icon" name="C-bxl-redux" size="34"></u-icon> |
|||
<u-icon custom-prefix="custom-icon" name="attachment" size="42"></u-icon> |
|||
<u-icon custom-prefix="custom-icon" name="moneycollect" size="40"></u-icon> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="border-l-2 border-gray-300 ml-3.5 my-2"> |
|||
<view class="ml-4 shadow-lg task-box overflow-hidden"> |
|||
<u-card :show-foot="false" :show-head="false" class="h-16" margin="0"> |
|||
<view slot="body"> |
|||
<view class="u-col-between p-0 u-skeleton"> |
|||
<view class="u-skeleton-rect">瓶身描绘的牡丹一如你初妆</view> |
|||
</view> |
|||
</view> |
|||
</u-card> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<Tips /> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import TimeStatus from './TimeStatus.vue'; |
|||
export default { |
|||
name: 'TimeBox', |
|||
|
|||
components: { TimeStatus }, |
|||
|
|||
data() { |
|||
return { list: [0, 1, 2, 0, 1, 2] }; |
|||
}, |
|||
|
|||
methods: { |
|||
addTopList() { |
|||
this.list.unshift(0, 0, 0); |
|||
console.log('this.list: ', this.list); |
|||
}, |
|||
|
|||
addBottomList() { |
|||
this.list.push(1, 1, 1); |
|||
console.log('this.list: ', this.list); |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.task-box { |
|||
border-radius: 24rpx; |
|||
} |
|||
</style> |
@ -0,0 +1,130 @@ |
|||
<!-- |
|||
* @Author: aBin |
|||
* @email: binbin0314@126.com |
|||
* @Date: 2021-07-19 15:47:38 |
|||
* @LastEditors: aBin |
|||
* @LastEditTime: 2021-07-19 19:39:36 |
|||
--> |
|||
<template> |
|||
<view> |
|||
<view class="rounded-full h-7 w-7 flex items-center justify-center text-blue-400" v-if="status === 0" @tap="changeStatus($event, 0)"> |
|||
<u-circle-progress :percent="100" active-color="#2979ff" bgColor="rgba(255,255,255,0)" borderWidth="4" width="66"> |
|||
<view class="u-progress-content"> |
|||
<view class="u-progress-dot"></view> |
|||
<text class="u-progress-info"> |
|||
<u-icon name="checkmark" size="30"></u-icon> |
|||
</text> |
|||
</view> |
|||
</u-circle-progress> |
|||
</view> |
|||
<view class="rounded-full h-7 w-7 flex items-center justify-center text-black" v-if="status === 1" @tap="changeStatus($event, 1)"> |
|||
<u-circle-progress :percent="80" active-color="#2979ff" bgColor="rgba(255,255,255,0)" borderWidth="6" width="66"> |
|||
<view class="u-progress-content"> |
|||
<view class="u-progress-dot"></view> |
|||
<view class="u-progress-info">{{ time }}</view> |
|||
</view> |
|||
</u-circle-progress> |
|||
</view> |
|||
<view class="rounded-full h-7 w-7 flex items-center justify-center text-gray-400" v-if="status === 2" @tap="changeStatus($event, 2)"> |
|||
<u-circle-progress :percent="40" active-color="#2979ff" bgColor="rgba(255,255,255,0)" borderWidth="6" width="66"> |
|||
<view class="u-progress-content"> |
|||
<view class="u-progress-dot"></view> |
|||
<text class="u-progress-info"> |
|||
<u-icon name="play-right-fill" size="30"></u-icon> |
|||
</text> |
|||
</view> |
|||
</u-circle-progress> |
|||
</view> |
|||
<view |
|||
class="rounded-full h-7 w-7 flex items-center justify-center text-red-800 font-black" |
|||
v-if="status === 3" |
|||
@tap="changeStatus($event, 3)" |
|||
> |
|||
<u-circle-progress :percent="80" active-color="#2979ff" bgColor="rgba(255,255,255,0)" borderWidth="6" width="66"> |
|||
<view class="u-progress-content"> |
|||
<view class="u-progress-dot"></view> |
|||
<text class="u-progress-info"> |
|||
<u-icon name="pause" size="30"></u-icon> |
|||
</text> |
|||
</view> |
|||
</u-circle-progress> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import { mapMutations } from 'vuex'; |
|||
export default { |
|||
name: 'TimeStatus', |
|||
props: { |
|||
status: { |
|||
default: 0, |
|||
type: Number, |
|||
}, |
|||
content: { |
|||
default: '', |
|||
type: String, |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
time: 20, |
|||
start: [ |
|||
{ |
|||
text: '确认开始任务', |
|||
color: 'blue', |
|||
}, |
|||
], |
|||
pause: [ |
|||
{ text: '继续' }, |
|||
{ |
|||
text: '重新开始任务', |
|||
color: 'blue', |
|||
}, |
|||
{ text: '结束' }, |
|||
], |
|||
proceed: [ |
|||
{ text: '暂停' }, |
|||
{ |
|||
text: '重新开始任务', |
|||
color: 'blue', |
|||
}, |
|||
{ text: '结束' }, |
|||
], |
|||
again: [ |
|||
{ |
|||
text: '重新开始任务', |
|||
color: 'blue', |
|||
}, |
|||
], |
|||
}; |
|||
}, |
|||
methods: { |
|||
...mapMutations('home', ['setClient', 'setTips', 'setStatus', 'setTipsContent']), |
|||
chooseList() { |
|||
return this.start; |
|||
}, |
|||
changeStatus(e, num) { |
|||
this.setStatus(num); |
|||
this.setTipsContent(this.chooseTips(num, this.content)); |
|||
const client = { |
|||
left: e.target.x, |
|||
top: e.target.y, |
|||
}; |
|||
this.setClient(client); |
|||
this.setTips(true); |
|||
}, |
|||
chooseTips(num, content) { |
|||
switch (num) { |
|||
case 0: |
|||
return `确认开始任务${content}吗?`; |
|||
case 1: |
|||
return `请选择要执行的操作`; |
|||
case 2: |
|||
return `请选择要执行的操作`; |
|||
case 3: |
|||
return `是否要重新开始此任务`; |
|||
} |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
@ -0,0 +1,7 @@ |
|||
<!-- |
|||
* @Author: aBin |
|||
* @email: binbin0314@126.com |
|||
* @Date: 2021-07-19 15:40:02 |
|||
* @LastEditors: aBin |
|||
* @LastEditTime: 2021-07-19 15:40:03 |
|||
--> |
@ -0,0 +1,73 @@ |
|||
<template> |
|||
<view |
|||
class="fixed shadow-2xl shadow-2xl" |
|||
style="z-index: 1000" |
|||
:style="{ |
|||
left: client.left + 'px', |
|||
top: height - client.top > 110 ? client.top + 'px' : '', |
|||
bottom: height - client.top > 110 ? '' : '10px', |
|||
}" |
|||
id="u-icard" |
|||
> |
|||
<u-card |
|||
:title="title" |
|||
style="width: 500rpx; margin: 0 !important" |
|||
v-if="showTips" |
|||
titleSize="28" |
|||
:headStyle="headStyle" |
|||
:footStyle="footStyle" |
|||
> |
|||
<view class="" slot="body"> {{ tipsContent }} </view> |
|||
<view class="flex ustify-between" slot="foot"> |
|||
<u-button size="mini" @tap="clickCancel">取消</u-button> |
|||
<u-button v-if="status === 1" size="mini" @tap="clickCancel">暂停</u-button> |
|||
<u-button v-if="status === 2" size="mini" @tap="clickCancel">继续</u-button> |
|||
<u-button v-if="status === 1 || status === 2" size="mini" @tap="clickCancel">重新开始</u-button> |
|||
<u-button v-if="status === 1 || status === 2" type="primary" size="mini" @tap="clickCancel">结束</u-button> |
|||
<u-button v-if="status === 0 || status === 3" type="primary" size="mini" @tap="clickOk">确定</u-button> |
|||
</view> |
|||
</u-card> |
|||
<u-toast ref="uToast" /> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapState, mapMutations } from 'vuex'; |
|||
export default { |
|||
name: 'Tips', |
|||
props: { |
|||
title: { |
|||
default: '提示', |
|||
type: String, |
|||
}, |
|||
}, |
|||
computed: mapState('home', ['client', 'showTips', 'status', 'tipsContent']), |
|||
data() { |
|||
return { |
|||
footStyle: { padding: '4px 15px' }, |
|||
headStyle: { paddingTop: '8px', paddingBottom: '8px' }, |
|||
height: 0, |
|||
}; |
|||
}, |
|||
mounted() { |
|||
this.height = window.screen.height; |
|||
}, |
|||
methods: { |
|||
...mapMutations('home', ['setTips']), |
|||
clickOk() { |
|||
this.$refs.uToast.show({ |
|||
title: '点击了确定', |
|||
type: 'success', |
|||
}); |
|||
this.setTips(false); |
|||
}, |
|||
clickCancel() { |
|||
this.$refs.uToast.show({ |
|||
title: '点击了取消', |
|||
type: 'error', |
|||
}); |
|||
this.setTips(false); |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
@ -0,0 +1,43 @@ |
|||
<template> |
|||
<view> |
|||
<u-navbar back-text="返回"> |
|||
<view class="flex justify-center flex-1"> |
|||
<view v-if="Istrue">{{ title }}</view> |
|||
<view v-else>{{ titleBar }}</view> |
|||
</view> |
|||
<view class="mr-2" slot="right"> |
|||
<u-icon class="m-1" name="checkmark-circle"></u-icon> |
|||
<u-icon class="m-1" name="reload"></u-icon> |
|||
<u-icon class="m-1" name="home"></u-icon> |
|||
<u-icon class="m-1" name="more-dot-fill"></u-icon> |
|||
</view> |
|||
</u-navbar> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: 'Title', |
|||
data() { |
|||
return { |
|||
title: '加载中...', |
|||
titleBar: '项目名称', |
|||
Istrue: true, |
|||
}; |
|||
}, |
|||
mounted() { |
|||
this.getTitle(); |
|||
}, |
|||
methods: { |
|||
getTitle() { |
|||
this.Istrue = !this.Istrue; |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.slot-warp { |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
} |
|||
</style> |
@ -1,43 +1,48 @@ |
|||
{ |
|||
"pages": [ |
|||
{ |
|||
"path": "pages/index/index", |
|||
"style": { |
|||
"navigationBarTitleText": "uni-app" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/plugin-test/plugin-test", |
|||
"style": { |
|||
"navigationBarTitleText": "iframe-测试" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/rich-text/rich-text", |
|||
"style": { |
|||
"navigationBarTitleText": "rich-text 测试" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/pinch/pinch", |
|||
"style": { |
|||
"navigationBarTitleText": "pinch 测试" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/test/test", |
|||
"style": { |
|||
"navigationBarTitleText": "test" |
|||
} |
|||
} |
|||
], |
|||
"globalStyle": { |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarTitleText": "uni-app", |
|||
"navigationBarBackgroundColor": "#F8F8F8", |
|||
"backgroundColor": "#F8F8F8" |
|||
}, |
|||
"easycom": { |
|||
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue" |
|||
} |
|||
} |
|||
{ |
|||
"pages": [ |
|||
{ |
|||
"path": "pages/index/index", |
|||
"style": { |
|||
"navigationStyle": "custom" , |
|||
"navigationBarTextStyle": "white" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/plugin-test/plugin-test", |
|||
"style": { |
|||
"navigationBarTitleText": "iframe-测试" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/rich-text/rich-text", |
|||
"style": { |
|||
"navigationBarTitleText": "rich-text 测试" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/pinch/pinch", |
|||
"style": { |
|||
"navigationBarTitleText": "pinch 测试" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "components/Title/Title", |
|||
"style": { |
|||
"navigationStyle": "custom" , |
|||
"navigationBarTextStyle": "white" |
|||
} |
|||
} |
|||
], |
|||
"globalStyle": { |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarTitleText": "uni-app", |
|||
"navigationBarBackgroundColor": "#F8F8F8", |
|||
"backgroundColor": "#F8F8F8" |
|||
}, |
|||
"easycom": { |
|||
"autoscan": true, |
|||
"custom": { |
|||
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue" |
|||
} |
|||
} |
|||
} |
|||
|
@ -0,0 +1,3 @@ |
|||
const actions = {}; |
|||
|
|||
export default actions; |
@ -0,0 +1,3 @@ |
|||
const getters = {}; |
|||
|
|||
export default getters; |
@ -0,0 +1,12 @@ |
|||
import state from './state'; |
|||
import getters from './getters'; |
|||
import mutations from './mutations'; |
|||
import actions from './actions'; |
|||
|
|||
export default { |
|||
namespaced: true, |
|||
state, |
|||
getters, |
|||
mutations, |
|||
actions, |
|||
}; |
@ -0,0 +1,52 @@ |
|||
const mutations = { |
|||
/** |
|||
* 记录时间轴向上滚动的距离 |
|||
* @param { object } state |
|||
* @param { number } num |
|||
*/ |
|||
setScrollTop(state, num) { |
|||
state.scrollTop = num; |
|||
}, |
|||
/** |
|||
* 设置日常任务当前是否应该处于收缩状态 |
|||
* @param { object } state |
|||
* @param { boolean } data |
|||
*/ |
|||
setShrink(state, data) { |
|||
state.isShrink = data; |
|||
}, |
|||
/** |
|||
* 存储鼠标点击位置 |
|||
* @param { object } state |
|||
* @param { object } data |
|||
*/ |
|||
setClient(state, data) { |
|||
state.client = { ...data }; |
|||
}, |
|||
/** |
|||
* 是否显示tips |
|||
* @param { object } state |
|||
* @param { boolean } data |
|||
*/ |
|||
setTips(state, data) { |
|||
state.showTips = data; |
|||
}, |
|||
/** |
|||
* 是否显示tips |
|||
* @param { object } state |
|||
* @param { number } data |
|||
*/ |
|||
setStatus(state, data) { |
|||
state.status = data; |
|||
}, |
|||
/** |
|||
* 是否显示tips |
|||
* @param { object } state |
|||
* @param { string } data |
|||
*/ |
|||
setTipsContent(state, data) { |
|||
state.tipsContent = data; |
|||
}, |
|||
}; |
|||
|
|||
export default mutations; |
@ -0,0 +1,13 @@ |
|||
const state = { |
|||
scrollTop: 0, |
|||
isShrink: false, // true: 收起, false:展开
|
|||
client: { |
|||
left: 0, // 鼠标点击位置距离左边的距离
|
|||
top: 0, // 鼠标点击位置距离上边的距离
|
|||
}, |
|||
showTips: false, |
|||
status: 0, // 点击了时间轴上的哪种样式,默认点击了开始
|
|||
tipsContent: '', // 提示框内的内容,需要传入
|
|||
}; |
|||
|
|||
export default state; |
@ -0,0 +1,8 @@ |
|||
import Vue from 'vue'; |
|||
import Vuex from 'vuex'; |
|||
import home from './home/index'; |
|||
import db from './db/index'; |
|||
import user from './user/index'; |
|||
|
|||
Vue.use(Vuex); |
|||
export default new Vuex.Store({ modules: { home, db, user } }); |
Loading…
Reference in new issue