gpt4 book ai didi

javascript - 计算 Vue 插槽的高度和宽度

转载 作者:搜寻专家 更新时间:2023-10-30 22:28:36 25 4
gpt4 key购买 nike

我无法计算插槽的高度和宽度。我正在尝试在我的 Perimeter 组件中渲染图像。这些图像的大小为 105x160。但是,当我控制台记录 clientWidth 和 clientHeight 时,我得到 0x24。

我相信我的问题与此有关:In vue.js 2, measure the height of a component once slots are rendered但我还是想不通。我已经尝试在 Perimeter 组件和各个插槽组件上使用 $nextTick。

在我的 Perimeter 组件中,我有:

<template>
<div class="d-flex">
<slot></slot>
<div class="align-self-center">
<slot name="center-piece"></slot>
</div>
</div>
</template>

<script>
export default {
name: 'Perimeter',
mounted() {
this.distributeSlots();
},
updated() {
this.distributeSlots();
},
computed: {
centerRadius() {
return this.$slots['center-piece'][0].elm.clientWidth / 2;
},
},
methods: {
distributeSlots() {
let angle = 0;
const {
clientHeight: componentHeight,
clientWidth: componentWidth,
offsetTop: componentOffsetTop,
offsetLeft: componentOffsetLeft,
} = this.$el;
const componentXCenter = componentWidth / 2;
const componentYCenter = componentHeight / 2;

const slots = this.$slots.default.filter(slot => slot.tag) || [];
const step = (2 * Math.PI) / slots.length;

slots.forEach((slot) => {
slot.context.$nextTick(() => {
const { height, width } = slot.elm.getBoundingClientRect();
console.log(`height ${height}, width ${width}`);
const distanceFromCenterX = (this.centerRadius + componentXCenter) * Math.cos(angle);
const distanceFromCenterY = (this.centerRadius + componentYCenter) * Math.sin(angle);
const x = Math.round((componentXCenter + distanceFromCenterX + componentOffsetLeft) - (width / 2));
const y = Math.round((componentYCenter + distanceFromCenterY + componentOffsetTop) - (height / 2));

slot.elm.style.left = `${x}px`;
slot.elm.style.top = `${y}px`;

angle += step;
});
});
},
},
};
</script>

我还编写了没有 $nextTick 的 distributeSlots() 方法:

distributeSlots() {
let angle = 0;
const {
clientHeight: componentHeight,
clientWidth: componentWidth,
offsetTop: componentOffsetTop,
offsetLeft: componentOffsetLeft,
} = this.$el;
const componentXCenter = componentWidth / 2;
const componentYCenter = componentHeight / 2;

const slots = this.$slots.default.filter(slot => slot.tag) || [];
const step = (2 * Math.PI) / slots.length;

slots.forEach((slot) => {
const { height, width } = slot.elm.getBoundingClientRect();
const distanceFromCenterX = (this.centerRadius + componentXCenter) * Math.cos(angle);
const distanceFromCenterY = (this.centerRadius + componentYCenter) * Math.sin(angle);
const x = Math.round((componentXCenter + distanceFromCenterX + componentOffsetLeft) - (width / 2));
const y = Math.round((componentYCenter + distanceFromCenterY + componentOffsetTop) - (height / 2));

slot.elm.style.left = `${x}px`;
slot.elm.style.top = `${y}px`;

angle += step;
});
},

我按如下方式传递给 Perimeter 组件:

<template>
<perimeter>
<div v-for="(book, index) in books.slice(0, 6)" v-if="book.image" :key="book.asin" style="position: absolute">
<router-link :to="{ name: 'books', params: { isbn: book.isbn }}">
<img :src="book.image" />
</router-link>
</div>
<perimeter>
</template>

更糟糕的是,当我在 forEach 函数中使用 console.log(slot.elm) 并在浏览器控制台中打开数组时,我看到了正确的 clientHeight + clientWidth:

ClientHeight and ClientWidth when slot.elm logged and expanded

最佳答案

通常在这种情况下,这是一个逻辑错误,而不是框架的问题。因此,我会继续将您的代码简化到能够证明您的问题的最低限度。

假设您在 mounted() 或之后获得了 clientWidthclientHeight,如下所示,它应该可以正常工作。

避免任何计时器黑客攻击,它们是极难调试的错误的罪魁祸首。

<template>
<div style="min-height: 100px; min-width: 100px;">
<slot />
</div>
</template>

<script>
export default {
name: 'MyContainer',
data (){
return {
width: 0,
height: 0,
}
},
mounted (){
this.width = this.$slots["default"][0].elm.clientWidth
this.height = this.$slots["default"][0].elm.clientHeight
console.log(this.width, this.height) // => 100 100 (or more)
},

}
</script>

<style scoped lang="scss">
</style>

关于javascript - 计算 Vue 插槽的高度和宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47420251/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com