zoukankan      html  css  js  c++  java
  • vue手写轮播

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    #app {
    1200px;
    height: 500px;
    border: 1px solid red;
    margin: 50px auto;
    }

    .swiper {
    100%;
    height: 100%;
    position: relative;
    overflow: hidden;
    }

    .item {
    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 {
    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 {
    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;
    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动画轮播

  • 相关阅读:
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
  • 原文地址:https://www.cnblogs.com/QQPrincekin/p/12022746.html
Copyright © 2011-2022 走看看