index.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import { postMessage } from '@/helpers/native-message'
  2. import { browser } from '@/helpers/utils'
  3. import { NavBar } from 'vant'
  4. import { defineComponent, PropType, Teleport } from 'vue'
  5. import styles from './index.module.less'
  6. export default defineComponent({
  7. name: 'o-header',
  8. props: {
  9. title: String,
  10. isBack: {
  11. type: Boolean,
  12. default: false
  13. },
  14. backIconColor: {
  15. // 返回按钮颜色
  16. type: String as PropType<'black' | 'white'>,
  17. default: 'black'
  18. },
  19. isFixed: {
  20. type: Boolean,
  21. default: true
  22. },
  23. styleName: {
  24. type: Object,
  25. default: () => ({})
  26. },
  27. titleClass: String,
  28. background: {
  29. type: String,
  30. default: 'white'
  31. },
  32. color: {
  33. type: String,
  34. default: '#323233'
  35. },
  36. rightText: String,
  37. onClickRight: {
  38. type: Function,
  39. default: () => {}
  40. },
  41. border: {
  42. type: Boolean,
  43. default: true
  44. },
  45. onHeaderBack: {
  46. // 头部高度设置后返回
  47. type: Function,
  48. default: () => {}
  49. },
  50. desotry: {
  51. // 用于组件销毁时,是否重置原生头部样式
  52. type: Boolean,
  53. default: true
  54. }
  55. },
  56. watch: {
  57. backIconColor() {
  58. // 设置返回按钮颜色
  59. postMessage({
  60. api: 'backIconChange',
  61. content: { iconStyle: this.backIconColor }
  62. })
  63. }
  64. },
  65. data() {
  66. return {
  67. headerTitle: null as any,
  68. navBarHeight: 0, // 顶部导航栏高度
  69. titleHeight: 44 // 顶部导航高度(默认44px)
  70. }
  71. },
  72. mounted() {
  73. this.headerTitle = this.title || this.$route.meta.title
  74. this.navBarInit(() => {
  75. this.onHeaderBack && this.onHeaderBack()
  76. })
  77. },
  78. unmounted() {
  79. if (this.desotry) {
  80. // 设置是否显示导航栏 0 不显示 1 显示
  81. postMessage({ api: 'setBarStatus', content: { status: 1 } })
  82. // 设置返回按钮颜色
  83. postMessage({
  84. api: 'backIconChange',
  85. content: { iconStyle: 'black' }
  86. })
  87. }
  88. },
  89. methods: {
  90. navBarInit(callBack?: Function) {
  91. // 设置是否显示导航栏 0 不显示 1 显示
  92. postMessage({ api: 'setBarStatus', content: { status: 0 } })
  93. // 设置返回按钮颜色
  94. postMessage({
  95. api: 'backIconChange',
  96. content: { iconStyle: this.backIconColor || 'black' }
  97. })
  98. const sNavHeight = sessionStorage.getItem('navHeight')
  99. const sTitleHeight = sessionStorage.getItem('titleHeight')
  100. if (sNavHeight && sTitleHeight) {
  101. this.navBarHeight = Number(sNavHeight)
  102. callBack && callBack()
  103. } else {
  104. postMessage({ api: 'getNavHeight' }, (res) => {
  105. const { content } = res as any
  106. const dpi = content.dpi || 2
  107. if (content.navHeight) {
  108. const navHeight = content.navHeight / dpi
  109. sessionStorage.setItem('navHeight', String(navHeight))
  110. this.navBarHeight = navHeight
  111. }
  112. if (content.titleHeight) {
  113. // 导航栏的高度
  114. const titleHeight = content.titleHeight / dpi
  115. sessionStorage.setItem('titleHeight', String(titleHeight))
  116. this.titleHeight = titleHeight
  117. }
  118. callBack && callBack()
  119. })
  120. }
  121. !browser().isApp && callBack && callBack()
  122. },
  123. onClickLeft() {
  124. this.$router.back()
  125. },
  126. clickRight() {
  127. console.log('111')
  128. this.onClickRight && this.onClickRight()
  129. }
  130. },
  131. render() {
  132. return (
  133. <div>
  134. {this.$slots.content ? (
  135. <div
  136. style={{
  137. paddingTop: `${this.navBarHeight}px`,
  138. background: this.background
  139. }}
  140. class={styles.headerSection}
  141. >
  142. {this.$slots.content(this.navBarHeight)}
  143. </div>
  144. ) : (
  145. <>
  146. <div
  147. // style={{ paddingTop: `${this.navBarHeight}px` }}
  148. style={{
  149. minHeight: `calc(var(--van-nav-bar-height) + ${this.navBarHeight}px)`
  150. }}
  151. class={styles.headerSection}
  152. >
  153. <NavBar
  154. title={this.headerTitle}
  155. class={[styles.colHeader]}
  156. style={{
  157. background: this.background,
  158. color: this.color,
  159. paddingTop: `${this.navBarHeight}px`
  160. }}
  161. left-arrow={this.isBack}
  162. rightText={this.rightText}
  163. fixed={this.isFixed}
  164. zIndex={2000}
  165. border={this.border}
  166. onClick-right={() => this.clickRight()}
  167. onClick-left={this.onClickLeft}
  168. v-slots={{
  169. right: () => (this.$slots.right && this.$slots.right()) || this.rightText,
  170. title: () => (this.$slots.title && this.$slots.title()) || this.headerTitle
  171. }}
  172. ></NavBar>
  173. </div>
  174. {this.$slots.default ? this.$slots.default() : null}
  175. </>
  176. )}
  177. </div>
  178. )
  179. }
  180. })