Vue.js прави работата с различни видове анимации много лесна. Предоставя компоненти и кукички за анимиране на единични и множество елементи — Transition и Transition-Group; можете да прочетете повече за тях в официалната документация, която можете да намерите на адрес https://vuejs.org/v2/guide/transitions.html. Доста лесно е да създавате прости и дори по-сложни анимации само с помощта на CSS. Ако имате нужда от нещо по-модерно, библиотеките на трети страни могат лесно да бъдат интегрирани. За целите на този урок ще използвам TweenLiteза анимация. Преди да започнете, уверете се, че имате минимум Node.js 8.x.xинсталиран, както се изисква от vue-cli и npm.

Първо нека бързо подготвим структурата на папките и всички пакети, от които се нуждаем за приложението. Отворете своя терминал и инсталирайте най-новия vue-cli, като напишете

npm install -g @vue/cli

След като се инсталира успешно в папката, в която искате да имате вашия проект, в моя случай това е C:\Users\User\Dev. CD към него и стартирайте

vue create AnimatedList

Можете да използвате командата vue, след като инсталирате vue-cli. Ако не работи, уверете се, че сте отворили отново своя терминал. Ако все още не работи, може би PATH не е зададен правилно. Create е команда, предоставена от vue, а „AnimatedList“ е името на нашия проект. След като изпълните тази команда, ще трябва да изберете няколко опции за проекта. Тъй като това е само за създаване на анимации, нека да продължим с настройките по подразбиране (babel, eslint). Когато всичко е готово, трябва да видите нещо подобно на вашия терминал:

cd в AnimatedList и стартирайте npm run serve, за да проверите дали всичко работи.

Това е структура на папки, която вероятно вече имате. Въпреки това, може да е различно за вас, тъй като към момента на писане на този урок vue-cli 3 е в бета етап.

В терминала стартирайте „npm install –save axios gsap“. Имаме нужда от Axios за извличане на някои данни от API и GSAP, тъй като предоставя TweenLiteза анимации. Можете да прочетете повече за това, което GSAPможе да предложи на https://greensock.com/gsap. След като пакетите са инсталирани, стартирайте във вашия терминал „npm run serve“, за да стартирате сървъра за разработка.

Преименувайте файла HelloWorld.vue на AnimatedList.vue и променете съдържанието му, така че да има само основен шаблон за единичния файлов компонент.

Сега трябва да коригираме файла App.vue, тъй като той все още се опитва да импортира и използва компонент HelloWorld.vue, който вече не съществува. Променете импортирането от „импортиране на HelloWorld от ‘./components/HelloWorld.vue’” на „импортиране на AnimatedList от ‘./components/AnimatedList.vue’”. Актуализирайте свойството на компонентите до AnimatedList, както и компонента в шаблона. Също така премахнете логото на Vue от шаблона. Вашият файл App.vue сега трябва да изглежда така:

Приключихме с изчистването на файловете, така че първо нека вземем някои данни за списъка, който искаме да анимираме. В AnimatedList.vue преди „export default“ добавете „импортиране на axios от „axios“ и след това създайте нов екземпляр на axios.

Ще използваме API на starwars, за да получим някои данни.

Ако сте на локален хост, може да имате проблеми с CORS. В този случай просто инсталирайте приставка за браузър като MOESIFв Chrome.

Добавете свойството „хора“ към данните, които трябва да бъдат масив. Ние ще съхраняваме нашия списък там. Освен това имаме нужда от currentPage, loadingDataфлаг и animatingфлаг, които ще използваме по-късно.

След това създаваме метод за извличане на хора от звездни войни. Добавете свойството на методи към експортирания обект и създайте метод „getPeople“, който ще приеме „page“ като параметър. По подразбиране трябва да е 1 и да връща обект с данни.

Както вероятно сте забелязали, използвам тук const, async/await и параметри по подразбиране, които са налични в новите стандарти на EcmaScript. Ако трябва да поддържате по-стари браузъри, уверете се, че използвате нещо като babel за транспилиране на вашия код в ES5. Освен това, от ES6, ако свойството на обекта има същото име като стойността, вместо да пишете { страница: страница }, можете просто да напишете { страница }.

Сега нека добавим кука created(), в която ще извикаме getPeople() и ще обработим резултата. API на swapi ще върне обект, който ще има свойства за брой, следващ, предишен и резултати. Ние обаче се интересуваме само от резултати и броене. С деструктурирането можем лесно да получим резултати и да преброим и да им присвоим константи. След това актуализираме собствеността на хората. Това ще доведе до повторно изобразяване на списък, който скоро ще добавим. Също така трябва да съхраним максимален брой страници за пагинацията. Максималният брой страници няма да се промени и следователно не е необходимо да бъде реактивен. Трябва да съхраним и дължината на масива, но също така не трябва да е реактивен. Статичните свойства обикновено се съхраняват в $options prop. Освен това трябва да включваме и изключваме loadingData, така че бутоните за страниране да са деактивирани, докато данните се извличат.

