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 相关文章推荐
浅说js变量
May 25 Javascript
javascript实现图片跟随鼠标移动效果的方法
May 13 Javascript
js代码实现随机颜色的小方块
Jul 30 Javascript
详解微信小程序 页面跳转 传递参数
Dec 08 Javascript
bootstrapValidator表单验证插件学习
Dec 30 Javascript
Vue中的Vux配置指南
Dec 08 Javascript
在vue项目中引入highcharts图表的方法(详解)
Mar 05 Javascript
vue+mousemove实现鼠标拖动功能(拖动过快失效问题解决方法)
Aug 24 Javascript
详解SPA中前端路由基本原理与实现方式
Sep 12 Javascript
微信小程序实现文字跑马灯
May 26 Javascript
深入浅析Vue中mixin和extend的区别和使用场景
Aug 01 Javascript
微信小程序绑定手机号获取验证码功能
Oct 22 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代码(星期六,星期日总和)
2009/11/12 PHP
PHP与MYSQL中UTF8编码的中文排序实例
2014/10/21 PHP
2款PHP无限级分类实例代码
2015/11/11 PHP
PHP调用Mailgun发送邮件的方法
2017/05/04 PHP
PHP实时统计中文字数和区别
2019/02/28 PHP
讨论javascript(一)工厂方式 js面象对象的定义方法
2009/12/15 Javascript
extjs 04_grid 单击事件新发现
2012/11/27 Javascript
jquery如何把参数列严格转换成数组实现思路
2013/04/01 Javascript
jquery中对于批量deferred的处理方法
2014/01/22 Javascript
node.js插件nodeclipse安装图文教程
2020/10/19 Javascript
sso跨域写cookie的一段js脚本(推荐)
2016/05/25 Javascript
checkbox 选中一个另一个checkbox也会选中的实现代码
2016/07/09 Javascript
Js遍历键值对形式对象或Map形式的方法
2016/08/08 Javascript
浅谈javascript控制HTML5的全屏操控,浏览器兼容的问题
2016/10/10 Javascript
浅谈js之字面量、对象字面量的访问、关键字in的用法
2016/11/20 Javascript
微信小程序-图片、录音、音频播放、音乐播放、视频、文件代码实例
2016/11/22 Javascript
Nodejs 发送Post请求功能(发短信验证码例子)
2017/02/09 NodeJs
Bootstrap警告框(Alert)插件使用方法
2017/03/21 Javascript
移动端网页开发调试神器Eruda的介绍与使用技巧
2017/10/30 Javascript
详解vue-cli中模拟数据的两种方法
2018/07/03 Javascript
详解微信小程序「渲染层网络层错误」的解决方法
2021/01/06 Javascript
[48:39]Ti4主赛事胜者组第一天 EG vs NEWBEE 2
2014/07/19 DOTA
详解Pandas之容易让人混淆的行选择和列选择
2019/07/10 Python
如何基于python实现归一化处理
2020/01/20 Python
Python的in,is和id函数代码实例
2020/04/18 Python
详解通过变换矩阵实现canvas的缩放功能
2019/01/14 HTML / CSS
赫里福德的一家乡村零售商店:Philip Morris & Son
2017/06/25 全球购物
微软新西兰官方网站:Microsoft New Zealand
2018/08/17 全球购物
NOTINO英国:在线购买美容和香水
2020/02/25 全球购物
Linux管理员面试经常问道的相关命令
2013/04/29 面试题
营销总监岗位职责范本
2014/02/26 职场文书
行政人事专员岗位职责
2014/03/05 职场文书
2014年五四青年节演讲稿范文
2014/04/22 职场文书
政风行风评议工作总结
2014/10/21 职场文书
严以用权学习心得体会
2016/01/12 职场文书
用Python实现一个打字速度测试工具来测试你的手速
2021/05/28 Python