Упражнение по разработке компонентов Vue — переключение карт фокуса

JavaScript Vue.js

1. Введение

Vue используется некоторое время, и разработанная система управления фоном также становится все более и более совершенной.Сейчас время относительно простаивает! В это свободное время я изучаю некоторые другие возможности Vue, такие как компоненты, плагины и т. д. Сегодня я поделюсь практическим проектом компонента — компонентом переключения карт фокуса. Этот проект я использую для практики компонентов vue.Конечно, код также будет отправлен на github (ec-slider), также будет сохранен. Я также думаю, что то, что я разработал, проще в использовании! Теперь я предлагаю нуждающимся партнерам прийти и сыграть в этот проект в качестве практики! Кроме того, если у вас есть какие-либо предложения, добро пожаловать, чтобы дать указатели!

предложение
1. Для следующих шагов лучше запускать их локально, и выполнять их шаг за шагом в соответствии с шагами статьи.Если вы только посмотрите на код, то легко запутаться.
2. Если вы не знаете, какой код что делает, вы можете отладить его самостоятельно, удалить код и посмотреть, какой эффект он дает, и легко понять, что делает код!

2. Каталог проекта

Очень распространенный, хорошо понятный каталог, но позвольте мне кратко объяснить его

node_modules: модуль файловых зависимостей (создается автоматически)
dist:Каталог вывода файла пакета (создается автоматически)
src: Каталог файлов разработки
src/components: Каталог файлов компонентов
.babelrc:babel компилирует файлы конфигурации es6
.gitnore: файлы конфигурации для файлов (каталогов), не зафиксированных в git
fontSize: Установить файл алгоритма rem (сейчас не используется, игнорировать)
index.html: файл шаблона
index.js: входной файл
package.json:файл конфигурации
README.md: Документация
webpack.config.babel.js: файл конфигурации веб-пакета

3. Подробные шаги

3-1 разбег

Это первый шаг проекта (проект создает это, я не буду много говорить, предыдущая статья уже говорила это несколько раз!), Сейчасsrc/components/ec-slider.vueЭто выводит «ожидание»
1. Во-первых, вsrc/components/ec-slider.vueОн выводит «ожидание», код выглядит следующим образом

<template>
    <div>
        守候
    </div>
</template>
<script type="text/javascript">
    export default {
        data () {
            return {

            }
        },
        computed: {

        },
        mounted(){

        },
        props: [],
        methods: {

        }
    }
</script>

2. Затем вsrc/components/index.jsУстановите компонент регистрации внутри (методом установки), код выглядит следующим образом

import SlideImg from './ec-slider.vue'
const ecslide={
    install:function (Vue) {
        Vue.component('ec-slide',SlideImg)
    }
}
export default ecslide;

3. Введите и используйте компоненты в файле ввода, index.js

require("./index.html");
require("./src/sass/index.scss");
import Vue from 'vue'
//引入并且使用组件
import ecslide from './src/js/components/index';
Vue.use(ecslide);
let app6 = new Vue({
    el: "#app6",
    data: {

    },
    mounted(){
        
    }

});

4. В Index.html (файл шаблона) выходной компонент

<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
        <title>Title</title>
    </head>
    <body>
    <div id="app6">
        <ec-slide></ec-slide>
    </div>
    </body>
</html>  

5. Ввод командной строки$ npm run devБеги, получилось идеально! Принципы этих шагов, кажется, ни о чем не говорят, все они являются фиксированными шагами.

3-2 Подготовка к разработке

После предыдущего шага заложена основа, затем следующий шаг — процесс разработки, большая часть которого — модификации.src/components/ec-slider.vueэтот файл.
Перед разработкой не спешите писать код, сначала проанализируйте запущенный процесс!
Во-первых, какие параметры нужны для переключения карты фокуса? Согласно следующим каштанам Taobao, я просто проанализирую следующие!

list-список изображений[{источник:'url',href:'www.baidu.com'},{src:'url',href:'www.163.com'}] (src: src картинки, href: переход по ссылке, при нажатии на картинку)
autoplay- следует ли автоматически воспроизводить логическое значение (по умолчанию false)
type- Режим карусели «прозрачный» (переключатель прозрачности), «слайд» (ползунковый переключатель) (слайд по умолчанию)
option-Соответствующий переключатель (по умолчанию false, не отображается)
time- Интервал карусели, миллисекунд (по умолчанию 4000)
sildetype- эффекты перехода (по умолчанию «облегчение» медленного начала, затем быстрее и конец эффекта медленного перехода, ссылка:transition-timing-function)
arrowurl-стрелка ссылка на изображение
arrowsize- Размер стрелки "ширина, высота"
direction- переключить ориентацию «влево» (влево и вправо) «вверх» (вверх и вниз) (по умолчанию: влево и вправо)

