You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

311 lines
9.4 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="tm-timeline">
<block v-if="model=='center'">
<block v-for="(item,index) in listData" :key="index">
<view v-if="(index+1)%2" class="tm-timeline-item " >
<view :style="{
width: bwi(item)+'px',
height: bwi(item)+'px'
}" :class="[item['icon']?'pa-4':'',item.color?item.color:color_tmeme,`shadow-${item.color?item.color:color_tmeme}-4`,black_tmeme?'bk':'']" class=" flex-center rounded tm-timeline-jidian border-white-a-2">
<tm-icons style="line-height: 0;" dense v-if="item.icon" color="white" :size="item.iconSize||24" :name="item.icon"></tm-icons>
</view>
<view class=" tm-timeline-item-content relative">
<view :class="[`text-${(item.color?item.color:color_tmeme)}`]" v-if="item.time" class="tm-timeline-item-right pr-36 text-weight-b text-size-n text-align-right">
{{item.time}}
</view>
<!-- <tm-divider :vertical="true" :width="4" :height="100"></tm-divider> -->
<view :class="[`border-${item.borderColor?item.borderColor:borderColor}-l-1`,black_tmeme?'bk':'']" class="tm-timeline-item-right pl-36 ">
<view v-if="item.title" class="mb-12 text-align-left">
<text class="text-weight-b text-size-n" :class="[`text-${(item.color?item.color:color_tmeme)}`]">{{item.title}}</text>
</view>
<view class="text-align-left pb-24">
<text class="text-size-s text-grey-darken-1">
{{item.content}}
</text>
</view>
</view>
</view>
</view>
<view v-if="(index+1)%2==0" class="tm-timeline-item ">
<view :style="{
width: bwi(item)+'px',
height: bwi(item)+'px'
}" :class="[item['icon']?'pa-4':'',item.color?item.color:color_tmeme,`shadow-${item.color?item.color:color_tmeme}-4`,black_tmeme?'bk':'']" class="flex-center rounded tm-timeline-jidian border-white-a-2">
<tm-icons style="line-height: 0;" dense v-if="item.icon" color="white" :size="item.iconSize||24" :name="item.icon"></tm-icons>
</view>
<view class=" tm-timeline-item-content relative">
<view :class="[index!==listData.length-1?(`border-${item.borderColor?item.borderColor:borderColor}-r-1`):'',black_tmeme?'bk':'']" class="tm-timeline-item-left pr-36 ">
<view v-if="item.title" class="mb-12 text-align-right">
<text class="text-weight-b text-size-n" :class="[`text-${(item.color?item.color:color_tmeme)}`]">{{item.title}}</text>
</view>
<view class="text-align-right pb-24">
<text class="text-size-s text-grey-darken-1">
{{item.content}}
</text>
</view>
</view>
<view v-if="item.time" :class="[`text-${(item.color?item.color:color_tmeme)}`]" class="tm-timeline-item-right pl-36 text-weight-b text-size-n ">
{{item.time}}
</view>
</view>
</view>
</block>
</block>
<block v-if="model=='left'">
<block v-for="(item,index) in listData" :key="index">
<view class="tm-timeline-item tm-timeline-item--leftDir">
<view style="width: 160upx;">
<view :style="{
width: bwi(item)+'px',
height: bwi(item)+'px'
}" :class="[item['icon']?'pa-4':'',item.color?item.color:color_tmeme,`shadow-${item.color?item.color:color_tmeme}-4`,black_tmeme?'bk':'']" class="flex-center rounded tm-timeline-jidian border-white-a-2">
<tm-icons style="line-height: 0;" dense v-if="item.icon" color="white" :size="item.iconSize||24" :name="item.icon"></tm-icons>
</view>
<view :style="{
marginTop:'-'+botop(item)+'px'
}" :class="[index!==listData.length-1?'tm-timeline-item-boder':'',`${item.borderColor?item.borderColor:borderColor}`,black_tmeme?'bk':'']"></view>
</view>
<view class=" tm-timeline-item-content relative">
<view class="tm-timeline-item-left ">
<slot name="content" :data="item">
<view v-if="item.time" :class="['text-'+(item.color?item.color:color_tmeme)]" class="mb-0 tm-timeline-item-right text-size-s ">
{{item.time}}
</view>
<view v-if="item.title" class="mb-12 text-align-left">
<text :class="['text-'+(item.color?item.color:color_tmeme)]" class="text-weight-b text-size-n ">{{item.title}}</text>
</view>
<view class="text-align-left pb-24 mb-32">
<text class="text-size-s text-grey-darken-1">
{{item.content}}
</text>
</view>
</slot>
</view>
</view>
</view>
</block>
</block>
<block v-if="model=='right'">
<block v-for="(item,index) in listData" :key="index">
<view class="tm-timeline-item tm-timeline-item--leftDir endright">
<view class=" tm-timeline-item-content relative">
<view class="tm-timeline-item-left ">
<view v-if="item.time" :class="[`text-${(item.color?item.color:color_tmeme)}`]" class="mb-0 tm-timeline-item-right text-size-s text-align-right">
{{item.time}}
</view>
<view v-if="item.title" class="mb-12 text-align-right">
<text :class="[`text-${(item.color?item.color:color_tmeme)}`]" class="text-weight-b text-size-n ">{{item.title}}</text>
</view>
<view class="text-align-right pb-24 mb-32">
<text class="text-size-s text-grey-darken-1">
{{item.content}}
</text>
</view>
</view>
</view>
<view style="width: 140upx;">
<view :style="{
width: bwi(item)+'px',
height: bwi(item)+'px'
}" :class="[item['icon']?'pa-4':'',item.color?item.color:color_tmeme,`shadow-${item.color?item.color:color_tmeme}-4`,black_tmeme?'bk':'']" class="flex-center rounded tm-timeline-jidian border-white-a-2">
<tm-icons style="line-height: 0;" dense v-if="item.icon" color="white" :size="item.iconSize||24" :name="item.icon"></tm-icons>
</view>
<view :style="{
marginTop:'-'+botop(item)+'px'
}" :class="[index!==listData.length-1?'tm-timeline-item-boder':'',`${item.borderColor?item.borderColor:borderColor}`,black_tmeme?'bk':'']"></view>
</view>
</view>
</block>
</block>
</view>
</template>
<script>
/**
* timeline 时间轴
* @property {Boolean} reverse = [] 默认false ,是否反转数据。
* @property {String} border-color = [] 默认grey-lighten-2 ,默认线的颜色。
* @property {String} color = [] 默认primary ,认主题和节点颜色如果。
* @property {Number} size = [] 默认32 ,默认的节点大小单位upx
* @property {String} model = [left|center|right] 默认center ,时间轴的方向。
* @property {Array} list = [] 默认:[] ,数据。{
title:'',
content:'我是内容我是内容我是内容',
time:"2020年7月",
color:"blue",
icon:'icon-position-fill',
iconSize:36,
borderColor:'blue'
},
*/
import tmIcons from "@/tm-vuetify/components/tm-icons/tm-icons.vue"
export default {
components:{tmIcons},
name: 'tm-timeline',
props:{
list:{
type:Array,
default:()=>{
return [];
}
},
// 是否反转内容
reverse:{
type:Boolean,
default:false
},
// 默认线的颜色,
borderColor:{
type:String,
default:'grey-lighten-2'
},
// 默认主题和节点颜色如果
color:{
type:String,
default:'primary'
},
size:{
type:Number,
default:36
},
black:{
type:Boolean|String,
default:null
},
model:{
type:String,
default:'center' // left|center|right
},
// 跟随主题色的改变而改变。
fllowTheme:{
type:Boolean|String,
default:true
}
},
data() {
return {
listData:[],
};
},
watch:{
list:{
deep:true,
handler(){
this.jsList = this.list;
}
}
},
computed:{
black_tmeme: function() {
if (this.black !== null) return this.black;
return this.$tm.vx.state().tmVuetify.black;
},
color_tmeme:function(){
if(this.$tm.vx.state().tmVuetify.color!==null&&this.$tm.vx.state().tmVuetify.color && this.fllowTheme){
return this.$tm.vx.state().tmVuetify.color;
}
return this.color;
},
jsList:{
get:function(){
return this.listData;
},
set:function(val){
if(this.reverse){
this.listData = this.list.reverse();
}else{
this.listData = this.list;
}
}
}
},
mounted() {
this.jsList = this.list;
},
methods: {
botop(d){
return uni.upx2px(d.size+8||32)
},
bwi(item){
if(!item||!item['size']){
return uni.upx2px(this.size||24)
}else if(item['size']){
return uni.upx2px(item['size']||24)
}
return uni.upx2px(24)
}
}
};
</script>
<style lang="less" scoped>
.tm-timeline {
.tm-timeline-item {
.tm-timeline-item-left,
.tm-timeline-item-right {
width: 200upx;
flex-shrink: 0;
// transform: translateY(-34upx);
}
.tm-timeline-item-content{
display: flex;
justify-content: center;
align-items: flex-start;
align-content: flex-start;
}
.tm-timeline-jidian {
margin: auto;
}
&.tm-timeline-item--leftDir{
display: flex;
flex-flow: row;
&.endright{
justify-content: flex-end;
}
.tm-timeline-item-left,
.tm-timeline-item-right {
width:auto;
max-width: 400upx;
}
.tm-timeline-item-boder{
height: 100%;
width: 1px;margin: auto;
}
.tm-timeline-jidian {
position: relative;
margin: auto;
z-index: 2;
}
.tm-timeline-item-content{
display: flex;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
}
}
}
}
</style>