1. 滚动条封装
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>滚动条</title>
<style>
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
overflow: hidden;
}
.box {
position: relative;
width: 100%;
height: 100%;
}
.box .scroll {
position: absolute;
right: 0;
top: 0;
width: 40px;
height: 100%;
background-color: aquamarine;
}
.box .scroll .scrollIn {
position: absolute;
width: 40px;
height: 100px;
background-color: orangered;
}
.box .content {
position: absolute;
}
</style>
</head>
<body>
<div class="box">
<div class="scroll">
<div class="scrollIn"></div>
</div>
<div class="content"></div>
</div>
<script>
var content = document.querySelector(".box .content");
var scroll = document.querySelector(".box .scroll");
var scrollIn = document.querySelector(".box .scroll .scrollIn");
for (var i = 1; i <= 300; i++) {
content.innerHTML += i + "<br>";
}
var scroll_dis = scroll.clientHeight;
var content_dis = content.clientHeight;
var scale = scroll_dis / content_dis;
var scrollIn_dis = scale * scroll_dis;
scrollIn.style.height = scrollIn_dis + "px";
scrollIn.onmousedown = function (event) {
var eleY = scrollIn.offsetTop;
var startY = event.clientY;
document.onmousemove = function (event) {
var endY = event.clientY;
var disY = endY - startY;
var lastY = disY + eleY;
if (lastY >= document.documentElement.clientHeight - scrollIn.offsetHeight) {
lastY = document.documentElement.clientHeight - scrollIn.offsetHeight;
} else if (lastY <= 0) {
lastY = 0;
}
scrollIn.style.top = lastY + "px";
content_dis = lastY / scale;
content.style.top = -content_dis + "px";
};
document.onmouseup = function () {
document.onmousemove = document.onmouseup = null;
};
};
function f1(event) {
event = event || window.event;
var flag = true;
if (event.wheelDelta) {
if (event.wheelDelta > 0) {
flag = true;
} else {
flag = false;
}
} else {
if (event.detail < 0) {
flag = true;
} else {
flag = false;
}
}
var startY = scrollIn.offsetTop;
var lastY;
if (flag) {
lastY = startY - 10;
} else {
lastY = startY + 10;
}
if (lastY > document.documentElement.clientHeight - scrollIn.offsetHeight) {
lastY = document.documentElement.clientHeight - scrollIn.offsetHeight;
} else if (lastY <= 0) {
lastY = 0;
}
scrollIn.style.top = lastY + "px";
content_dis = lastY / scale;
content.style.top = -content_dis + "px";
}
document.addEventListener("mousewheel", f1);
document.addEventListener("DOMMouseScroll", f1);
</script>
</body>
</html>
2. 轮播图
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>轮播</title>
<style>
* {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
}
li {
list-style: none;
}
.box {
overflow: hidden;
position: relative;
width: 500px;
height: 400px;
margin: 150px auto;
}
.box .list {
position: absolute;
width: 3500px;
height: 400px;
left: -500px;
}
.box .list li {
float: left;
width: 500px;
height: 400px;
}
.box .list li img {
width: 500px;
height: 400px;
}
.box .circle {
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 10px;
}
.box .circle li {
float: left;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: white;
opacity: 0.5;
margin-right: 5px;
cursor: pointer;
transition: all 0.3;
}
.box .circle .current {
opacity: 1;
}
.box .link {
position: absolute;
width: 100%;
height: 60px;
top: 50%;
transform: translateY(-50%);
}
.box .left,
.box .right {
position: absolute;
width: 80px;
height: 80px;
color: #fff;
background-color: rgba(200, 200, 200, 0.7);
font-size: 80px;
text-align: center;
line-height: 80px;
opacity: 0;
transition: all 0.5s;
}
.box .left {
left: 0;
}
.box .right {
right: 0;
}
</style>
</head>
<body>
<div class="box">
<ul class="list">
<li>
<a href="javascript:;"><img src="D:\steam\steamapps\workshop\content\431960\2542550955\preview.jpg" alt="" /></a>
</li>
<li>
<a href="javascript:;"><img src="D:\steam\steamapps\workshop\content\431960\2533685650\preview.jpg" alt="" /></a>
</li>
<li>
<a href="javascript:;"><img src="D:\steam\steamapps\workshop\content\431960\2236720263\preview.jpg" alt="" /></a>
</li>
<li>
<a href="javascript:;"><img src="D:\steam\steamapps\workshop\content\431960\1546098341\preview.jpg" alt="" /></a>
</li>
<li>
<a href="javascript:;"><img src="D:\steam\steamapps\workshop\content\431960\875617215\preview.jpg" alt="" /></a>
</li>
<li>
<a href="javascript:;"><img src="D:\steam\steamapps\workshop\content\431960\2542550955\preview.jpg" alt="" /></a>
</li>
<li>
<a href="javascript:;"><img src="D:\steam\steamapps\workshop\content\431960\2533685650\preview.jpg" alt="" /></a>
</li>
</ul>
<ul class="circle">
<li class="current"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div class="link">
<a href="javascript:;" class="left"> < </a>
<a href="javascript:;" class="right"> > </a>
</div>
</div>
<script>
var arrow_left = document.querySelector('.link .left');
var arrow_right = document.querySelector('.link .right');
var timer = null;
var ul = document.querySelector('.box .list');
var box = document.querySelector('.box');
var circle_list = document.querySelectorAll('.circle li');
var is_move = false;
box.onmouseenter = function() {
arrow_left.style.opacity = .6;
arrow_right.style.opacity = .6;
clearInterval(auto_timer);
}
box.onmouseleave = function() {
arrow_left.style.opacity = 0;
arrow_right.style.opacity = 0;
Auto_Move();
}
var auto_timer = null;
function Auto_Move() {
auto_timer = setInterval(function() {
Move(true);
},2000)
}
Auto_Move();
for(var i = 0; i < circle_list.length; i++) {
circle_list[i].index = i;
circle_list[i].onclick = function() {
var img_move = (this.index + 1) * -500
Move(img_move);
}
}
function Move(flag) {
if(is_move) {
return;
}
is_move = true;
var startX = ul.offsetLeft;
var move_dis;
if(typeof flag == 'boolean') {
if(flag) {
move_dis = -500;
} else {
move_dis = 500;
}
} else {
move_dis = flag - startX;
}
var lastX = startX + move_dis;
var allTime = 500;
var stepTime = 25;
var step_num = allTime / stepTime;
timer = setInterval(function() {
var startX = ul.offsetLeft;
var step = move_dis / step_num;
var endX = startX + step;
if(endX == lastX) {
clearInterval(timer);
is_move = false;
if(endX == -3000) {
endX = -500;
} else if(endX == 0) {
endX = -2500;
}
}
ul.style.left = endX + 'px';
},stepTime);
var index = lastX / -500 - 1;
if(index > 4) {
index = 0;
} else if(index < 0) {
index = 4;
}
for(var i = 0; i < circle_list.length; i++) {
circle_list[i].className = '';
}
circle_list[index].className = 'current';
}
arrow_left.onclick = function() {
Move(false);
}
arrow_right.onclick = function() {
Move(true);
}
</script>
</body>
</html>
3. 切片轮播图
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>1</title>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
body {
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
background: radial-gradient(circle at top, #444, #000);
}
.main {
display: flex;
-webkit-box-reflect: below 13px linear-gradient(transparent 70%,rgba(0,0,0,0.2));
}
.box {
width: 900px;
height: 500px;
background-size: cover;
transition: all 0.5s;
}
.box img {
width: 900px;
height: 500px;
}
.main .content {
height: 500px;
}
.main .content ul {
display: flex;
height: 100%;
flex-direction: column;
justify-content: space-between;
}
.content ul li {
width: 150px;
height: 90px;
}
.content ul li:hover img {
opacity: 0;
transform: translateX(-150px);
}
.content li .current {
opacity: 0;
transform: translateX(-150px);
}
.content ul img {
width: 100%;
height: 100%;
transition: all 0.5s;
}
</style>
</head>
<body>
<div class="main">
<div class="box"></div>
<div class="content">
<ul>
<li><img src="./img/5-img/bg0.webp" alt="" /></li>
<li><img src="./img/5-img/bg1.webp" alt="" /></li>
<li><img src="./img/5-img/bg2.webp" alt="" /></li>
<li><img src="./img/5-img/bg3.webp" alt="" /></li>
<li><img src="./img/5-img/bg4.webp" alt="" /></li>
</ul>
</div>
</div>
<script>
var list = document.querySelectorAll(".main .content li");
var img = document.querySelectorAll('img');
var box = document.querySelector(".main .box");
var main = document.querySelector(".main");
var timer = null;
var num = 1;
box.style.backgroundImage = "url(./img/5-img/bg0.webp)";
function Reset() {
img.forEach((item,index) => img[index].className = '');
}
list.forEach((item, index) => {
item.addEventListener("mouseenter", function () {
Reset();
box.style.backgroundImage = "url(./img/5-img/bg" + index + ".webp)";
num = index + 1;
});
});
function Auto_Play() {
timer = setInterval(function () {
if (num > 4) {
num = 0;
}
Reset();
img[num].className = 'current';
box.style.backgroundImage = "url(./img/5-img/bg" + num + ".webp)";
num++;
}, 1600);
}
Auto_Play();
main.addEventListener("mouseenter", function () {
clearInterval(timer);
});
main.addEventListener("mouseleave", function () {
Auto_Play();
});
</script>
</body>
</html>
3. event兼容性
event = event || window.event ( window.event 低级浏览器 )
event.target = event.target || event.srcElement ( 低级浏览器 )
4. flag
定义 flag 为布尔值是因为布尔类型内存占用少(相较于数字 0 / 1)
5. 自定义对象的迭代器
let s1 = Symbol('one');
let s2 = Symbol('two');
let obj = {
name:'ling',
age:16,
[s1]:'老王',
[s2]:'老李'
}
Object.prototype[Symbol.iterator] = function() {
let arr = Object.keys(this);
let array = Object.getOwnPropertySymbols(this);
let allArr = [...arr,...array];
let index = 0;
return {
next:() => {
return {
value:[allArr[index],this[allArr[index]]],
done:index++ >= allArr.length
}
}
}
}
for(let [key,val] of obj) {
console.log(key,val);
}
6.自定义 Swiper (vue 轮播图)
需要下载 npm i vue-swiper 插件
在 main.js 引入注册插件
import { SwiperSlide, Swiper } from 'vue-awesome-swiper';
import 'swiper/css/swiper.min.css';
Vue.component('Swiper', Swiper);
Vue.component('SwiperSlide', SwiperSlide);
<!--banner轮播-->
<Swiper :options="options" ref="swiper">
<SwiperSlide v-for="(banner, index) in bannerArr" :key="banner.id">
<img :src="banner.imgUrl" alt="">
</SwiperSlide>
<div class="swiper-pagination" slot="pagination"></div>
<div class="swiper-button-prev" slot="button-prev"></div>
<div class="swiper-button-next" slot="button-next"></div>
</Swiper>
配置
options: {
//控制轮播图方向
direction: "horizontal",
//导航按钮
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
//自动切换
autoplay: {
delay: 2000,
stopOnLastSlide: false,
disableOnInteraction: true,
},
//无缝滚动轮播
loop: true,
//分页器
pagination: {
el: ".swiper-pagination",
clickable: true,
},
},
鼠标移入轮播图暂停
let el = this.$refs.swiper.$el;
el.onmouseenter = () => this.$refs.swiper.$swiper.autoplay.stop();
el.onmouseleave = () => this.$refs.swiper.$swiper.autoplay.start();
7. 自定义分页器
<template>
<div class="pagination">
<button :disabled="StartEnd.start==1" @click="$emit('getCurrent', current - 1)">上一页</button>
<button v-show="StartEnd.start > 1" @click="$emit('getCurrent', 1)">1</button>
<button v-show="StartEnd.start > 2">···</button>
<button v-for="(page, index) in StartEnd.end" v-if="page >= StartEnd.start" :key="index" :class="{'active': page==current}" @click="$emit('getCurrent', page)">{{page}}</button>
<button v-show="StartEnd.end < totalPage - 1">···</button>
<button v-show="StartEnd.end < totalPage" @click="$emit('getCurrent', totalPage)">{{totalPage}}</button>
<button :disabled="StartEnd.end==totalPage" @click="$emit('getCurrent', current + 1)">下一页</button>
<select v-model="size" @change="$emit('getLimit', size)">
<option value="3">3/页</option>
<option value="5">5/页</option>
<option value="7">7/页</option>
<option value="9">9/页</option>
</select>
<button style="margin-left: 30px">共 {{ total }} 条</button>
</div>
</template>
<script>
export default {
name: "Pagination",
props: ['current', 'limit', 'pageCount', 'total'],
data() {
return {
size: 3
}
},
computed: {
totalPage() {
return Math.ceil(this.total / this.limit);
},
StartEnd() {
let start = 0, end = 0;
let {pageCount, totalPage, current} = this;
if(pageCount > totalPage) {
start = 1;
end = totalPage;
}else {
start = current - Math.floor(pageCount / 2);
end = current + Math.floor(pageCount / 2);
if(start < 1) {
start = 1;
end = pageCount;
}
if(end > totalPage) {
end = totalPage;
start = totalPage - pageCount + 1;
}
}
return {start, end}
}
}
}
</script>
<style lang="less" scoped>
.pagination {
button {
margin: 0 5px;
background-color: #f4f4f5;
color: #606266;
outline: none;
border-radius: 2px;
padding: 0 4px;
vertical-align: top;
display: inline-block;
font-size: 13px;
min-width: 35.5px;
height: 28px;
line-height: 28px;
cursor: pointer;
box-sizing: border-box;
text-align: center;
border: 0;
&[disabled] {
color: #c0c4cc;
cursor: not-allowed;
}
&.active {
cursor: not-allowed;
background-color: #409eff;
color: #fff;
}
}
}
</style>
8.XLSX实现导出Excel
需要先 npm i xlsx
import * as XLSX from 'xlsx';
let worksheet = XLSX.utils.json_to_sheet(record.value); // 将JSON数据,生成单元格数据
let workBook = XLSX.utils.book_new(); // 创建excel容器
// 设置单元格标题
XLSX.utils.sheet_add_aoa(worksheet, [["序号", "品牌名称", "品牌LOGO"]], {
origin: "A1",
});
// 将数据追加到excel容器中准备导出
XLSX.utils.book_append_sheet(workBook, worksheet);
// 导出excel
XLSX.writeFile(workBook, "aaa.xlsx");
9. 按钮权限自定义指令
首先在小仓库发登录请求时,把按钮权限存一下
// utils 文件创建一个 directive.ts 文件,用于存储自定义指令,使用时在 main.js 引入,并传入app
// elSvg(app), 这种形式,使用时 v-has='' 后面的值为 mounted 中的 options.value
import { useUserInfoStore } from "@/stores/userInfo";
import pinia from '@/stores';
let userStore = useUserInfoStore(pinia);
export default function(app: any) {
app.directive('has', { // 自定义指令的名字
mounted(element: any, options: any) { // element为元素
// options.value 为 自定义指令 v-has 后面的值
if(!userStore.buttons.includes(options.value)) { // 判断小仓库权限是否包含
element.parentNode.removeChild(element);
}
}
})
}