После анализа я знаю, что временно нужно очень много параметров, тогда следующим шагом будетec-slider.vueВнутри получите эти параметры. Я хочу, чтобы все знали, как передавать параметры между родительским и дочерним компонентами.props. код показывает, как показано ниже

<template>
    <div>
        守候
    </div>
</template>
<script type="text/javascript">
    export default {
        data () {
            return {

            }
        },
        computed: {

        },
        mounted(){

        },
        props: ['list', 'autoplay', 'type', 'time', 'sildetype', 'arrowurl','arrowsize','option','direction'],
        methods: {

        }
    }
</script>

Если есть место для получения параметров, должно быть место и для передачи параметров, т.е.index.htmlв файле шаблона

<div class="slider-left">
    <ec-slide :list='list' :autoplay="true" :type="'slide'" :option="true" :time="4000" :sildetype="'ease'" :arrowurl="'http://i1.buimg.com/1949/4d860a3067fab23b.jpg'" :arrowsize="'20,40'" :direction="'left'"></ec-slide>
</div>    

макет 3-3 стиля

Теперь, когда вы знаете, какие параметры будут получены, давайте сначала разложим макет стиля и сначала сделаем его правильно.Ничего особенного, код выглядит следующим образом! (Некоторые пояснения я также ввел прямо в код)

<template>
    <div class="switch-img-box" id="ec-slide-box">
        <div class="switch-img-type switch-img-left">
            <ul :style="{'width':ulWidth,'transition-timing-function':slideChange}">
                <li v-for="(li,index) in list" :style="{'width':listWidth+'%'}">
                    <a :href="li.href?li.href:'javascript:;'">
                        <img :src="li.src" class="slider-img"/>
                    </a>
                </li>
            </ul>
        </div>
        <!--如果需要显示对应的点-->
        <div class="switch-option" v-if="option">
            <div>
                <span v-for="(li,index) in list"></span>
            </div>
        </div>
        <!--如果需要显示箭头-->
        <div class="switch-arrow" v-if="arrowurl&&arrowsize">
            <div :class="{'arrow-left':direction==='left','arrow-top':direction==='top'}"
                 :style="{'width':arrowWidth+'px','height':arrowHeight+'px','background':'url('+arrowurl+') no-repeat','background-size':'100%'}"></div>
            <div :class="{'arrow-right':direction==='left','arrow-bottom':direction==='top'}"
                 :style="{'width':arrowWidth+'px','height':arrowHeight+'px','background':'url('+arrowurl+') no-repeat','background-size':'100%'}"></div>
        </div>
    </div>
</template>
<script type="text/javascript">
    export default {
        data () {
            return {
                slideChange: '',
                arrowWidth: '',
                arrowHeight: '',
            }
        },
        computed: {
            //ul宽度
            ulWidth: function () {
                return (this.list.length) + "00%";

            },
            //li宽度
            listWidth: function () {
                return 100 / (this.list.length)
            }
        },
        mounted(){
            //设置各个数据初始值
            this.slideChange = this.sildetype || 'ease';
            if (this.arrowsize && this.arrowurl) {
                this.arrowWidth = this.arrowsize.split(',')[0];
                this.arrowHeight = this.arrowsize.split(',')[1];
            }
        },
        props: ['list', 'autoplay', 'type', 'time', 'sildetype', 'arrowurl', 'arrowsize', 'option', 'direction'],
        methods: {
        }
    }
