在写html的过程中,我们经常会遇到要写tabs的切换,类似于这样:
在vue中,我们也有自己的组件和属性来实现这样的效果,这个东西我们叫做动态组件。
html:
<h3>动态组件</h3> <!-- 定义三个temp模板,用于切换 --> <template id="temp-tab01"> <div>this is tab01</div> </template> <template id="temp-tab02"> <div>this is tab02</div> </template> <template id="temp-tab03"> <div>this is tab03</div> </template> <div id="dr01"> <!-- 导航栏 --> <div class="border cf"> <ul> <li><a href="javascript:void(0);" @click="toggleTabs(tab01Text);">{{tab01Text}}</a></li> <li><a href="javascript:void(0);" @click="toggleTabs(tab02Text);">{{tab02Text}}</a></li> <li><a href="javascript:void(0);" @click="toggleTabs(tab03Text);">{{tab03Text}}</a></li> </ul> </div> <!-- 点击导航后要切换的内容 --> <div class="border" style="height: 100px;"> <!-- 如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数 --> <component :is="currentView" keep-alive></component> </div> </div>
js:
//扩展组件tab01 var tab01 = Vue.extend({ template: "#temp-tab01", }); //扩展组件tab02 var tab02 = Vue.extend({ template: "#temp-tab02", }); //扩展组件tab03 var tab03 = Vue.extend({ template: "#temp-tab03", }); //新建vue实例 var dr01 = new Vue({ el: "#dr01", data: { tab01Text: "tab01", //导航栏文本1 tab02Text: "tab02", //导航栏文本2 tab03Text: "tab03", //导航栏文本3 currentView: 'tab01', //默认选中的导航栏 }, //局部注册组件 components: { tab01: tab01, tab02: tab02, tab03: tab03, }, methods: { //绑定tab的切换事件 toggleTabs: function(tabText) { this.currentView = tabText; } } });
步骤解释:
1、在html中定义三个template模板
2、在js中通过Vue.extend()中指定扩展组件的模板,在vue实例中局部注册三个组件
3、html中在要切换tab的地方通过<component :is="currentView" keep-alive></component>来动态切换成我们要显示的组件
"currentView":是要展示的模板的名称。
"keep-alive":如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数。
4、在li中添加点击事件toggleTabs,将vm的currentView切换为要显示的模板的名称即可。
结果:
#过渡效果
为了让切换的时候过渡效果(后面我会讲下vue的过渡效果,用css3来写)平滑自然,我们需要在component上添加transition-mode属性
在这里我们将component标签添加两个属性transition和transition-mode
<component :is="currentView" transition="fade" transition-mode="out-in" keep-alive></component>
然后定义css样式:
.fade-transition {
transition: opacity .3s ease;
}
.fade-enter,
.fade-leave {
opacity: 0;
}
这样就可以了,我们看下后面的效果: