对于那些不需要路由的内部组件,在切换的时候希望增加一个轮播过渡的效果,效果如下:
创新互联是一家专业提供漳县企业网站建设,专注与网站制作、成都做网站、HTML5、小程序制作等业务。10年已为漳县众多企业、政府机构等服务。创新互联专业网站设计公司优惠进行中。

我们可以引入一个轮播组件,但是有个问题,通常轮播组件都会把所有的slide都渲染出来再进行切换,这样就导致所有的资源都会触发加载,这可能不是我们所期待的,毕竟如果slide比较多的情况需要一次性加载的图片等资源太多了。所以我们可以手动简单地写一个,满足需求即可。
现在一步步来实现这个功能,先写一个实现基本切换的demo.
1. 实现切换
先用vue-cli搭建一个工程脚手架,使用以下命令:
npm install -g vue-cli
vue init webpack slide-demo # 运行后router等都选择no
这样就搭了一个webpack + vue的工程,进入slide-demo目录,查看src/App.vue,这个文件是初始化工具提供的,是整个页面的组件。还有一个src/components目录,这个是放子组件的目录。
在这个目录里面新建3个组件:task-1.vue、task-2.vue、task-3.vue,然后在App.vue里面import进来,如下App.vue所示:
我们的数据格式questions是这样的:
[{index: 1, type: 1, content: ''}, {index: 2, type: 1, content: ''},
{index: 3, type: 2, content: ''}, {index: 4, type: 3, content: ''}]
它是一个数组,数组里的每个元素代表每道题,每道题都有一个类型,如选择题、填空题、判断题等,分别对应上面的task-1、task-2、task-3,我们用一个currentIndex变量表示当前是在哪道题,初始化为0,如下代码所示(添加到App.vue里面):
data() {
return {
currentIndex: 0
};
},
created() {
// 请求question数据
this.questions = [
{index: 1, type: 1, question: ''}, /*...*/];
},通过改变currentIndex的值,从而切到一下题即下一个组件,要怎么实现这个切换的效果呢?
可以使用Vue自定义的一个全局组件component,给合它的is属性,达到动态改变组件的目的,如下代码所示:
当currentIndex增加时,就会改变:is里面的值,依次从task-1变到task-2、task-3等,这样component就会换成相应的task组件。
接着,再添加一个切换到下一题的按钮,在这个按钮的响应函数里面改变currentIndex的值。同时把question的数据传给component:
响应函数nextQuestion实现如下:
methods: {
nextQuestion() {
this.currentIndex = (this.currentIndex + 1)
% this.questions.length;
}
},具体每个task的实现参考如task-1.vue示例:
{{question.index}}. 选择题
{{content}}
最后的效果如下(加上题目内容):