</script>
<style lang="scss">
    .ec-slide-img-box {
        width: 100%;
        height: 100%;
        position: relative;
        touch-action: none;
    }

    .ec-slide-img-type {
        position: relative;
        overflow: hidden;
        width: 100%;
        height: 100%;
        &.ec-slide-img-top {
        }
        &.ec-slide-img-left {
            li {
                display: inline-block;
                font-size: 0;
            }
        }
        &.ec-slide-img-transparent {
            li {
                opacity: 0;
                transition: opacity 1s;
                width: 0;
                &.cur {
                    width: auto;
                }
                &.show {
                    opacity: 1;
                }
            }
        }
        ul {
            font-size: 0;
            &.tran {
                transition: all .4s;
            }
            li {
                text-align: center;
            }

            img {
                vertical-align: middle;
                max-width: 100%;
                max-height: 100%;
            }
        }
    }

    .ec-slide-arrow {
        div {
            position: absolute;
            z-index: 2;
            margin: auto;
            top: 0;
            bottom: 0;
            right: 0;
            left: 0;
            opacity: .5;
            &:hover {
                opacity: 1;
            }
            &.arrow-left {
                left: 10px;
                right: auto;
            }
            &.arrow-right {
                right: 10px;
                left: auto;
                transform: rotate(180deg);
            }
            &.arrow-top {
                top: 10px;
                bottom: auto;
            }
            &.arrow-bottom {
                bottom: 10px;
                top: auto;
                transform: rotate(180deg);
            }
        }
    }

    .ec-slide-option {
        position: absolute;
        font-size: 0;
        bottom: 10px;
        text-align: center;
        width: 100%;
        z-index: 5;
        &.isFirst {
            span:first-child {
                display: none;
            }
        }
        &.isLast {
            span:last-child {
                display: none;
            }
        }
        span {
            border-radius: 100%;
            margin: 0 5px;
            background: #fff;
            display: inline-block;
            width: 10px;
            height: 10px;
            &.active {
                background: #09f;
            }
        }
        &.ec-slide-option-top {
            display: table;
            width: 10px;
            height: 100%;
            top: 0;
            right: 10px;
            margin: auto;
            bottom: 0;
            span {
                margin: 5px 0;
            }
            div {
                display: table-cell;
                vertical-align: middle;
            }
        }
    }
</style> 

Результат операции следующий

3-4 Выполнить анимацию

Макет готов, и вы можете написать анимацию ниже, чтобы карусель двигалась! Здесь также необходимо добавить несколько переменных, одна из которых — nowIndex, которая записывает текущий индекс. Один таймер таймер!
Во-первых, я используюtransform:translate3d()контролировать таким образомulскользящий.

<ul :style="{'width':ulWidth,'transform':'translate3d(-'+(listWidth*(nowIndex))+'%,0,0)','transition-timing-function':slideChange,'transition': 'all .4s'}">
    <li v-for="(li,index) in list" :style="{'width':listWidth+'%'}">
        <a :href="li.href?li.href:'javascript:;'">
            <img :src="li.src" class="slider-img"/>
        </a>
    </li>
</ul>

Затем, согласно nowIndex, установить класс соответствующей точки.

<div class="switch-option" v-if="option">
    <div>
        <!--如果当前索引index等于nowIndex。则添加active这个class,点就会变成蓝色-->
        <span v-for="(li,index) in list" :class="{'active':index===nowIndex}"></span>
    </div>
</div>

js-код выглядит следующим образом

<script type="text/javascript">
    export default {
        data () {
            return {
                nowIndex: 0,
                timer: null,
                slideChange: '',
                arrowWidth: '',
                arrowHeight: '',
            }
        },
        computed: {
            //ul宽度
            ulWidth: function () {
                return (this.list.length) + "00%";

            },
            //li宽度
            listWidth: function () {
                return 100 / (this.list.length)
            }
        },
        mounted(){
            //是否自动播放
            if (this.autoplay) {
                this.autoSwitch();
            }
            //设置初始值
            this.slideChange = this.sildetype || 'ease';
            if (this.arrowsize && this.arrowurl) {
                this.arrowWidth = this.arrowsize.split(',')[0];
                this.arrowHeight = this.arrowsize.split(',')[1];
            }
        },
        props: ['list', 'autoplay', 'type', 'time', 'sildetype', 'arrowurl', 'arrowsize', 'option', 'direction'],
        methods: {
            //滑动操作
            switchDo(reduce){
                clearInterval(this.timer);
                //根据reduce判断this.nowIndex的增加或者减少!
                //如果是减少模式reduce=‘reduce’
                if (reduce === 'reduce') {
                    //如果nowIndex等于0,已经是第一个了,就回到最后一个
                    if (this.nowIndex === 0) {
                        this.nowIndex = this.list.length - 1;
                    }
                    else {
                        this.nowIndex--;
                    }
                }
                //如果是增加模式reduce=undefined
                else {
                    //如果nowIndex等于this.list.length-1,已经是最后一个了,就回到第一个
                    if (this.nowIndex === this.list.length-1) {
                        this.nowIndex = 0;
                    }
                    else{
                        this.nowIndex++;
                    }
                }
                //如果需要自动播放
                if (this.autoplay) {
                    this.autoSwitch();
                }

            },
            //自动播放函数
            autoSwitch(){
                let time = this.time || 4000;
                this.timer = setInterval(() => {
                    this.switchDo();
                }, time);
            }
        }
    }
