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实现的论坛常用的运行代码的效果
Jul 15 Javascript
javascript实现文本域写入字符时限定字数
Feb 12 Javascript
javascript中不提供sleep功能如何实现这个功能
May 27 Javascript
node.js中的path.dirname方法使用说明
Dec 09 Javascript
vue.js入门教程之基础语法小结
Sep 01 Javascript
Node.js实现mysql连接池使用事务自动回收连接的方法示例
Feb 03 Javascript
React之PureComponent的使用作用
Jul 10 Javascript
深入理解Vue router的部分高级用法
Aug 15 Javascript
Nuxt升级2.0.0时出现的问题(小结)
Oct 08 Javascript
JS实现随机生成10个手机号的方法示例
Dec 07 Javascript
vue中组件通信详解(父子组件, 爷孙组件, 兄弟组件)
Jul 27 Javascript
Vue包大小优化的实现(从1.72M到94K)
Feb 18 Vue.js
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下一个阿拉伯数字转中文数字的函数
2007/07/16 PHP
Uchome1.2 1.5 代码学习 common.php
2009/04/24 PHP
PHP遍历二维数组的代码
2011/04/22 PHP
php判断上传的Excel文件中是否有图片及PHPExcel库认识
2013/01/11 PHP
浅析php中三个等号(===)和两个等号(==)的区别
2013/08/06 PHP
10个值得深思的PHP面试题
2016/11/14 PHP
PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法分析
2017/02/04 PHP
JavaScript Event学习补遗 addEventSimple
2010/02/11 Javascript
javascript suggest效果 自动完成实现代码分享
2012/02/17 Javascript
jquery实现div拖拽宽度示例代码
2013/07/31 Javascript
jQuery.holdReady()使用方法
2014/05/20 Javascript
JavaScript获取鼠标移动时的坐标(兼容IE8、chome谷歌、Firefox)
2014/09/13 Javascript
Jquery的基本对象转换和文档加载用法实例
2015/02/25 Javascript
JavaScript通过function定义对象并给对象添加toString()方法实例分析
2015/03/23 Javascript
浅析Node.js:DNS模块的使用
2016/11/23 Javascript
AngularJS表单基本操作
2017/01/09 Javascript
js仿iphone秒表功能 计算平均数
2017/01/11 Javascript
详解webpack的配置文件entry与output
2017/08/21 Javascript
浅谈Vue.js 关于页面加载完成后执行一个方法的问题
2019/04/01 Javascript
微信小程序图片左右摆动效果详解
2019/07/13 Javascript
opencv实现图片模糊和锐化操作
2018/11/19 Python
Python常用模块之requests模块用法分析
2019/05/15 Python
seek引发的python文件读写的问题及解决
2019/07/26 Python
解决python明明pip安装成功却找不到包的问题
2019/08/28 Python
Python字典取键、值对的方法步骤
2020/09/30 Python
Python 列表反转显示的四种方法
2020/11/16 Python
Django自带的用户验证系统实现
2020/12/18 Python
TALLY WEiJL法国网上商店:服装、时装及配饰
2019/08/31 全球购物
FragranceNet中文网:北美健康美容线上零售商
2020/08/26 全球购物
2014离婚协议书范文(3篇)
2014/11/29 职场文书
单位提档介绍信
2015/10/22 职场文书
详解PHP服务器如何在有限的资源里最大提升并发能力
2021/05/25 PHP
Java9新特性之Module模块化编程示例演绎
2022/03/16 Java/Android
Python+OpenCV实现在图像上绘制矩形
2022/03/21 Python
MySQ InnoDB和MyISAM存储引擎介绍
2022/04/26 MySQL
HTML页面点击按钮关闭页面的多种方式
2022/12/24 HTML / CSS