我一直在尝试破解这个简单的逻辑但却失败了,我真的需要你的帮助。 那么我想要实现的是在插槽中添加或修改类名。
// Parent component
<div class="col">
<slider>
<slide v-for="intro in compOpts.blockIntro">
<block-intro :compOpts="{ props: { wrapper: true, bg: false } }">
<p v-html="intro.title"></p>
<div slot="content" v-html="intro.content" class="blockIntro__content"></div>
</block-intro>
</slide>
</slider>
</div>
// Slider component
<div class="slider__container">
<slot></slot>
</div>
// Slide component
<div>
<slot></slot>
</div>
// BlockIntro component
<div class="col--h100" :class="{ 'bg--darkDark': compOpts.props.bg, 'col': !compOpts.props.wrapper }"> << --- Add visible class here from Slider component
<div class="col col__blockIntro" :class="{ 'col__blockIntro--spaced': compOpts.props.spaced }">
<div class="col col__blockIntro__introQuote">
<slot></slot>
</div>
<slot name="content"></slot>
</div>
<div class="col--h100" :class="{ 'bg--darkDark': compOpts.props.bg, 'col': !compOpts.props.wrapper }"> << --- Add visible class here from Slider component
组件层次结构
-> Slider
--> Slide
---> BlockIntro
我的Slot组件给我BlockIntro组件模板和div.col - h100是Slider中的第一个/父子元素。现在我正在尝试将一个可见类添加到div.col - 来自Slider组件的h100。我使用$ slots安装了Vnode,但无法更改$ slots中的值。$ elm.className
请帮忙。
P.S。我是Vue的新手,所以如果我的结构不对,请原谅我
P.S。我想我无法清楚地解释自己。所以我期待实现的是在Vue2中实现以下轮播
答案 0 :(得分:3)
这是您链接到Vue的幻灯片的首次转换。请注意,我使用作用域槽来传递插槽中包含的方法组件。希望你能用它来获得一些想法。
可立即采取的一些改进
console.clear()
const slideData = [
{
url:"https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/waterfall-free-stock-photo-244915.jpg",
backgroundColor:"green"
},
{
url:"https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/free-stock-photos-1.jpg",
backgroundColor:"orange"
},
{
url: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/snowy-winter-vignette-bokeh-night-snow-falling-free-stock-photo.jpg",
backgroundColor: "red"
}
]
Vue.component("slideshow",{
template: `
<div class="container">
<ul id="slides">
<slot name="slides" :register="registerSlide" :active="activeSlide">
{{registerSlide}}
</slot>
</ul>
<slot :pause="pause"
:play="playSlideshow"
:next="nextSlide"
:prev="previousSlide"
name="controls">
</slot>
</div>
`,
data(){
return {
slides:[],
currentSlide: 0,
playing: false,
slideInterval: null,
controls: null,
activeSlide: null
}
},
methods:{
pause(){
clearInterval(this.slideInterval)
},
registerSlide(slide){
this.slides.push(slide)
},
goToSlide(n){
this.currentSlide = (n+this.slides.length)%this.slides.length;
this.activeSlide = this.slides[this.currentSlide]
},
nextSlide(){
this.goToSlide(this.currentSlide+1);
},
previousSlide(){
this.goToSlide(this.currentSlide-1);
},
playSlideshow(){
this.playing = true;
this.slideInterval = setInterval(this.nextSlide,2000);
}
},
mounted(){
if (this.slides.length > 0){
this.activeSlide = this.slides[this.currentSlide]
this.playSlideshow()
}
}
})
Vue.component("slide",{
props:["slide", "register", "active"],
template:`
<li class="slide" :class="slideClass" :style="slideStyle"></li>
`,
data(){
return {
showing: false,
isSlide: true
}
},
computed:{
slideClass(){
return {
showing: this.active === this,
}
},
slideStyle(){
return {
'background-image': `url(${this.slide.url})`,
'background-color': this.slide.backgroundColor
}
}
},
mounted(){
console.log(this.$props)
this.register(this)
}
})
Vue.component("slide-controls", {
props:["pause", "play", "next", "prev"],
template:`
<div class="buttons" style="top: 10px; left: 10px">
<button @click="prev" class="controls" id="previous"><</button>
<button @click="onPause" class="controls" id="pause">{{paused ? '►' : '❚❚'}}</button>
<button @click="next" class="controls" id="next">></button>
</div>
`,
data(){
return {
isControls: true,
paused: false
}
},
methods:{
onPause(){
this.paused = !this.paused
if (this.paused)
this.pause()
else
this.play()
}
}
})
new Vue({
el: "#app",
data:{
slides: slideData,
}
})
/*
essential styles:
these make the slideshow work
*/
#slides{
position: relative;
height: 300px;
padding: 0px;
margin: 0px;
list-style-type: none;
}
.slide{
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
opacity: 0;
z-index: 1;
-webkit-transition: opacity 1s;
-moz-transition: opacity 1s;
-o-transition: opacity 1s;
transition: opacity 1s;
}
.showing{
opacity: 1;
z-index: 2;
}
/*
non-essential styles:
just for appearance; change whatever you want
*/
.slide{
font-size: 40px;
padding: 40px;
box-sizing: border-box;
background: #333;
color: #fff;
background-size: cover;
}
.controls{
background: #333;
color: #fff;
border: none;
padding: 20px 0px;
font-size: 20px;
cursor: pointer;
border: 2px solid #fff;
margin: 10px 0px 0px 10px;
width: 70px;
}
.controls:hover,
.controls:focus{
background: #eee;
color: #333;
}
.container{
position: relative;
}
.buttons{
position: absolute;
left: 0px;
top: 0px;
z-index: 10;
font-size: 0px;
}
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
<slideshow>
<template slot="slides" scope="props">
<slide v-for="slide in slides"
:slide="slide"
v-bind="props">
</slide>
</template>
<template slot="controls" scope="props">
<slide-controls v-bind="props"></slide-controls>
</template>
</slideshow>
</div>