</script>    

На этом этапе остается только нажать на две стрелки, чтобы выполнить соответствующую анимацию.Это относительно просто.Это не что иное, как вызов функции switchDo.Единственная разница в том, что нажатие на стрелку слева вызывает уменьшение режим, а стрелка справа — режим увеличения. Код выглядит следующим образом, легко понять.

<!--判断是否需要显示箭头-->
<div class="switch-arrow" v-if="arrowurl&&arrowsize">
    <div :class="{'arrow-left':direction==='left','arrow-top':direction==='top'}"
         :style="{'width':arrowWidth+'px','height':arrowHeight+'px','background':'url('+arrowurl+') no-repeat','background-size':'100%'}" @click.stop="switchDo('reduce')"></div>
    <div :class="{'arrow-right':direction==='left','arrow-bottom':direction==='top'}"
         :style="{'width':arrowWidth+'px','height':arrowHeight+'px','background':'url('+arrowurl+') no-repeat','background-size':'100%'}" @click.stop="switchDo"></div>
</div>

Вот разработчики взаимодействующие за обсессивно-компульсивное расстройство не выдерживают.На последнем кликните на стрелку вправо, появится следующая ситуация!

Когда вы дойдете до первой картинки, снова нажмите на стрелку влево — аналогичная ситуация, что очень плохо. В идеале следующее

3-5 Детальная оптимизация

Если вы хотите добиться вышеуказанного эффекта, изменений будет больше.Давайте сначала поговорим о принципе.Когда вы дойдете до последнего, в это время нажмите стрелку справа, как Taobao, чтобы вернуться к первому. Когда вы дойдете до первого, нажмите стрелку слева, чтобы вернуться к последнему. Итак, окончательный макет выглядит так

Таким образом, макет может достичь эффекта.Когда вы дойдете до последнего, в это время снова нажмите стрелку справа, как Taobao, чтобы вернуться к первому. как ниже

В это время вам нужно сделать еще один шаг, а когда вы прокрутите здесь, мгновенно оттяните его назад. И потяните это назад, чтобы сделать эффект перехода ultransitionУдалите его, или вы увидите переходный эффект оттягивания назад! Также измените файл nowIndex.

1. Во-первых, аспект макета UL

<div class="switch-img-type switch-img-left" v-if="type==='slide'&&direction==='left'">
    <!--用tran这个class控制ul是否含有过渡效果,样式已经写好-->
    <ul :style="{'width':ulWidth,'transform':'translate3d(-'+(listWidth*(nowIndex+1))+'%,0,0)','transition-timing-function':slideChange}"
        :class="{'tran':noLast}">
        <!--最后一张图片-->
        <li :style="{'width':listWidth+'%'}">
            <a :href="list[list.length-1].href?list[list.length-1].href:'javascript:;'">
                <img :src="list[list.length-1].src" class="slider-img"/>
            </a>
        </li>
        <!--遍历出来的图片-->
        <li v-for="(li,index) in list" :style="{'width':listWidth+'%'}">
            <a :href="li.href?li.href:'javascript:;'">
                <img :src="li.src" class="slider-img"/>
            </a>
        </li>
        <!--第一张图片-->
        <li :style="{'width':listWidth+'%'}">
            <a :href="list[0].href?list[0].href:'javascript:;'">
                <img :src="list[0].src" class="slider-img"/>
            </a>
        </li>
    </ul>
</div>

2. Затем соответствующая точка изменена

<!--isLast:隐藏最后一个span,isFirst隐藏第一个span-->
<div class="switch-option" v-if="option"
     :class="{'isLast':nowIndex===list.length, 'isFirst':nowIndex===-1,'switch-option-top':direction==='top'}">
    <div>
        <span class="active span1" v-if="nowIndex===list.length"></span>
        <span v-for="(li,index) in list" :class="{'active':index===nowIndex}"></span>
        <span class="active span2" v-if="nowIndex===-1"></span>
    </div>
</div>

Это может быть немного извилистым, позвольте мне объяснить, например, прокрутите последний, нажмите стрелку справа и проведите вправо до первого, как показано ниже

