@minix-iot/ui
Version:
基于Vue的移动端轻量级UI组件库
236 lines (229 loc) • 7.1 kB
JSX
import { Namespace } from "../../utils/namespace"
import Icon from '../icon/icon.jsx'
const namespace = Namespace.Create('nav-bar')
export default {
name: namespace.name,
components:{
Icon
},
data() {
return{
offsetWidth: -1,
}
},
props:{
title:{
type: String | Array,
required: true
},
subtitle:{
type: String
},
leftText:{
type:String
},
leftArrow:{
type: Boolean,
default: true
},
rightText:{
type: String
},
more:{
type: Boolean,
default: true
},
fixed:{
type: Boolean,
default: false
},
zIndex:{
type: Number | String,
default: 1030
},
border:{
type: Boolean,
default: false
},
background:{
type: String
},
iconColor:{
type: String
},
titleColor:{
type: String
},
subtitleColor:{
type: String
},
safeAreaInsetTop:{
type: Boolean,
default:false
},
returnIcon:{
type: String,
default: 'icon_backleft'
}
},
computed:{
cls(){
return namespace.derive({
fixed: this.fixed,
'safe-area-inset-top': this.safeAreaInsetTop,
'border-bottom': this.border
})
},
style(){
const style ={}
if(this.fixed){
style.zIndex = this.zIndex
}
if(this.background){
style.background = this.background
}
return style
},
contentCls(){
return namespace.derive('content')
},
leftCls(){
return namespace.derive('left')
},
titleContainerCls(){
return namespace.derive('title-container')
},
titleCls(){
return namespace.derive('title',{
small: this.subtitle || this.$slots.subtitle
})
},
titleItemContainerCls(){
return namespace.derive('title-item-container')
},
titleItemCls(){
return namespace.derive('title-item')
},
lineCls(){
return namespace.derive('title-bottom-line')
},
titleStyle(){
const style = {}
if(this.titleColor){
style.color = this.titleColor
}
return style
},
subtitleCls(){
return namespace.derive('subtitle')
},
subtitleStyle(){
const style = {}
if(this.subtitleColor){
style.color = this.subtitleColor
}
return style
},
rightCls(){
return namespace.derive('right')
},
arrowCls(){
return namespace.derive('arrow')
},
textCls(){
return namespace.derive('text')
},
moreCls(){
return namespace.derive('more')
},
hasLeft(){
return this.leftText || this.leftArrow || this.$slots.left
},
hasRight(){
return this.rightText || this.more || this.$slots.right
}
},
methods:{
onLeftClick(e){
this.$emit('left-click',e)
},
onRightClick(e){
this.$emit('right-click',e)
},
onItemClick(e){
const el = e.target;
const indexVal = el.className.split('-')
this.$emit('change', indexVal[indexVal.length-1])
this.$refs.line.style.transform=`translateX(${el.offsetLeft + el.offsetWidth/4}px)`;
this.title.forEach((item,index) => {
const elCls = `item-title-${index}`;
if (elCls !== el.className) {
this.$refs[elCls].style['font-weight'] = 'normal';
}
})
el.style['font-weight'] = 600;
}
},
mounted() {
if(Object.prototype.toString.call(this.title) === '[object Array]') {
this.offsetWidth = this.$refs['item-title-0'].offsetWidth;
this.$nextTick(() => {
this.$refs['line'].style.width = this.offsetWidth/2 + 'px';
this.$refs['item-title-0'].style['font-weight']=600;
this.$refs['line'].style.transform = `translateX(${this.$refs['item-title-0'].offsetLeft + this.offsetWidth/4}px)`
})
}
},
render(){
const renderLeft = ()=>{
if(this.$slots.left){
return this.$slots.left
}
return [
this.leftArrow && <Icon class={this.arrowCls} name={this.returnIcon} color={this.iconColor} size="20"/>,
this.leftText && <span class={this.textCls}>{this.leftText}</span>
]
}
const renderRight = ()=>{
if(this.$slots.right){
return this.$slots.right
}
return [
this.rightText && <span class={this.textCls}>{this.rightText}</span>,
this.more && <Icon class={this.moreCls} name="more" color={this.iconColor} size="20" />
]
}
const titleItem = ()=>(this.title.map((item,index) =><div ref={`item-title-${index}`}
onClick={this.onItemClick} class={`item-title-${index}`}>{item}</div>))
const renderTitle = ()=>[
this.$slots.title || (Object.prototype.toString.call(this.title) === '[object Array]' &&
(<div class={this.titleItemContainerCls}>
<div class={this.titleItemCls}>{titleItem()}</div>
<transition>
<div ref="line" class={this.lineCls}></div>
</transition>
</div>)) ||
<div class={this.titleCls} style={this.titleStyle}>{this.title}</div>,this.$slots.subtitle ||
(this.subtitle && <div class={this.subtitleCls} style={this.subtitleStyle} >{this.subtitle}</div>)
]
return (
<div class={this.cls} style={this.style}>
<div class={this.contentCls}>
{this.hasLeft && (
<div class={this.leftCls} onClick={this.onLeftClick}>
{renderLeft()}
</div>
)}
<div class={this.titleContainerCls}>
{renderTitle()}
</div>
{this.hasRight &&(
<div class={this.rightCls} onClick={this.onRightClick}>
{renderRight()}
</div>
)}
</div>
</div>
)
}
}