vue 幻灯片组件封装
2019-04-16 本文已影响0人
铁匠简记
今天来做个幻灯组件的笔记,这里只记录实现逻辑,不对样式代码做展示。
一个幻灯片组件需要实现的功能如下:
1、幻灯片的循环播放;
2、幻灯片分页;
3、幻灯片标题的显示;
4、鼠标进入,停止幻灯切换;
5、鼠标离开,继续幻灯切换;
6、点击相应幻灯,或幻灯标题,触发不同事件(根据实际需求做处理);
7、点击页码,实现幻灯切换及循环播放。
效果如下:
具体步骤
第一步:新建slideShow.vue组件;
<template>
<div>hello world {{ x }}</div>
</template>
<script>
export default {
name: "slideShow",
data() {
return {
x : '我是slideShow'
}
}
}
</script>
第二步:在父组件中引入
// template
<div class="index-right">
<slide-show></slide-show>
</div>
// script
import slideShow from '../components/slideShow'
export default {
components: {
slideShow
},
data() {
return {
}
}
}
这时候可以看到效果:slideShow组件的内容已被渲染到父组件
第三步:在父组件为幻灯片动态绑定要显示的内容,并在子组件接收。
知识点:父、子组件通信。
父组件 :template
<slide-show :slides="slides"></slide-show>
script :data
slides: [
{
src: require('../assets/slideShow/pic1.jpg'),
title: 'xxx1',
href: 'detail/analysis'
},
{
src: require('../assets/slideShow/pic2.jpg'),
title: 'xxx2',
href: 'detail/count'
},
{
src: require('../assets/slideShow/pic3.jpg'),
title: 'xxx3',
href: 'http://xxx.xxx.com'
},
{
src: require('../assets/slideShow/pic4.jpg'),
title: 'xxx4',
href: 'detail/forecast'
}
]
子组件,这里限制了父组件传参的类型
props: {
slides: {
type: Array,
default: []
}
},
mounted () {
console.log(this.slides)
}
这里可以看到,子组件接收到了父组件传过来的参数
第四步:把父组件传来的参数展示在模板;
<template>
<div class="slide-show">
<div class="slide-img">
<a href="xxx">
<img :src="slides[0].src">
</a>
</div>
<h2>{{ slides[0].title }}</h2>
<ul class="slide-pages">
<li><</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>></li>
</ul>
</div>
</template>
效果如下
第五步:分页,让幻灯片切换
<template>
<div class="slide-show">
<div class="slide-img">
<a :href="slides[nowIndex].href">
<img :src="slides[nowIndex].src">
</a>
</div>
<h2>{{ slides[nowIndex].title }}</h2>
<ul class="slide-pages">
<li><</li>
<li v-for="(item, index) in slides" @click="goto(index)">
<a>{{ index + 1 }}</a>
</li>
<li>></li>
</ul>
</div>
</template>
methods: {
goto(index) {
this.nowIndex = index
}
},
实现页码上一页、下一页功能;使用计算属性,通过一个方法实现;
知识点:计算属性。
<li @click="goto(prevIndex)"><</li>
<li v-for="(item, index) in slides" @click="goto(index)">
<a :class="{on: index === nowIndex}">{{ index + 1 }}</a>
</li>
<li @click="goto(nextIndex)">></li>
computed: {
prevIndex () {
if (this.nowIndex === 0) {
return this.slides.length - 1
}
else {
return this.nowIndex - 1
}
},
nextIndex () {
if (this.nowIndex === this.slides.length - 1) {
return 0
}
else {
return this.nowIndex + 1
}
}
},
第六步:让幻灯片自动切换
父组件动态传参:幻灯片自动切换时间间隔
<slide-show :slides="slides" :inv="invTime"></slide-show>
// 在data中注册
invTime: 2000,
子组件
// props 注册组件的动态属性
inv: {
type: Number,
default: 1000
}
// 添加 methods实现幻灯片切换
runInv () {
this.invId = setInterval(() => {
this.goto(this.nextIndex)
}, this.inv)
},
// 在mounted中调用方法
mounted () {
this.runInv();
}
第七步:鼠标事件
// 在methods注册一个清除切换的方法
clearInv () {
clearInterval(this.invId)
}
// 在根节点添加鼠标时间
<template>
<div class="slide-show" @mouseover="clearInv" @mouseout="runInv">
...
第八步:高级功能:图片的动画效果
知识点:样式标签transition的使用;
难点:这里的两个nowIndex一个是新值一个是旧值,在goto函数中改变。
// 幻灯片切换添加transition
<a :href="slides[nowIndex].href">
<transition name="slide-trans">
<img v-if="isShow" :src="slides[nowIndex].src">
</transition>
<transition name="slide-trans-old">
<img v-if="!isShow" :src="slides[nowIndex].src">
</transition>
</a>
// 为变量注册初始值
isShow:true
// 修改goto函数
goto(index) {
this.isShow = false
setTimeout(() => {
this.isShow = true
this.nowIndex = index
}, 10)
},
// 添加样式
.slide-trans-enter-active {
transition: all .5s;
}
.slide-trans-enter {
transform: translateX(900px);
}
.slide-trans-old-leave-active {
transition: all .5s;
transform: translateX(-900px);
}
第九步:子组件切换:触发父组件的事件
知识点:子组件向父组件通信
// 所有的切换都是在goto函数中,所以在goto函数调用事件$emit
goto(index) {
this.isShow = false
setTimeout(() => {
this.isShow = true
this.nowIndex = index
this.$emit('onChange',index)
}, 10)
},
// 在父组件的子组件标签中绑定事件
<slide-show :slides="slides" :inv="invTime" @onChange="doSomethingOnSlideChange"></slide-show>
// 在methods中实现绑定的事件
methods: {
doSomethingOnSlideChange() {
console.log('幻灯片切换了,父组件要做点什么')
}
},