跟小满老师学vue3 第十四章 父子组件传值 + 瀑布流布局

父子组件传值

App.vue(父)

<template>
  <div>父级</div>
  <hr>
  <waterFallVue ref="waterFall" @on-click="getName" :arr="[1,2,3]" :title="name"></waterFallVue>
</template>

<script setup lang="ts">
import {ref} from 'vue'
import waterFallVue from './components/water-fall.vue';
const waterFall = ref<InstanceType<typeof waterFallVue>>()
let name = '小满'

waterFall.value.open

// const getName = (name:string) => {
//   console.log(name,'============>我是父组件')
// }
</script>

water-fall.vue(子)

<template>
  <div>
    子集
  </div>
  <!-- <button @click="send">给父组件传值</button> -->
</template>

<script setup lang="ts">
// 接收父组件传过来的defineProps
// ts 特有定义默认值 withDefaults
// 给父组件传值 defineEmits
// const emit = defineEmits(['on-click'])
/* const emit = defineEmits<{
  (e:'on-click',name:string):void
}>()
const send = () => {
  emit('on-click','小满')
} */
// withDefaults(defineProps<{
//   title:string,
//   arr:number[]
// }>(),{
//   arr: () => [666]
// })
/* const props = defineProps({
  title:{
    type:String,
    default:"默认值"
  }
})

console.log(props.title) */

defineExpose({ //对外暴露,可通过vm(组件实例).value.$s(属性和方法)访问
  name:'小满',
  open:() => console.log(1)
})

</script>

瀑布布局实例

app.vue

<template>
  <div>
    <waterFall :list="list" />
  </div>
</template>

<script setup lang="ts">
import waterFall from './components/water-fall.vue'
const list = [
  {
    height: 300,
    background: 'red'
  },
  {
    height: 400,
    background: 'pink'
  },
  {
    height: 500,
    background: 'blue'
  },
  {
    height: 350,
    background: 'green'
  },
  {
    height: 100,
    background: 'palegreen'
  },
  {
    height: 150,
    background: 'paleturquoise'
  },
  {
    height: 80,
    background: 'purple'
  },
  {
    height: 50,
    background: 'yellowgreen'
  },
  {
    height: 80,
    background: 'red'
  },
  {
    height: 160,
    background: 'blue'
  },
  {
    height: 90,
    background: 'yellowgreen'
  },
  {
    height: 220,
    background: 'palegreen'
  },
  {
    height: 170,
    background: 'pink'
  },
  {
    height: 360,
    background: 'purple'
  },
  {
    height: 410,
    background: 'green'
  },
  {
    height: 290,
    background: 'yellowgreen'
  },
]
</script>

waterFall.vue

<template>
  <div class="wraps">
    <div class="items" v-for="item in waterList" :style="{height:item.height + 'px',background:item.background,left:item.left + 'px',top:item.top + 'px'}"></div>
  </div>
</template>

<script setup lang="ts">
import { onMounted,reactive } from 'vue'
const props = defineProps<{
  list:any[]
}>()
const waterList = reactive<any[]>([])
const heightList:number[] = []
const init = () => {
  const width = 130
  const x = document.body.clientWidth
  const column = Math.floor(x / width)
  console.log(column)

  for (let i = 0; i < props.list.length; i++) {
    if (i < column) {
      props.list[i].left = i * width + 20
      props.list[i].top = 20
      waterList.push(props.list[i])
      heightList.push(props.list[i].height + 20)
    }else{
      let current = heightList[0];
      let index = 0;
      heightList.forEach((h,i) => {
        if (current > h) {
          current = h;
          index = i;
        }
      })
      props.list[i].top = current + 20 
      props.list[i].left = index * width + 20
      heightList[index] = heightList[index] + props.list[i].height + 20
      waterList.push(props.list[i])
      console.log(index)
    }
  }
}

onMounted(() => {
  init()
})
</script>

<style lang="scss" scoped>
.wraps{
  position: relative;
  .items{
    position: absolute;
    width: 120px;
  }
}
</style>

运行结果

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值