Explorar el Código

wip: Waterfall

kailong321200875 hace 1 año
padre
commit
cd774ccc0c

+ 51 - 4
src/components/Waterfall/src/Waterfall.vue

@@ -1,20 +1,67 @@
 <script lang="ts" setup>
 import { propTypes } from '@/utils/propTypes'
 import { useDesign } from '@/hooks/web/useDesign'
+import { ref, nextTick, unref } from 'vue'
 
 const { getPrefixCls } = useDesign()
 
 const prefixCls = getPrefixCls('waterfall')
 
-defineProps({
-  data: propTypes.array.def([]),
+const prop = defineProps({
+  data: propTypes.arrayOf(propTypes.any),
   reset: propTypes.bool.def(false),
   width: propTypes.number.def(200),
   gap: propTypes.number.def(20),
-  getContainer: propTypes.func.def(() => document.body)
+  getContainer: propTypes.func.def(() => document.body),
+  props: propTypes.objectOf(propTypes.string).def({
+    src: 'src',
+    height: 'height'
+  })
 })
+
+const wrapEl = ref<HTMLDivElement>()
+
+const heights = ref<number[]>([])
+
+// 首先确定列数 = 页面宽度 / 图片宽度
+const cols = ref(0)
+
+const filterWaterfall = async () => {
+  const { props, width, gap, getContainer } = prop
+  const data = prop.data as any[]
+  await nextTick()
+
+  const container = (getContainer?.() || unref(wrapEl)) as HTMLElement
+  if (!container) return
+  cols.value = Math.floor(container.clientWidth / (width + gap))
+
+  const length = data.length
+  for (let i = 0; i < length; i++) {
+    if (i + 1 < unref(cols)) {
+      // 说明在第一列
+      const height = data[i][props.height as string]
+      if (height) {
+        heights.value.push(height)
+      } else {
+        await nextTick()
+        const itemEl = container.querySelector(`.${prefixCls}-item__${i}`)
+        const rectObject = itemEl?.clientHeight
+        console.log(rectObject)
+      }
+    }
+  }
+}
+filterWaterfall()
 </script>
 
 <template>
-  <div :class="prefixCls"></div>
+  <div :class="prefixCls" ref="wrapEl">
+    <div
+      v-for="(item, $index) in data"
+      :class="`${prefixCls}-item__${$index}`"
+      :key="`water-${$index}`"
+    >
+      <img :src="item[props.src as string]" alt="" srcset="" />
+    </div>
+  </div>
 </template>

+ 17 - 6
src/utils/propTypes.ts

@@ -1,11 +1,22 @@
-import VueTypes, { toType } from 'vue-types'
-import { CSSProperties, PropType } from 'vue'
+import { VueTypeValidableDef, VueTypesInterface, createTypes, toValidableType } from 'vue-types'
+import { CSSProperties } from 'vue'
 
-class propTypes extends VueTypes {
+type PropTypes = VueTypesInterface & {
+  readonly style: VueTypeValidableDef<CSSProperties>
+}
+const newPropTypes = createTypes({
+  func: undefined,
+  bool: undefined,
+  string: undefined,
+  number: undefined,
+  object: undefined,
+  integer: undefined
+}) as PropTypes
+
+class propTypes extends newPropTypes {
   static get style() {
-    return toType('style', {
-      type: [String, Object] as PropType<[string | CSSProperties]>,
-      default: undefined
+    return toValidableType('style', {
+      type: [String, Object]
     })
   }
 }

+ 7 - 1
src/views/Components/Waterfall.vue

@@ -28,6 +28,12 @@ const { t } = useI18n()
 
 <template>
   <ContentWrap :title="t('router.waterfall')">
-    <Waterfall :data="data" />
+    <Waterfall
+      :data="data"
+      :props="{
+        src: 'image_uri',
+        height: 'height'
+      }"
+    />
   </ContentWrap>
 </template>

+ 2 - 1
vite.config.ts

@@ -151,7 +151,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
         '@wangeditor/editor-for-vue',
         'vue-json-pretty',
         '@zxcvbn-ts/core',
-        'dayjs'
+        'dayjs',
+        'mockjs'
       ]
     }
   }