UNPKG

@minix-iot/ui

Version:

基于Vue的移动端轻量级UI组件库

236 lines (229 loc) 7.1 kB
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> ) } }