tm-menubars.vue 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <template>
  2. <view @click.stop="" class="tm-menubars fulled ">
  3. <view v-if="!transparent" :style="{ height: tabHeight }"></view>
  4. <view v-if="!transparent" :style="{ height: '45px' }"></view>
  5. <view class="body fulled" :class="[
  6. black_tmeme ? 'bk grey-darken-5 ' : '',
  7. 'shadow-' + color_tmeme + `-${shadow} `,
  8. transparent ? (isTransparent ? 'transparent flat ' + `text-${fontColorTheme}` : color_tmeme) : color_tmeme,
  9. flat ? 'flat' : ''
  10. ]">
  11. <view :style="{ height: tabHeight }"></view>
  12. <view class="body_wk flex-between">
  13. <view class="left flex-start">
  14. <block v-if="showback">
  15. <view v-if="pageUrl && isHome == false" class="home-btn mr-20 text flex-center flex-shrink"
  16. :class="[color_tmeme,black_tmeme ? 'outlined bk' : '']">
  17. <navigator :url="pageUrl" open-type="reLaunch" class="flex-center">
  18. <text class="iconfont icon-home" :style="{ fontSize: '32rpx' }"></text>
  19. </navigator>
  20. </view>
  21. <navigator v-if="!pageUrl" open-type="navigateBack" class="flex-center px-24 flex-shrink fulled-height">
  22. <text style="color: white !important;" class="iconfont icon-angle-left" :class="[`text-${fontColorTheme}`]" :style="{ fontSize: '28rpx' }">返回</text>
  23. </navigator>
  24. </block>
  25. <slot name="left" :data="{ style: widths, isTransparent: isTransparent, title: title }"></slot>
  26. </view>
  27. <view style="color: white !important;" class="center flex-center text-size-g text-overflow text-align-center" :class="[`text-${fontColorTheme}`]">
  28. <slot name="default" :data="{ style: widths, isTransparent: isTransparent, title: title }">
  29. {{ title }}
  30. </slot>
  31. </view>
  32. <view class="right flex-end" :style="{ width: widths.btns }">
  33. <slot name="right" :data="{ style: widths, isTransparent: isTransparent, title: title }"></slot>
  34. </view>
  35. </view>
  36. </view>
  37. </view>
  38. </template>
  39. <script>
  40. /**
  41. * 菜单工具栏
  42. * @property {Boolean} black = [true|false] 默认:false,暗黑模式。
  43. * @property {String|Array} color = [primary] 默认:primary,主题颜色名称如果为array,则为渐变色格式第一个方向:top,bottom,right,left[top,color1,color2],如果为string时,可以为rgba,rgb,#fff或者颜色主题名称如:purple-darken-4
  44. * @property {String} theme = [black|white] 默认:custom,只有在transparent:true时,black:表示黑色模式,文字变白。white文字变黑。
  45. * @property {String} font-color = [] 默认:null,文字颜色,默认不需要提供根据主题色自动推断。一旦赋值,自带的theme失效。使用用户颜色类。
  46. * @property {String} home-url = [] 默认:'/pages/index/index',应用的首页地址。当从其它页面以reLaunch进入非首页时会自动显示首页按钮。
  47. * @property {Boolean} flat = [true|false] 默认:false,去除投影,边线
  48. * @property {Boolean} transparent = [true|false] 默认:false,开启透明顶部。下拉时会变成自定义的背景色。
  49. * @property {Number} scroll-tobg = [true|false] 默认:0,当值大于0即开启透明背景。下拉时达到设定的值,即显示自定义的背景和文字色。
  50. * @property {Number | String} width = [] 默认:0,宽度,数字,或者百度比。数字的单位是upx
  51. * @property {Boolean} showback = [true|false] 默认:true,是否显示左边的返回和首页按钮。
  52. * @property {String} title = [] 默认:标题, 中间标题文字。
  53. * @example <tm-menubars color="white" :showback="false"></tm-menubars>
  54. *
  55. */
  56. import tmIcons from '@/tm-vuetify/components/tm-icons/tm-icons.vue';
  57. export default {
  58. components: {
  59. tmIcons
  60. },
  61. name: 'tm-menubars',
  62. props: {
  63. // 是否开启暗黑模式
  64. black: {
  65. type: String | Boolean,
  66. default: null
  67. },
  68. // 主题颜色名称如果为array,则为渐变色格式第一个方向:top,bottom,right,left[top,color1,color2]
  69. // 如果为string时,可以为rgba,rgb,#fff或者颜色主题名称如:purple-darken-4
  70. color: {
  71. type: String | Array,
  72. default: 'primary'
  73. },
  74. fontColor:{
  75. type:String,
  76. default:''
  77. },
  78. // custom为自定导航样式 。black标题文字为白。white标题文字为黑。它表示的是所处背景的模式。
  79. theme: {
  80. type: String,
  81. default: 'custom' //'black'|'white'|'custom'
  82. },
  83. // 几乎所有组件都有flat选项,去除投影,边线。
  84. flat: {
  85. type: String | Boolean,
  86. default: false
  87. },
  88. // 是否开启顶部透明模式。
  89. transparent: {
  90. type: String | Boolean,
  91. default: false
  92. },
  93. // 当值大于0即开启透明背景。下拉时达到设定的值,即显示自定义的背景和文字色。
  94. scrollTobg: {
  95. type: Number,
  96. default: 70
  97. },
  98. // 是否显示左边的返回和首页按钮。
  99. showback: {
  100. type: Boolean,
  101. default: true
  102. },
  103. // 中间标题文字。
  104. title: {
  105. type: String,
  106. default: '标题'
  107. },
  108. // 首页页面地址。当前访问子页面时,将会显示首页按钮。
  109. homeUrl: {
  110. type: String,
  111. default: '/pages/index/index'
  112. },
  113. shadow: {
  114. type: String | Number,
  115. default: 3
  116. },
  117. // 跟随主题色的改变而改变。
  118. fllowTheme: {
  119. type: Boolean | String,
  120. default: true
  121. }
  122. },
  123. data() {
  124. return {
  125. pageUrl: '',
  126. nowScrollTop: 0,
  127. isHome: false,
  128. tabHeight: 0
  129. };
  130. },
  131. computed: {
  132. black_tmeme: function() {
  133. if (this.black !== null) return this.black;
  134. return this.$tm.vx.state().tmVuetify.black;
  135. },
  136. color_tmeme: function() {
  137. if (this.$tm.vx.state().tmVuetify.color !== null && this.$tm.vx.state().tmVuetify.color && this
  138. .fllowTheme) {
  139. return this.$tm.vx.state().tmVuetify.color;
  140. }
  141. if(this.transparent){
  142. if(this.isTransparent) return ''
  143. }
  144. return this.color;
  145. },
  146. fontColorTheme:function(){
  147. if(this.theme == 'custom') return this.fontColor;
  148. if(this.transparent){
  149. if(this.isTransparent){
  150. if(this.theme == 'black') return 'white';
  151. if(this.theme == 'white') return 'black';
  152. }
  153. }
  154. return this.fontColor;
  155. },
  156. // 当页面在滚动时返回当前是透明还是不透明背景。
  157. isTransparent: function() {
  158. return this.nowScrollTop < this.scrollTobg;
  159. },
  160. ColorThemeName:function(){
  161. return this.color;
  162. },
  163. widths: function() {
  164. let jnwd = 0; //小程序有的胶囊宽度.
  165. // #ifdef MP
  166. // 胶囊的大小。
  167. let mw = uni.getMenuButtonBoundingClientRect();
  168. jnwd = mw.width;
  169. // #endif
  170. return uni.$tm.objToString({
  171. btns: jnwd + 'px',
  172. });
  173. }
  174. },
  175. created() {
  176. let sysinfo = uni.getSystemInfoSync();
  177. let sysbarheight = 0;
  178. // #ifdef MP || APP-PLUS || APP-VUE
  179. sysbarheight = sysinfo.statusBarHeight;
  180. // #endif
  181. this.tabHeight = sysbarheight + 'px';
  182. },
  183. mounted() {
  184. uni.$on('onPageScroll', e => {
  185. this.nowScrollTop = e.scrollTop;
  186. });
  187. // 检查页面栈
  188. let pages = getCurrentPages();
  189. let nopage = pages[pages.length - 1].route;
  190. if (nopage[0] != '/') {
  191. nopage = '/' + nopage;
  192. }
  193. if (nopage == this.homeUrl) {
  194. this.isHome = true;
  195. }
  196. if (pages.length == 1 && typeof pages[0].route !== 'undefined') {
  197. // #ifdef H5
  198. this.pageUrl = '/';
  199. // #endif
  200. // #ifdef MP
  201. this.pageUrl = this.homeUrl;
  202. // #endif
  203. }
  204. },
  205. methods: {}
  206. };
  207. //
  208. </script>
  209. <style lang="scss" scoped>
  210. .tm-menubars {
  211. .body {
  212. position: fixed;
  213. z-index: 450;
  214. top: 0;
  215. left: 0;
  216. &.transparent {
  217. background: none !important;
  218. transition: all 0.6s;
  219. }
  220. .body_wk {
  221. height: 45px;
  222. // opacity: 0.9;
  223. .left {
  224. max-width: 74px;
  225. min-width: 74px;
  226. .home-btn {
  227. border-radius: 50%;
  228. height: 30px;
  229. width: 30px;
  230. line-height: 30px;
  231. margin-left: 24upx;
  232. }
  233. }
  234. .right {
  235. max-width: 74px;
  236. min-width: 74px;
  237. }
  238. .center {
  239. width: calc(100% - 148px);
  240. flex-shrink: 0;
  241. }
  242. }
  243. }
  244. }
  245. </style>