2. 添加轮播切换效果
轮播切换通常是把所有的slide都拼起来,拼成一张长长的横图,然后改变这个横图在显示容器里面的位置,如老牌jQuery插件flipsnap.js,它是把所有的slide都float: left,形成一张长图,然后 改变这张长图的translate值,达到切换的目的。这个插件的缺点是没有办法从最后一张切回第一张,解决这个问题的方法之一是不断地移动DOM:每次切的时候都把第一张移到最后一张的后面,这样就实现了最后一张点下一张的时候回到第一张的目的,但是这样移来移去地对性能消耗比较大,不是很优雅。另外一个轮播插件jssor slider,它也是把所有的slide都渲染出来,然后每次切换的时候都 动态地计算每张slide的translate的值,而不是整体长图的位置,这样就不用移动DOM节点,相对较为优雅。还有很多Vue的轮播插件的实现也是类似上面提到的方式。
不管怎么样,上面的轮播模式都不太适用于我们的场景,其中一个是这种答题的场景不需要切回上一题,每道题做完就不能回去了,更重要的一个是我们 不希望一次性把所有的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%),如下代码所示:
上面代码把具有.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的奇偶性切换。
如下代码所示:
基本
文件
流程
错误
SQL
调试
- 请求信息 : 2026-05-28 02:28:23 HTTP/1.1 GET : /article/iiiosg.html
- 运行时间 : 1.9028s ( Load:0.0021s Init:0.0011s Exec:1.8863s Template:0.0133s )
- 吞吐率 : 0.53req/s
- 内存开销 : 513.89 kb
- 查询信息 : 12 queries 5 writes
- 文件加载 : 36
- 缓存信息 : 0 gets 0 writes
- 配置加载 : 130
- 会话信息 : SESSION_ID=1m69asjgqt3077mh9klkp4g8d3
- /home/wwwroot/bluegullmediac/wwwroot/index.php ( 1.09 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/ThinkPHP.php ( 4.61 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Think.class.php ( 12.26 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Storage.class.php ( 1.37 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Storage/Driver/File.class.php ( 3.52 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Mode/common.php ( 2.82 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Common/functions.php ( 53.56 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Hook.class.php ( 4.01 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/App.class.php ( 13.49 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Dispatcher.class.php ( 14.79 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Route.class.php ( 13.36 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Controller.class.php ( 11.23 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/View.class.php ( 7.59 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Behavior/BuildLiteBehavior.class.php ( 3.68 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Behavior/ParseTemplateBehavior.class.php ( 3.88 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Behavior/ContentReplaceBehavior.class.php ( 1.91 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Conf/convention.php ( 11.15 KB )
- /home/wwwroot/bluegullmediac/wwwroot/App/Common/Conf/config.php ( 2.16 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Lang/zh-cn.php ( 2.55 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Conf/debug.php ( 1.49 KB )
- /home/wwwroot/bluegullmediac/wwwroot/App/Home/Conf/config.php ( 0.31 KB )
- /home/wwwroot/bluegullmediac/wwwroot/App/Home/Common/function.php ( 3.33 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Behavior/ReadHtmlCacheBehavior.class.php ( 5.62 KB )
- /home/wwwroot/bluegullmediac/wwwroot/App/Home/Controller/ArticleController.class.php ( 6.02 KB )
- /home/wwwroot/bluegullmediac/wwwroot/App/Home/Controller/CommController.class.php ( 1.60 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Model.class.php ( 60.11 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Db.class.php ( 32.43 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Db/Driver/Pdo.class.php ( 16.74 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Cache.class.php ( 3.83 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Cache/Driver/File.class.php ( 5.87 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Template.class.php ( 28.16 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Template/TagLib/Cx.class.php ( 22.40 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Template/TagLib.class.php ( 9.16 KB )
- /home/wwwroot/bluegullmediac/wwwroot/App/Runtime/Cache/Home/7540f392f42b28b481b30614275e4e55.php ( 18.20 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Behavior/WriteHtmlCacheBehavior.class.php ( 0.97 KB )
- /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Behavior/ShowPageTraceBehavior.class.php ( 5.24 KB )
- [ app_init ] --START--
- Run Behavior\BuildLiteBehavior [ RunTime:0.000016s ]
- [ app_init ] --END-- [ RunTime:0.000081s ]
- [ app_begin ] --START--
- Run Behavior\ReadHtmlCacheBehavior [ RunTime:0.000113s ]
- [ app_begin ] --END-- [ RunTime:0.000163s ]
- [ view_parse ] --START--
- [ template_filter ] --START--
- Run Behavior\ContentReplaceBehavior [ RunTime:0.000186s ]
- [ template_filter ] --END-- [ RunTime:0.000250s ]
- Run Behavior\ParseTemplateBehavior [ RunTime:0.012011s ]
- [ view_parse ] --END-- [ RunTime:0.012088s ]
- [ view_filter ] --START--
- Run Behavior\WriteHtmlCacheBehavior [ RunTime:0.000192s ]
- [ view_filter ] --END-- [ RunTime:0.000235s ]
- [ app_end ] --START--
- 1064:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') LIMIT 1' at line 1
[ SQL语句 ] : SELECT `id`,`pid`,`navname` FROM `cx_nav` WHERE ( id= ) LIMIT 1
- 1064:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') LIMIT 1' at line 1
[ SQL语句 ] : SELECT `id`,`navname` FROM `cx_nav` WHERE ( id= ) LIMIT 1
- 1064:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
[ SQL语句 ] : SELECT `id`,`navname` FROM `cx_nav` WHERE ( pid= )
- [8] Undefined index: pid /home/wwwroot/bluegullmediac/wwwroot/App/Home/Controller/ArticleController.class.php 第 47 行.
- [8] Undefined index: db_host /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Db.class.php 第 120 行.
- [8] Undefined index: db_port /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Db.class.php 第 121 行.
- [8] Undefined index: db_name /home/wwwroot/bluegullmediac/wwwroot/ThinkPHP/Library/Think/Db.class.php 第 122 行.

1.9028s
