Vue + ts实现轮播插件的示例


Posted in Javascript onNovember 10, 2020

背景

最近在学习 ts,打算用 ts 写一个练手项目,参照的网站内容是 wanandroid,这个接触过android开发的同学可能更i了解一些,其实一开始是打算后台全部都自己写的,不过奈何一个懒字,所以现在的打算就是自己实现登录注册简单的逻辑。这些都不重要,一开始实现轮播是打算在 vue 中引入轮播图 swiper.js,后来想想还是自己写算了。也当作熟悉 ts。先上效果图(这里没有动态图片,各位同学可以自己实现)

代码已经上传 git,进度比较慢,如果可以各位大佬点个 star。 github.com/jiwenjie/vu…

Vue + ts实现轮播插件的示例

<!-- vue 实现轮播图 -->
<template>
 <div id="swiperDIV" :style="{height: height + 'px'}" @mouseover="suspend" @mouseout="autoPlay" @blur="suspend"
  @focus="autoPlay">
  <!-- 淡入淡出效果 -->
  <transition-group tag="ul" class="img-list" :name="animation">
   <li v-for="(item, index) in bannerList" :key="item.id" v-show="curIndex === index">
    <img :src="item[nameField]">
   </li>
  </transition-group>
  <!-- 操作按钮部分(底部导航器) -->
  <ul class="option-list" v-if="showPagination">
   <li class="option-list-item" :class="curIndex === index ? 'cur-option-style':''"
    v-for="(item, index) in bannerList" :key="item.id" @click="jump(item, index)"></li>
  </ul>

  <!-- 左侧右侧切换按钮 -->
  <template v-if="showBtn">
   <div class="common-btn-space pre-btn-space">
    <span class="common-btn-span pre-btn-span"></span>
   </div>
   <div class="common-btn-space next-btn-space">
    <span class="common-btn-span next-btn-span"></span>
   </div>
  </template>
 </div>
</template>

<!-- ts 文件拆分 -->
<script lang="ts">
 // 两种动画背景
 import {
  Component,
  Prop,
  Vue
 } from 'vue-property-decorator'
 import swiper from './ts/swiper'

 @Component({
  name: 'Swiper',
  mixins: [swiper],
 })
 export default class extends Vue {}

</script>

<!-- 样式文件拆分 -->
<style lang="scss" scoped>
 @import url("./css/swiper.scss");

</style>

ts文件

import {
 Component,
 Prop,
 Vue
} from 'vue-property-decorator'
import { Banner } from '@/beans/index' // 首页banner图
@Component({
 name: 'Swiper',
 components: {},
})
export default class IndexPage extends Vue {
 @Prop({ default: 6000 }) private timeout: number; // 默认的切换banner图的时长
 @Prop({ default: 400 }) private height: number | string; // banner区域高度
 @Prop({ default: () => [] }) private bannerList: Banner[]; // 传入的图片数组
 @Prop({ default: 'imagePath' }) private nameField: string; // 图片地址对应的字段名
 @Prop({ default: true }) private showPagination: boolean; // 是否显示底部原点分页器
 @Prop({ default: false }) private showBtn: boolean; // 是否显示左右的切换按钮
 @Prop({
  default: 'fade', validator: function (value) {
   let arr = ['fade', 'translate']
   return arr.includes(value);
 } }) private animation: string; // 是否显示左右的切换按钮

 private timer: any;
 private curIndex: number = 0;

 created(): void {
  this.autoPlay()
 }

 // lifecycle hook
 mounted(): void {

 }

 // method
 private handleSelect() {

 }

 // 自动播放图片
 private autoPlay() {
  clearInterval(this.timer)//还是一样,开启定时器之前需要先清除一下,防止bug
  this.timer = setInterval(this.nextClick, this.timeout as number)
 }

 // 切换下一个 banner 图片
 private nextClick() {
  this.curIndex++;
  if (this.curIndex >= this.bannerList.length) {
   this.curIndex = 0;
  }
 }

 // 切换上一个图片
 private preClick() {
  this.curIndex++;
  if (this.curIndex >= this.bannerList.length) {
   this.curIndex = 0;
  }
 }

 // 暂停的方法
 private suspend() {
  clearInterval(this.timer)
 }

 // 点击底部原点按钮调整方法
 private jump(bannerItem: Banner, index: number) {
  this.curIndex = index;
 }

 // private animationMethodValidator(): string {

 // }
}

css文件

#swiperDIV {
 position: relative;
 display: block;
 width: 100%;
}

.img-list {
 width: 100%;
 height: 100%;
 position: relative;
 margin: 0;
 padding: 0;
 z-index: 9;
}

.img-list li {
 position: absolute;
 left: 0;
 width: 100%;
 height: 100%;
}

.img-list img {
 width: 100%;
 height: 100%;
}

.option-list {
 position: absolute;
 left: 0;
 right: 0;
 bottom: 10px;
 height: 30px;
 line-height: 30px;
 z-index: 99;
 text-align: center;
}

.option-list-item {
 display: inline-block;
 background-color: rgba(255, 255, 255, .4);
 width: 10px;
 height: 10px;
 border-radius: 50%;
 margin: 0 3px;
 cursor: pointer;
}

.cur-option-style {
 background-color: #fff;
}

.common-btn-space {
 position: absolute;
 top: 0;
 bottom: 0;
 z-index: 99;
 width: 22px;
}

.pre-btn-space {
 left: 20px;
}

.next-btn-space {
 right: 20px;
}

.common-btn-span {
 display: inline-block;
 width: 22px;
 height: 22px;
 background-color: transparent;
 cursor: pointer;
 position: absolute;
 top: 0;
 bottom: 0;
 margin: auto;
 border-top: 2px solid transparent;
 border-right: 2px solid transparent;
 border-bottom: 2px solid red;
 border-left: 2px solid red;
}