В это время первая точка должна снова стать синей, но индекс соответствующей точки не совпадает с nowIndex.В это время используется трюк. Показать первую точку (.span1) и скрыть последнюю точку. Таким образом, пользователь все равно видит на экране 4 точки! Когда анимация закончится, вернитесь к первому. Скрыть .span1 и нормально отображать соответствующие точки! Все это знают, если подумать. Когда вы доберетесь до первого, нажмите на стрелку слева, чтобы таким же образом вернуться к последнему!

На данный момент функция в основном завершена, и эта часть кода приведена ниже!

<template>
    <div class="ec-slide-img-box" id="ec-slide-box">
        <div class="ec-slide-img-type ec-slide-img-left" v-if="type==='slide'&&direction==='left'">
            <!--用tran这个class控制ul是否含有过渡效果,样式已经写好-->
            <ul :style="{'width':ulWidth,'transform':'translate3d(-'+(listWidth*(nowIndex+1))+'%,0,0)','transition-timing-function':slideChange}"
                :class="{'tran':noLast}">
                <!--最后一张图片-->
                <li :style="{'width':listWidth+'%'}">
                    <a :href="list[list.length-1].href?list[list.length-1].href:'javascript:;'">
                        <img :src="list[list.length-1].src" class="slider-img"/>
                    </a>
                </li>
                <!--遍历出来的图片-->
                <li v-for="(li,index) in list" :style="{'width':listWidth+'%'}">
                    <a :href="li.href?li.href:'javascript:;'">
                        <img :src="li.src" class="slider-img"/>
                    </a>
                </li>
                <!--第一张图片-->
                <li :style="{'width':listWidth+'%'}">
                    <a :href="list[0].href?list[0].href:'javascript:;'">
                        <img :src="list[0].src" class="slider-img"/>
                    </a>
                </li>
            </ul>
        </div>
        <!--isLast:隐藏最后一个span,isFirst隐藏第一个span-->
        <div class="ec-slide-option" v-if="option"
             :class="{'isLast':nowIndex===list.length, 'isFirst':nowIndex===-1,'ec-slide-option-top':direction==='top'}">
            <div>
                <span class="active" v-if="nowIndex===list.length"></span>
                <span v-for="(li,index) in list" :class="{'active':index===nowIndex}"></span>
                <span class="active" v-if="nowIndex===-1"></span>
            </div>
        </div>
        <div class="ec-slide-arrow" v-if="arrowurl&&arrowsize">
            <div :class="{'arrow-left':direction==='left','arrow-top':direction==='top'}"
                 :style="{'width':arrowWidth+'px','height':arrowHeight+'px','background':'url('+arrowurl+') no-repeat','background-size':'100%'}"
                 @click.stop="switchDo('reduce')"></div>
            <div :class="{'arrow-right':direction==='left','arrow-bottom':direction==='top'}"
                 :style="{'width':arrowWidth+'px','height':arrowHeight+'px','background':'url('+arrowurl+') no-repeat','background-size':'100%'}"
                 @click.stop="switchDo"></div>
        </div>
    </div>
</template>
<script type="text/javascript">
    export default {
        data () {
            return {
                nowIndex: 0,
                noLast: true,
                timer: null,
                slideChange: '',
                arrowWidth: '',
                arrowHeight: ''
            }
        },
        computed: {
            ulWidth: function () {
                return (this.list.length + 2) + "00%";

            },
            listWidth: function () {
                return 100 / (this.list.length + 2)
            }
        },
        mounted(){
            if (this.autoplay) {
                this.autoSwitch();
            }
            this.slideChange = this.sildetype || 'ease';
            if (this.arrowsize && this.arrowurl) {
                this.arrowWidth = this.arrowsize.split(',')[0];
                this.arrowHeight = this.arrowsize.split(',')[1];
            }
        },
        props: ['list', 'autoplay', 'type', 'time', 'sildetype', 'arrowurl', 'arrowsize', 'option', 'direction'],
        methods: {
            //滑动操作
            switchDo(reduce){
                clearInterval(this.timer);
                //根据reduce判断this.nowIndex的增加或者减少!
                if (reduce === 'reduce') {
                    if (this.nowIndex === 0) {
                        //如果是滑动切换
                        this.nowIndex--;
                        //执行完了这次动画之后,去除过渡效果
                        setTimeout(() => {
                            this.nowIndex = this.list.length - 1;
                            this.noLast = false;
                        }, 400)
                    }
                    else {
                        this.nowIndex--;
                    }
                }
                else {
                    this.nowIndex++;
                }
                if (this.nowIndex === this.list.length) {

                    //执行完了这次动画之后,去除过渡效果
                    setTimeout(() => {
                        this.nowIndex = 0;
                        this.noLast = false;
                    }, 400)

                }
                //如果需要自动播放
                if (this.autoplay) {
                    this.autoSwitch();
                }
                //如果是滑动切换,设置this.noLast,增加过渡效果
                this.noLast = true;

            },
            //自动播放函数
            autoSwitch(){
                let time = this.time || 4000;
                this.timer = setInterval(() => {
                    this.switchDo();
                }, time);
            }
        }
    }
