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 相关文章推荐
javascript dom 操作详解 js加强
Jul 13 Javascript
javascript实现日历控件(年月日关闭按钮)
Dec 12 Javascript
javascript中[]和{}对象使用介绍
Mar 20 Javascript
jquery移除、绑定、触发元素事件使用示例详解
Apr 10 Javascript
基于JS实现新闻列表无缝向上滚动实例代码
Jan 22 Javascript
Js调用Java方法并互相传参的简单实例
Aug 11 Javascript
用Vue.js实现监听属性的变化
Nov 17 Javascript
vue.js如何将echarts封装为组件一键使用详解
Oct 10 Javascript
17道题让你彻底理解JS中的类型转换
Aug 08 Javascript
Node.js fs模块(文件模块)创建、删除目录(文件)读取写入文件流的方法
Sep 03 Javascript
JavaScript代码模拟鼠标自动点击事件示例
Aug 07 Javascript
JavaScript实现两个数组的交集
Mar 25 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
全国FM电台频率大全 - 28 甘肃省
2020/03/11 无线电
Phpbean路由转发的php代码
2008/01/10 PHP
一个漂亮的php验证码类(分享)
2013/08/06 PHP
PHP实现原生态图片上传封装类方法
2016/11/08 PHP
通过JAVASCRIPT读取ASP设定的COOKIE
2006/11/24 Javascript
JS 强制设为首页的代码
2009/01/31 Javascript
javascript 三种方法实现获得和设置以及移除元素属性
2013/03/20 Javascript
深入剖析JavaScript编程中的对象概念
2015/10/21 Javascript
javascript仿百度输入框提示自动下拉补全
2016/01/07 Javascript
轻量级jQuery插件slideBox实现带底栏轮播(焦点图)代码
2016/03/28 Javascript
jQuery仿京东商城楼梯式导航定位菜单
2016/07/25 Javascript
又一款MVVM组件 构建自己的Vue组件(2)
2017/03/13 Javascript
详解微信小程序Radio选中样式切换
2017/07/06 Javascript
JavaScript输出所选择起始与结束日期的方法
2017/07/12 Javascript
tangram.js库实现js类的方式实例分析
2018/01/06 Javascript
react.js组件实现拖拽复制和可排序的示例代码
2018/08/20 Javascript
[48:31]完美世界DOTA2联赛PWL S3 DLG vs Phoenix 第二场 12.17
2020/12/19 DOTA
python绘制简单彩虹图
2018/11/19 Python
Appium+Python自动化测试之运行App程序示例
2019/01/23 Python
Python pandas.DataFrame调整列顺序及修改index名的方法
2019/06/21 Python
python中将两组数据放在一起按照某一固定顺序shuffle的实例
2019/07/15 Python
python绘制规则网络图形实例
2019/12/09 Python
django中related_name的用法说明
2020/05/20 Python
Trip.com澳大利亚:在线旅行社
2019/12/01 全球购物
商务日语毕业生自荐信
2013/11/23 职场文书
幼儿园中班新学期寄语
2014/01/18 职场文书
大学军训感言1500字
2014/03/09 职场文书
丧事主持词大全
2014/04/02 职场文书
物业消防安全责任书
2014/07/23 职场文书
个人作风建设剖析材料
2014/10/11 职场文书
民事诉讼代理授权委托书
2014/10/11 职场文书
2015元旦节寄语
2014/12/08 职场文书
德能勤绩廉个人总结
2015/02/14 职场文书
2015年大学迎新工作总结
2015/07/16 职场文书
解决mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO/YES)
2021/06/26 MySQL
Vue3如何理解ref toRef和toRefs的区别
2022/02/18 Vue.js