vue.js 如何使这个旋转木马不可靠的id分配在 prop ?

am46iovg  于 2023-03-13  发布在  Vue.js
关注(0)|答案(1)|浏览(111)

我最近构建了一个带插槽的carousel,但它有一个问题,这个组件基于这样一个事实,即每张幻灯片的id都被定义为一个prop,所以代码看起来更复杂,我相信有更简单的方法来实现它。

<template>
    <div class="carousel">
        
        <slot class="image"></slot>
        <div class="arrow left" @click="prev"
        :class="{ 'invisible': !hasPrev() }">
        <svg width="80px" height="80px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M13.9783 5.31877L10.7683 8.52877L8.79828 10.4888C7.96828 11.3188 7.96828 12.6688 8.79828 13.4988L13.9783 18.6788C14.6583 19.3588 15.8183 18.8688 15.8183 17.9188V12.3088V6.07877C15.8183 5.11877 14.6583 4.63877 13.9783 5.31877Z" fill="#292D32"></path> </g></svg></div>
         <div class="arrow right" @click="next"
         :class="{ 'invisible': !hasNext() }"><svg width="80px" height="80px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" transform="rotate(180)"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <path d="M13.9783 5.31877L10.7683 8.52877L8.79828 10.4888C7.96828 11.3188 7.96828 12.6688 8.79828 13.4988L13.9783 18.6788C14.6583 19.3588 15.8183 18.8688 15.8183 17.9188V12.3088V6.07877C15.8183 5.11877 14.6583 4.63877 13.9783 5.31877Z" fill="#292D32"></path> </g></svg></div>
    </div>

</template>
<script>
import { ref } from "vue";
import { provide } from "vue";
export default {
  setup(props, { slots }) {
    const carouselIds = ref(slots.default().map((slide) => slide.props.id));
    const selectedId = ref(carouselIds.value[0]);
    provide("selectedId", selectedId);

    return {
        carouselIds,
        selectedId,
    };
  },
  data(){
    return{
        id:1
    }
  },
  methods:{
    hasNext() {
            return this.id  < this.carouselIds.length;
        },
        hasPrev() {
            return this.id - 1 >=  1
        },
        prev() {
            if (this.hasPrev()) {
                this.selectedId = this.id-=1
            }
        },
        next() {
            if (this.hasNext()) {
                this.selectedId = this.id+=1;
            }
        }
  },

};

</script>
<style scoped>
.invisible {
    visibility: hidden;
}
.carousel{
    position: relative;

}
.arrow{
    cursor: pointer;
    display: block;
    position: absolute;
    top: 50%;
  transform: translateY(-50%);
}

.arrow.right{
    right: 0;
}
.arrow.left{
    left: 0;
}
</style>

这是我的主Carousel组件,每张幻灯片都是Carousel中的插槽.如你所见,通过提取每个幻灯片组件中定义为prop的id,它创建了一个新的数组,每个id分配给数组中的每张幻灯片.通过点击按钮“next”,“prev”,它改变了id,所以它分配了下一张幻灯片,该幻灯片的id与我们增加的id相同.
x一个一个一个一个x一个一个二个x
我想以某种方式提取数组中所有元素的索引,然后用这些索引创建一个新数组,这样我就可以实现相同的方法,而不必为每张幻灯片分配id。
我在证监会操场的代码

qnakjoqk

qnakjoqk1#

如果希望Carousel负责根据selectedId显示/隐藏滑块,可以使用render函数动态地向display的每个滑块添加一个css类:

import { h } from 'vue'

export default {
  props: {
    selectedId: {
      type: Number,
      required: true
    }
  },
  render() {
    const slides = this.$slots.default()[0].children
    const render = []
    
    slides.forEach((slide, index) => {
      render.push(h('div', { class: this.selectedId === index ? '' : 'hidden'}, slide))
    })
    
    return render
  }
}

我已经相应地改造了你的证监会Playground。
您也可以只在用户导航时才在DOM中插入幻灯片,这会导致一种“延迟加载”:

render() {
    const slide = this.$slots.default()[0].children[this.selectedId]
    
    return h('div', slide)
  }

相关问题