ut-row.vue 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. <template>
  2. <view
  3. class="ut-row"
  4. :class="{ 'ut-row--wrap': wrap }"
  5. :style="rowStyle"
  6. >
  7. <slot />
  8. </view>
  9. </template>
  10. <script setup lang="ts">
  11. interface UtRowProps {
  12. /** 总栅格份数,默认 30 */
  13. columns?: number;
  14. /** 列间距,字符串形式,可为数值字符串,内部转为 px */
  15. gap?: string | number;
  16. /** 是否允许换行 */
  17. wrap?: boolean;
  18. }
  19. const props = withDefaults(defineProps<UtRowProps>(), {
  20. columns: 30,
  21. gap: '16rpx',
  22. wrap: true,
  23. });
  24. const ROW_INJECT_KEY = 'ut-row-context';
  25. // 将 gap 统一转成 px 数值
  26. const gapPx = computed(() => {
  27. const val = props.gap;
  28. if (val === '' || val == null) return 0;
  29. // 使用 uView 提供的 px 转换,兼容 rpx / rpx 字符串 / 数值字符串
  30. // @ts-ignore
  31. const fn = uni?.$u?.getPx;
  32. if (typeof fn === 'function') return fn(val as any) || 0;
  33. const n = Number(val);
  34. return Number.isFinite(n) ? n : 0;
  35. });
  36. // 提供给 ut-col 使用的上下文
  37. provide(ROW_INJECT_KEY, {
  38. columns: computed(() => props.columns),
  39. gap: gapPx,
  40. });
  41. // 外层行样式:用负 margin 抵消子项 padding,实现水平 / 垂直间距
  42. const rowStyle = computed(() => {
  43. const g = gapPx.value;
  44. if (!g) return '';
  45. const half = `${g / 2}px`;
  46. return {
  47. marginLeft: `-${half}`,
  48. marginRight: `-${half}`,
  49. marginTop: `-${half}`,
  50. marginBottom: `-${half}`,
  51. } as any;
  52. });
  53. defineExpose({ ROW_INJECT_KEY });
  54. </script>
  55. <style scoped lang="scss">
  56. .ut-row {
  57. display: flex;
  58. flex-direction: row;
  59. flex-wrap: wrap;
  60. }
  61. .ut-row--wrap {
  62. flex-wrap: wrap;
  63. }
  64. </style>