.pre-btn-span {
 transform: rotate(45deg);
}

.next-btn-span {
 transform: rotate(-135deg);
}

/* 实现动画的两组类(淡入淡出) */
.fade-enter-active,
.fade-leave-active {
 transition: opacity .6s;
}

.fade-enter,
.fade-leave-to {
 opacity: 0;
}

/* (滚动) */
.translate-enter {
 transform: translateX(100%)
}

.translate-enter-to {
 transition: all .6s ease;
 transform: translateX(0);
}

.translate-leave {
 transform: translateX(0)
}

.translate-leave-active {
 transition: all .6s ease;
 transform: translateX(-100%)
}

很多地方做了配置,包括底部的分页器,左右两侧的按钮。动画目前只实现了两种,一种是淡入淡出,一种是平滑滚动。

这里我把整个 vue 文件做了拆分。有多种原因,一个是我司做项目时整体就是这种拆分,不过我司用的就是正常的 vue 和 js。主要原因就是考虑到页面复杂和逻辑交互很多的时候,一个 vue 文件可能超过万行,所以做了拆分,这里我也延续了这种写法,基本思想其实就是使用 mixins 引入 ts。还有一个原因是 ts 在 vue 文件中会有很多莫名其妙的报错,明明代码没问题,但就是有错误警告。如果提到 ts 文件中就正常,这也是我拆分的一个原因。

其他的功能可以自己在加,如果有问题可以留言,有错误希望各位大佬指正。

以上就是Vue + ts实现轮播插件的示例的详细内容,更多关于Vue + ts 轮播插件的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
jQuery之折叠面板的深入解析
Jun 19 Javascript
JS数组的赋值介绍
Mar 10 Javascript
iframe实用操作锦集
Apr 22 Javascript
轻松实现JavaScript图片切换
Jan 12 Javascript
JS Attribute属性操作详解
May 19 Javascript
jQuery实现左侧导航模块的显示与隐藏效果
Jul 04 Javascript
jQuery给指定的table动态添加删除行的操作方法
Oct 12 Javascript
Bootstrap导航条的使用和理解3
Dec 14 Javascript
微信小程序 开发之全局配置
May 05 Javascript
详谈js对url进行编码和解码(三种方式的区别)
Aug 16 Javascript
react 生命周期实例分析
May 18 Javascript
element el-table表格的二次封装实现(附表格高度自适应)
Jan 19 Javascript
vue router返回到指定的路由的场景分析
Nov 10 #Javascript
如何将Node.js中的回调转换为Promise
Nov 10 #Javascript
vue实现动态给id赋值,点击事件获取当前点击的元素的id操作
Nov 09 #Javascript
jquery实现加载更多&quot;转圈圈&quot;效果(示例代码)
Nov 09 #jQuery
夯基础之手撕javascript继承详解
Nov 09 #Javascript
vue实现动态表格提交参数动态生成控件的操作
Nov 09 #Javascript
es5 类与es6中class的区别小结
Nov 09 #Javascript
You might like
php在字符串中查找另一个字符串
2008/11/19 PHP
php实现批量删除挂马文件及批量替换页面内容完整实例
2016/07/08 PHP
PHP命名空间namespace及use的简单用法分析
2018/08/03 PHP
复制本贴标题和地址的js代码
2008/07/01 Javascript
js异常捕获方法介绍
2013/04/10 Javascript
js操作输入框中选择内容兼容IE及其他主流浏览器
2014/04/22 Javascript
javascript实现捕捉键盘上按下的键
2015/05/05 Javascript
jquery验证邮箱格式并显示提交按钮
2015/11/07 Javascript
JavaScript实现同时调用多个函数的方法
2015/11/09 Javascript
Javascript中匿名函数的调用与写法实例详解(多种)
2016/01/26 Javascript
JSON对象 详解及实例代码
2016/10/18 Javascript
JS正则表达式验证密码格式的集中情况总结
2017/02/23 Javascript
Vue-cli项目获取本地json文件数据的实例
2018/03/07 Javascript
详解关于element el-button使用$attrs的一个注意要点
2018/11/09 Javascript
JS实现鼠标拖拽盒子移动及右键点击盒子消失效果示例
2019/01/29 Javascript
JavaScript 九种跨域方式实现原理
2019/02/11 Javascript
jQuery实现的卷帘门滑入滑出效果【案例】
2019/02/18 jQuery
ES6 Generator函数的应用实例分析
2019/06/26 Javascript
vue中监听路由参数的变化及方法
2019/12/06 Javascript
python脚本监控Tomcat服务器的方法
2018/07/06 Python
用Python实现大文本文件切割的方法
2019/01/12 Python
pandas中遍历dataframe的每一个元素的实现
2019/10/23 Python
Python json模块与jsonpath模块区别详解
2020/03/05 Python
CSS3结构性伪类选择器九种写法
2012/04/18 HTML / CSS
AJAX检测用户名是否存在的方法
2021/03/24 Javascript
食品营养与检测应届生求职信
2013/11/08 职场文书
会计顶岗实习心得
2014/01/25 职场文书
个人优缺点自我评价
2014/01/27 职场文书
十佳美德少年事迹材料
2014/02/05 职场文书
应聘文员自荐信范文
2014/03/11 职场文书
《青蛙看海》教学反思
2014/04/23 职场文书
中学生民族团结演讲稿
2014/08/27 职场文书
习总书记三严三实学习心得体会
2014/10/13 职场文书
首席执行官观后感
2015/06/03 职场文书
2016年心理学教育培训学习心得体会
2016/01/12 职场文书
蔬果开业典礼发言稿应该怎么写?
2019/09/03 职场文书