<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#app {
width: 1200px;
height: 500px;
border: 1px solid red;
margin: 50px auto;
} .swiper {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
} .item {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
overflow: hidden;
} .active {
z-index: 2
} .animating {
transition: transform .4s ease-in-out;
} .item:nth-child(1) {
background: pink;
} .item:nth-child(2) {
background: green;
} .item:nth-child(3) {
background: blue;
} .item:nth-child(4) {
background: red;
} .item:nth-child(5) {
background: orange;
} .text {
font-size: 50px;
text-align: center;
color: #fff;
line-height: 500px;
} .button {
width: 50px;
height: 100px;
background: #fff;
opacity: .6;
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 3;
} .left {
left: 20px;
} .right {
right: 20px;
} .indicators {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
z-index: 3;
list-style: none;
margin: 0;
padding: 0;
height: 27px;
} .labels {
width: 30px;
height: 3px;
display: inline-block;
padding: 12px 4px;
list-style: none;
margin: 0;
opacity: 0.5;
} .labels-active {
opacity: 1;
} .labels > span {
display: block;
width: 100%;
height: 100%;
background: #fff;
}
</style>
</head>
<body>
<div id="app"></div>
<script src="./vue.global.js"></script>
<script>
// Composition API
const {reactive, onMounted, effect, createApp, onRenderTriggered, computed, watch, onBeforeMount, createComponent} = Vue; const Item = createComponent({
template: `<div class="item text"
:class="{
'active':data.active,
'animating': data.animating
}"
:style="itemStyle()">
<slot></slot>
</div>`,
setup(props) {
let width = 0;
const data = reactive({
translate: 0,
active: false,
animating: false
});
onMounted(() => {
width = document.querySelector('.item').offsetWidth;
translateItem(props.index, props.active, props.length, props.oldIndex);
});
const itemStyle = () => {
const value = `translateX(${data.translate}px)`;
return {
transform: value
}
};
const calcTranslate = (index, active) => {
return width * (index - active);
};
const processIndex = (index, active, length) => {
if (active === 0 && index === length - 1) {
return -1;
} else if (active === length - 1 && index === 0) {
return length;
} else if (index < active - 1 && active - index >= length / 2) {
return length + 1;
} else if (index > active + 1 && index - active >= length / 2) {
return -2;
}
return index;
};
const translateItem = (index, active, length, oldIndex) => {
if (width === 0) {
return;
}
if (oldIndex !== undefined) {
data.animating = index === active || index === oldIndex;
}
if (index !== active && length > 2) {
index = processIndex(index, active, length);
}
data.active = index === active;
data.translate = calcTranslate(index, active);
};
effect(() => {
translateItem(props.index, props.active, props.length, props.oldIndex);
});
return {
data,
itemStyle
}
}
}); const App = {
template: `<div class="swiper"
@mouseenter.stop="removeActive()"
@mouseleave.stop="changeActive()">
<Item v-for="($item, $index) in data.list"
:key="$index"
:index="$index"
:oldIndex="data.oldIndex"
:length="data.list.length"
:active="data.index">
{{$index + 1}}
</Item>
<div class="button left"
@click="activeLeft()">
</div>
<div class="button right"
@click="activeRight()">
</div>
<ul class="indicators">
<li class="labels"
:class="{'labels-active':data.index === $index}"
v-for="($item, $index) in data.list"
@mouseenter="changeLabelsActive($index)">
<span></span>
</li>
</ul>
</div>`,
components: {Item},
setup() {
const data = reactive({
list: [1, 2, 3, 4, 5],
index: 0,
oldIndex: undefined,
time: 3000
});
watch(() => data.index, (val, oldVal) => {
data.oldIndex = oldVal;
});
let time = null;
const _initTimer = (time) => {
return setInterval(() => {
if (data.index < data.list.length - 1) {
data.index++;
} else {
data.index = 0;
}
}, time);
};
onMounted(() => {
time = _initTimer(data.time);
});
const changeActive = () => {
clearInterval(time);
time = _initTimer(data.time);
};
const removeActive = () => {
clearInterval(time);
};
// 节流函数
// 立即执行 在单位时间内只触发一次事件
const throttle = (method, delay) => {
let timer = null;
let start = false;
return function () {
if (!start) {
start = true;
method.apply(this, arguments);
timer = setTimeout(() => {
start = false;
}, delay);
}
};
};
// 防抖函数
// 延迟执行 在事件被触发单位时间内 又被触发 则重新计时
const debounce = (method, delay) => {
let timer = null;
let start = null;
return function () {
let now = Date.now();
if (!start) {
start = now;
}
if (now - start > delay) {
method.apply(this, arguments);
start = now;
} else {
clearTimeout(timer);
timer = setTimeout(() => {
method.apply(this, arguments);
}, delay);
start = now;
}
};
};
const activeLeft = throttle(() => {
if (data.index > 0) {
data.index--;
} else {
data.index = data.list.length - 1;
}
}, 400);
const activeRight = throttle(() => {
if (data.index < data.list.length - 1) {
data.index++;
} else {
data.index = 0;
}
}, 400);
const changeLabelsActive = debounce((index) => {
data.index = index;
}, 400);
return {
data,
changeActive,
removeActive,
activeLeft,
activeRight,
changeLabelsActive
}
}
};
// 挂载
let app = document.getElementById('app');
createApp().mount(App, app);
</script>
</body>
</html>

  

  基于Vue3.0的CSS3动画轮播

vue手写轮播的更多相关文章

  1. 偏前端-纯css,手写轮播-(焦点切换 和 自动轮播 只可选择一种,两者不可共存)

    现在我们一般都是在网上找个轮播插件,各种功能应有尽有,是吧!!~大家似乎已经生疏了手写是什么感觉.万一哪天想不起来,人家要手写,就尴尬了!~~跟我一起复习一下吧 不多说:效果图看一下: 高度不能是固定 ...

  2. 简单的 js手写轮播图

    html: <div class="na1">   <div class="pp">    <div class="na ...

  3. vue-awesome-swipe 基于vue使用的轮播组件 使用(改)

    npm install vue-awesome-swiper --save  //基于vue使用的轮播组件 <template> <swiper :options="swi ...

  4. SpringCloud-Ribbon负载均衡机制、手写轮询算法

    Ribbon 内置的负载均衡规则 在 com.netflix.loadbalancer 包下有一个接口 IRule,它可以根据特定的算法从服务列表中选取一个要访问的服务,默认使用的是「轮询机制」 Ro ...

  5. vue手写的轮播图片,解决已经修改data中的值,页面标签已绑定,但页面没效果

    1.效果 2.index.html <!DOCTYPE html> <html lang="en"> <link> <meta chars ...

  6. vue.js层叠轮播

    最近写公司项目有涉及到轮播banner,一般的ui框架无法满足产品需求:所以自己写了一个层叠式轮播组件:现在分享给大家: 主要技术栈是vue.js ;javascript;jquery:确定实现思路因 ...

  7. mpvue微信小程序怎么写轮播图,和官方微信代码的差别

    目前用mpvue很多第三方的ui库是引入不了的,因为它不支持含有dom操作. 那我们要做轮播图的话一个是手写另外一个就是用小程序的swiper组件了: 官方代码: <swiper indicat ...

  8. 原生Js写轮播图代码

    html css js 在知道jQuery如何实现轮播效果的基础上,用js写代码 如图:标记这里的地方 理解一下 用到的知识: 1.HTML DOM 的appendChild() 和 removeCh ...

  9. 原生JavaScript(js)手把手教你写轮播图插件(banner)

    ---恢复内容开始--- 1.轮播图插件 1.什么是插件: 为已有的程序增加功能 2.插件的特点(为什么要做成一个插件)与注意事项: 1.通用性,可移植性强 2.兼容性:不会对其他代码产生影响 3.创 ...

随机推荐

  1. Mac更改PHP默认目录的方法

    参考:http://www.cnblogs.com/muyunlee/p/6386095.html

  2. Python之路-变量和基本数据类型详解(变量、数据类型、)

    一.注释 注释的作用: 增加程序的可读性 作为调试用 提高团队的合作效率 注释的分类 1.单行注释 以井号(#)开头,右边的所有内容当做说明 2.多行注释 以三对单引号(’’’注释内容’’’)将注释包 ...

  3. 【知识强化】第七章 输入/输出系统 7.1 I/O系统基本概念

    那么下面,我们将要进入计算机组成原理的最后一章,也就是我们的第七章,输入输出系统的学习.那么这一部分内容呢,我们之前呢一直在提,但是并没有详细地讲解,那么进入到我们第七章输入输出系统这一部分,我们就要 ...

  4. 【记录】git error:bad signature 解决方法

    今天提交git 的时候出现 bad signature 错误,意思是git下的index文件损坏了,需要重新生成下 error: bad signature fatal: index file cor ...

  5. [HNOI2009]有趣的数列(卡塔兰数,线性筛)

    [HNOI2009]有趣的数列 题目描述 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满足a1< ...

  6. service pom

    <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> &l ...

  7. Eclipse 4.9 创建springboot项目步骤

    上一篇文章写了eclipse安装STS. 现在创建Spring Starter Project  具体步骤如下: 1.等你安装好STS后,就在Eclipse >  File >New 选择 ...

  8. SQL Server数据库的软硬件性能瓶颈

    在过去十年里,很多复杂的企业应用都是用Microsoft SQL Server进行开发和部署的.如今,SQL Server已经成为现代业务应用的基石,并且它还是很多大公司业务流程的核心.SQL Ser ...

  9. How-To-Ask-Questions-The-Smart-Way提问的技巧 提问的智慧

    How-To-Ask-Questions-The-Smart-Way https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/b ...

  10. PHP-图片处理

    开启 GD 扩展(php_gd2.dll) 创建画布 画布:一种资源型数据,可以操作的图像资源. 创建新画布(新建) ImageCreate(宽,高); 创建基于调色板的画布. imageCreate ...