Vue.js入门 0x9 组件(Component)(6)Demo——标签页组件

vue

    标签页(即选项卡切换组件)是网页布局中经常用到的元素,常用于平级区域大块内容的收纳和展现

• index.html 入口页

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>标签页组件</title>

<link rel="stylesheet" type="text/css" href="style.css">

</head>

<body>

<div id="app" v-cloak>

<tabs v-model="activeKey">

<pane label="标签一" name="1">

标签一的内容

</pane>

<pane label="标签二" name="2">

标签二的内容

</pane>

<pane label="标签三" name="3">

标签三的内容

</pane>

</tabs>

</div>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>

<script src="pane.js"></script>

<script src="tabs.js"></script>

<script type="text/javascript">

var app = new Vue({

el:'#app',

data:{

activeKey:'1'

}

})

</script>

</body>

</html>

• style.css 样式表

[v-cloak] {

display: none;

}

.tabs {

font-size: 14px;

color: #657180;

}

.tabs-bar:after{

content: '';

display: block;

width: 100%;

height: 1px;

background: #d7dde4;

margin-top: -1px;

}

.tabs-tab{

display: inline-block;

padding: 4px 16px;

margin-right: 6px;

background: #fff;

border: 1px solid #d7dde4;

cursor: pointer;

position: relative;

}

.tabs-tab-active{

color: #3399ff;

border-top: 1px solid #3399ff;

border-bottom: 1px solid #fff;

}

.tabs-tab-active:before{

content: '';

display: block;

height: 1px;

background: #3399ff;

position: absolute;

top: 0;

left: 0;

right: 0;

}

.tabs-content{

padding: 8px 0;

}

• tabs.js 标签页外层的组件 tabs

Vue.component('tabs',{

/**

* 当点击到pane对应的标签页标题按钮时 ,

* 此pane的show值设置为true,否则应该是false

*/

template:'\

<div class="tabs">\

<div class="tabs-bar">\

<!--标签页标题,这里用v-for-->\

<div class="tabs-bar">\

<div \

:class="tabCls(item)"\

v-for="(item,index) in navList"\

@click="handleChange(index)">\

{{item.label}}\

</div>\

</div>\

</div>\

<div class="tabs-content">\

<!--这里的slot就是嵌套的pane-->\

<slot></slot>\

</div>\

</div>',

props:{

//这里value是为了可以使用v-model

value:{

type:[String,Number]

}

},

data:function(){

return {

//用于渲染tabs标题

//因为不能修改value,所以复制一份自己维护

currentValue:this.value,

navList:[]

}

},

methods:{

tabCls:function(item){

return [

'tabs-tab',

{

'tabs-tab-active':item.name === this.currentValue

}

]

},

getTabs(){

//遍历子组件,得到所有的pane组件

return this.$children.filter(function(item){

return item.$options.name === 'pane';

});

},

updateNav(){

this.navList = [];

//设置对this的引用,在function回调里,this指的并不是Vue实例

var _this = this;

//遍历提取label和name

this.getTabs().forEach(function(pane,index){

_this.navList.push({

label:pane.label,

name:pane.name||index

});

//如果没有给pane设置name,默认设置他的索引

if(!pane.name) pane.name = index;

//设置当前选中的tab索引

if(index===0){

if(!_this.currentValue){

_this.currentValue = pane.name||index;

}

}

});

this.updateStatus();

},

updateStatus(){

var tabs = this.getTabs();

var _this = this;

//显示当前选中的tab对应的pane组件,隐藏没有选中的

tabs.forEach(function(tab){

return tab.show = tab.name === _this.currentValue;

})

},

handleChange:function(index){

var nav = this.navList[index];

var name = nav.name;

this.currentValue = name;

this.$emit('input',name);

this.$emit('on-click',name);

}

},

watch:{

value:function(val){

this.currentValue = val;

},

currentValue:function(){

this.updateStatus();

}

}

})

• pane. 标签页嵌套的组件 pane 

Vue.component('pane',{

name:'pane',

//设置data:show,并且用v-show指令来控制元素

template:'\

<div class="pane" v-show="show">\

<slot></slot>\

</div>',

data:function(){

return {

show :true

}

},

props:{

name:{

type:String

},

label:{

type:String,

default:''

}

},

/**

* prop: label 用户是可以动态调整的,所以在 pane 初始化

* 及 label 更新时,都要通知父组件也更新,因为是独立组件,

* 所以不能依赖像 bus.js 或Vuex 这样的状态管理办法,我们

* 可以直接通过 this.$parent 访问 tabs 组件的实例来调用

* 它的方法更新标题,该方法名暂定为 updateNav。

*/

methods:{

updateNav(){

this.$parent.updateNav();

}

},

watch:{

label(){

this.updateNav();

}

},

/**

* 在生命周期 mounted,也就是 pane 初始化时,调用一遍

* tabs 的 updateNav 方法,同时监昕了prop: label,在

* label 更新时,同样调用 。

*/

mounted(){

this.updateNav();

}

})

以上是 Vue.js入门 0x9 组件(Component)(6)Demo——标签页组件 的全部内容, 来源链接: utcz.com/z/376625.html

回到顶部