</script>
<style lang="scss">
    .ec-slide-img-box {
        width: 100%;
        height: 100%;
        position: relative;
        touch-action: none;
    }

    .ec-slide-img-type {
        position: relative;
        overflow: hidden;
        width: 100%;
        height: 100%;
        &.ec-slide-img-top {
        }
        &.ec-slide-img-left {
            li {
                display: inline-block;
                font-size: 0;
            }
        }
        &.ec-slide-img-transparent {
            li {
                opacity: 0;
                transition: opacity 1s;
                width: 0;
                &.cur {
                    width: auto;
                }
                &.show {
                    opacity: 1;
                }
            }
        }
        ul {
            font-size: 0;
            &.tran {
                transition: all .4s;
            }
            li {
                text-align: center;
            }

            img {
                vertical-align: middle;
                max-width: 100%;
                max-height: 100%;
            }
        }
    }

    .ec-slide-arrow {
        div {
            position: absolute;
            z-index: 2;
            margin: auto;
            top: 0;
            bottom: 0;
            right: 0;
            left: 0;
            opacity: .5;
            &:hover {
                opacity: 1;
            }
            &.arrow-left {
                left: 10px;
                right: auto;
            }
            &.arrow-right {
                right: 10px;
                left: auto;
                transform: rotate(180deg);
            }
            &.arrow-top {
                top: 10px;
                bottom: auto;
            }
            &.arrow-bottom {
                bottom: 10px;
                top: auto;
                transform: rotate(180deg);
            }
        }
    }

    .ec-slide-option {
        position: absolute;
        font-size: 0;
        bottom: 10px;
        text-align: center;
        width: 100%;
        z-index: 5;
        &.isFirst {
            span:first-child {
                display: none;
            }
        }
        &.isLast {
            span:last-child {
                display: none;
            }
        }
        span {
            border-radius: 100%;
            margin: 0 5px;
            background: #fff;
            display: inline-block;
            width: 10px;
            height: 10px;
            &.active {
                background: #09f;
            }
        }
        &.ec-slide-option-top {
            display: table;
            width: 10px;
            height: 100%;
            top: 0;
            right: 10px;
            margin: auto;
            bottom: 0;
            span {
                margin: 5px 0;
            }
            div {
                display: table-cell;
                vertical-align: middle;
            }
        }
    }
</style> 
  

3-6 Другие методы переключения

Как кодовые фермеры могут быть довольны статус-кво, есть только один способ переключения, как это можно сделать, поэтому я еще немного улучшил его:

1. Способ переключения прозрачности.

2. При длине входящего списка 1 будет отображаться только картинка без анимации.

3. Обработка левого и правого скользящих событий мобильного телефона (нестандартная обработка)! Хотя у него мало функций, я могу удовлетворить его в ежедневной разработке!

4. Добавьте режим вращения вверх и вниз.



Полный код — это слишком много, и это приведет к тому, что он будет слишком длинным, поэтому я не буду публиковать его здесь, давайте пойдем на github, чтобы увидеть его!ec-slider

4. Резюме

Ну вот и все для сегодняшнего развития. Сначала я планировал использовать этот проект как практическую работу, но позже я использовал его в проекте.Хотя это относительно просто написать, эффект неплох. Нынешняя ситуация не очень хорошая, и при необходимости она сохранится и в будущем. В настоящее время также рекомендуется играть в этот проект.Хотя статья немного длинная, вы можете прочитать ее напрямую, написать код и прочитать статью, и вы ее найдете. Все кончено в мгновение ока! Это должен быть проект с хорошей практикой, вы можете быть знакомы с использованием vue для разработки компонентов! Наконец, если вы чувствуете, что с написанием что-то не так, вы можете указать!


------------------------- Великолепная разделительная линия --------------------
Хотите узнать больше, обратите внимание на мой публичный аккаунт WeChat: В ожидании книжного магазина