s-custom-navbar.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <template>
  2. <navbar
  3. :alway="isAlway"
  4. :back="false"
  5. bg=""
  6. :placeholder="isPlaceholder"
  7. :bgStyles="bgStyles"
  8. :opacity="isOpacity"
  9. :sticky="sticky"
  10. >
  11. <template #item>
  12. <view class="nav-box">
  13. <view
  14. class="nav-item"
  15. v-for="(item, index) in navList"
  16. :key="index"
  17. :style="[parseImgStyle(item)]"
  18. :class="[{ 'ss-flex ss-col-center ss-row-center': item.type !== 'search' }]"
  19. >
  20. <navbar-item :data="item" :width="parseImgStyle(item).width" />
  21. </view>
  22. </view>
  23. </template>
  24. </navbar>
  25. </template>
  26. <script setup>
  27. /**
  28. * 装修组件 - 自定义标题栏
  29. *
  30. *
  31. * @property {Number | String} alwaysShow = [0,1] - 是否常驻
  32. * @property {Number | String} mode = [inner] - 是否沉浸式
  33. * @property {String | Number} type - 标题背景模式
  34. * @property {String} color - 页面背景色
  35. * @property {String} src - 页面背景图片
  36. */
  37. import { computed, unref } from 'vue';
  38. import sheep from '@/sheep';
  39. import Navbar from './components/navbar.vue';
  40. import NavbarItem from './components/navbar-item.vue';
  41. const props = defineProps({
  42. data: {
  43. type: Object,
  44. default: () => ({}),
  45. },
  46. });
  47. const sticky = computed(() => {
  48. if (props.data.mode == 'inner') {
  49. if (props.data.alway) {
  50. return false;
  51. }
  52. }
  53. if (props.data.mode == 'normal') {
  54. return false;
  55. }
  56. });
  57. const navList = computed(() => {
  58. if (!props.data.list) return [];
  59. // #ifdef MP
  60. return props.data.list.mp;
  61. // #endif
  62. return props.data.list.app;
  63. });
  64. // 单元格大小
  65. const windowWidth = sheep.$platform.device.windowWidth;
  66. const cell = computed(() => {
  67. if (unref(navList).length) {
  68. let cell = (windowWidth - 90) / 8;
  69. // #ifdef MP
  70. cell = (windowWidth - 80 - unref(sheep.$platform.capsule).width) / 6;
  71. // #endif
  72. return cell;
  73. }
  74. });
  75. // 解析位置
  76. const parseImgStyle = (item) => {
  77. let obj = {
  78. width: item.width * cell.value + (item.width - 1) * 10 + 'px',
  79. left: item.left * cell.value + (item.left + 1) * 10 + 'px',
  80. 'border-radius': item.borderRadius + 'px',
  81. };
  82. return obj;
  83. };
  84. const isAlway = computed(() =>
  85. props.data.mode === 'inner' ? Boolean(props.data.alwaysShow) : true,
  86. );
  87. const isOpacity = computed(() =>
  88. props.data.mode === 'normal' ? false : props.data.mode === 'inner',
  89. );
  90. const isPlaceholder = computed(() => props.data.mode === 'normal');
  91. const bgStyles = computed(() => {
  92. if (props.data.type) {
  93. return {
  94. background:
  95. props.data.type == 'color'
  96. ? props.data.color
  97. : `url(${sheep.$url.cdn(props.data.src)}) no-repeat top center / 100% 100%`,
  98. };
  99. }
  100. });
  101. </script>
  102. <style lang="scss" scoped>
  103. .nav-box {
  104. width: 750rpx;
  105. position: relative;
  106. height: 100%;
  107. .nav-item {
  108. position: absolute;
  109. top: 50%;
  110. transform: translateY(-50%);
  111. }
  112. }
  113. </style>