Имаме данни за показване, така че е време да добавим малко html и CSS.

Над тага ‹script› добавете този код:

Тук добавяме бутони за пагиниране, за да актуализираме нашия списък. Бутоните трябва да бъдат деактивирани, ако данните се зареждат или ако currentPageе 1 или равно на maxPages. „v-for“ е директива, предлагана от Vue.js за преминаване през данни. Преминаваме през масива хора и показваме името на човека. Не забравяйте, че v-for изисква предаването на уникален атрибут :key. По-късно ще използваме data-index за забавяне на всеки елемент от списъка.

Под тага ‹/script› добавете малко стил за бутони и списък.

Само не забравяйте, че елементите от списъка трябва да имат „position: relative“, за да можем по-късно да анимираме тяхното свойство „left“. Сега трябва да добавим метод changePage, тъй като Vue компилаторът ще изведе грешка. В changePageще проверим дали предадената страница не е по-малка от 1 или по-голяма от maxPages. Ако е, тогава ще го променим на 1 или на maxPages. След проверката ще извикаме updateList(page) и ще предадем pageкато параметър. В updateListще извлечем повече хора и ще актуализираме масива people и currentPage.

Имаме списък и пагинация. Сега е време най-накрая да добавим някои анимации, така че нека импортираме TweenLite в нашия файл.

„импорт { TweenLite } от ‘gsap’”

Също така трябва да обвием нашия списък с компонент ‹Transition-Group›, за да можем да използваме системата за преход и куките, предоставени от Vue.js.

Също така трябва да добавим методи за всяка кука.

В beforeEnterhook задаваме opacityна 0 и leftсвойство на 50%, за да преместим елемента от неговата позиция. Включваме и анимационенфлаг, който скоро ще ни трябва.

В enterhook получаваме закъснениеномер въз основа на индексана елемента. Колкото по-голям е индексът, толкова по-дълго е забавянето. По този начин гарантираме, че елементите няма да започнат да се появяват едновременно, а по-скоро един след друг. TweenLiteприема елементза анимиране като първи параметър, продължителностна анимацията като втори параметър и допълнителни опции като трети параметър. В опциипредаваме реквизити за свойствата на елемента, които искаме да анимираме. onCompleteще задейства обратно извикване, след като анимацията приключи.

В afterEnterhook ние просто изключваме animatingфлаг

Ако опресните браузъра сега, ще видите, че списъкът ни се плъзга добре отдясно наляво. Също така трябва да добавим код към leavehooks, така че когато променим елементите от списъка на страниците да се плъзгат.

Включете флага за анимиране в beforeLeaveкука

Leavehook е основно същото като enterhook освен стойностите, предадени на TweenLite за opacityи leftсвойството.

Последното нещо, което трябва да направите, е да добавите код към afterLeavehook, в който задаваме animatingфлаг на false.

Най-накрая нашият списък се плъзга навътре и навън. Има обаче проблем, когато извличаме нов набор от данни, който принуждава повторно изобразяване и задейства нова анимация, за да започне, преди текущата да е приключила. Ето защо се нуждаем от флаг „анимиране“. Добавете ново свойство към обекта с данни, наречено peopleToUpdate. Ето как трябва да изглежда вашият обект с данни сега.

Сега променете функцията updateList, така че когато получи резултати, да провери дали анимацията не е в ход. Ако не е, тогава трябва да присвои резултати на свойството „people“, в противен случай на „peopleToUpdate“?. Обърнете внимание, че актуализираме peopleLengthсамо когато анимацията не е в ход в тази функция. Правим го по този начин, защото анимацията зависи от дължината на предишния масив, така че все още не можем да го отменим, в случай че е бил различен.

Това обаче не е всичко. Нуждаем се също от начин да актуализираме хората с нови данни, когато анимацията приключи. Можем да инициализираме функция, след като последният елемент напусне, за да проверим дали има данни за актуализиране, но нека използваме свойство за наблюдение на екземпляр на Vue. Ще наблюдаваме свойството „animating“ и ще правим нещо само когато анимацията е изключена и ако имаме някакви данни за актуализиране. Освен актуализиране на свойството people и задействане на нова анимация, ние също актуализираме peopleLengthс нова дължина.

Това е последното нещо, от което се нуждаехме, за да завършим създаването на разместена анимация за списъка. Има различни начини за създаване на анимации като тази, има и много подобрения, които могат да бъдат направени в този код, например преместване на компонента за преходна група с неговите методи към друг компонент и след това просто предаване на елементи от списък в слот. Това обаче е нещо, което можете да направите сами за практика. Можете да намерите този проект в моето репо в Github на адрес https://github.com/DeraIeS/AnimatedList. Надявам се, че ви е харесало четенето на този урок. Можете да намерите работещ проект на тази връзка: http://animated-list.tkwebdev.co.uk/