Vue makes component carousel switching effect

php中世界最好的语言
Release: 2018-06-11 10:20:55
Original
1314 people have browsed it

This time I will bring you the effect of using Vue to make component carousel switching. What are the precautions for using Vue to make component carousel switching. The following is a practical case, let's take a look.

For those internal components that do not require routing, we hope to add a carousel transition effect when switching. The effect is as follows:

We can introduce a Carousel component, but there is a problem. Usually the carousel component will render all the slides and then switch them, which will cause all resources to trigger loading. This may not be what we expect, after all, if there are many slides There are too many images and other resources that need to be loaded at once. So we can simply write one manually to meet the needs.

Now let’s implement this function step by step. First, write a demo to implement basic switching.

1. Implement switching

First use vue-cli To build a project scaffolding, use the following command:

npm install -g vue-cli vue init webpack slide-demo # 运行后router等都选择no
Copy after login

In this way, a webpack vue project is set up. Enter the slide-demo directory and view src/App.vue. This file is provided by the initialization tool and is the entire page. s component. There is also a src/components directory, which is the directory where subcomponents are placed.

Create three new components in this directory: task-1.vue, task-2.vue, task-3.vue, and then import them in App.vue, as shown in App.vue below:

Copy after login

Our data format questions is like this:

[{index: 1, type: 1, content: ''}, {index: 2, type: 1, content : ''},
{index: 3, type: 2, content: ''}, {index: 4, type: 3, content: ''}]

It is a Array, each element in the array represents each question, and each question has a type, such as multiple choice questions, fill-in-the-blank questions, judgment questions, etc., which correspond to the above task-1, task-2, and task-3 respectively. We use A currentIndex variable indicates which question we are currently on, initialized to 0, as shown in the following code (added to App.vue):

data() { return { currentIndex: 0 }; }, created() { // 请求question数据 this.questions = [ {index: 1, type: 1, question: ''}, /*...*/]; },
Copy after login

By changing the value of currentIndex, we can switch to the next question, which is the next component. , how to achieve this switching effect?

You can use a global component component customized by Vue and combine it with its is attribute to achieve the purpose of dynamically changing the component, as shown in the following code:

Copy after login

When currentIndex increases, it will Change the value in: is from task-1 to task-2, task-3, etc., so that the component will be replaced with the corresponding task component.

Then, add a button to switch to the next question, and change the value of currentIndex in the response function of this button. At the same time, pass the question data to the component:

Copy after login

The response function nextQuestion is implemented as follows:

methods: { nextQuestion() { this.currentIndex = (this.currentIndex + 1) % this.questions.length; } },
Copy after login

The specific implementation reference of each task is such as task-1.vue example:

 
Copy after login

The final effect is as follows (plus title content):

2. Add carousel switching effect

Carousel switching is normal It is to put all the slides together to form a long horizontal picture, and then change the position of the horizontal picture in the display container, such as the old jQuery plug-in flipsnap.js, which is to float: left all the slides to form a long picture. , and thenchange the translate valueof this long picture to achieve the purpose of switching. The disadvantage of this plug-in is that there is no way to switch from the last picture back to the first picture. One way to solve this problem is to constantly move the DOM: every time you switch, move the first picture behind the last picture, so that This achieves the purpose of returning to the first picture when clicking the next one on the last one, but moving it back and forth in this way consumes a lot of performance and is not very elegant. Another carousel plug-in, jssor slider, also renders all slides, and thendynamically calculates the translate value of each slideevery time it is switched, instead of the position of the overall long image. This eliminates the need to move DOM nodes, which is relatively elegant. There are also many Vue carousel plug-ins implemented in a similar way as mentioned above.

不管怎么样,上面的轮播模式都不太适用于我们的场景,其中一个是这种答题的场景不需要切回上一题,每道题做完就不能回去了,更重要的一个是我们不希望一次性把所有的slide都渲染出来,这样会导致每张幻灯片里的资源都触发加载,就比如img标签虽然你把它display: none了,但是只要它的src是一个正常的url,它就会请求加载。 由于slide往往会比较多,就不使用这种轮播插件了。

还可以使用Vue自带的transition,但是transition的问题是,切下一个的时候,上一个不见了,因为被销毁了,只有下一个的动画,并且不能预加载下一个slide的资源。

所以我们手动实现一个。

我的想法是每次都准备两个slide,第1个slide是当前展示用的,第2个slide拼在它的后面,准备切过来,当第2个slide切过来之后,删掉第1个slide,然后在第2个的后面再接第3个slide,不断地重复这个过程。如果我们没有使用Vue,而是自己增删DOM,那么没什么问题,可以很任性地自己发挥。使用Vue可以怎么优雅地实现这个功能呢

在上面一个component的基础上,再添加一个component,刚开始第1个component是当前展示的,而第2个component是拼在它右边的,当第2个切过去之后,就把第1个移到第2的后面,同时把内容改成第3个slide的内容,依此类推。使用Vue不太好动态地改DOM,但是可以借助jssor slider的思想,不移动DOM,只是改变component的translate的值。

给其中一个component套一个next-task的类,具有这个类的组件就表示它是下一张要出现的,它需要translateX(100%),如下代码所示:

 
Copy after login

上面代码把具有.next-task类的component隐藏了,这样是做个优化,因为display: none的元素只会构建DOM,不会进行layout和render渲染。

所以就把问题转换成怎么在这两个component之间,切换next-task的类。一开始next-task是在第2个,当第2个切过来之后,next-task变成加在第1个上面,这样轮流交替。

进而,发现一个规律,如果currentIndex是偶数话,如o、2、4…,那么next-task是加在第2个component的,而如果currentIndex是奇数,则next-task是加在第1个component的。所以可以根据currentIndex的奇偶性切换。

如下代码所示: