Vue 标签页组件

效果:

 index.html

<html>
 <head> 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
  <title>标签页组件</title>
  <style>
  [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:5px 10px;
	  border:1px solid #d7dde4;
	  margin:0 10px;
	}
	.tabs-tab-active{
	  color:#3399ff;
	  border-top:2px solid #3399ff;
	  border-bottom:1px solid #fff;
	}
	.tabs-tab-active:before{
	  content:'';
	  display: inline;
	  height:1px;
	  background:#3399ff;
	  position: absolute;
	  top:0;
	  left:0;
	  right:0;
	}
	.tabs-content{
	  padding: 8px 0;
	}
	</style>
 </head> 
 <body> 
  <div id="app" v-cloak> 
    <tabs v-model="activeKey">
	    <pane label='标签一' name="1">
	      <h1>ReactNative </h1>
	      <p>使用JavaScript和React编写原生移动应用</p>
	    </pane>
	    <pane label='标签二' name="2">
	    	<p>重磅 | iView 发布 3.0 版本,以及开发者社区等 5 款新品</p>
	    </pane>
	    <pane label='标签三' name="3">
	    	<h6>
	    		Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
	    	</h6>
	    </pane>
	  </tabs>
  </div>  
<script src = "../lib/vue.min.js" ></script> 
<script src = "pane.js" ></script> 
<script src = "tabs.js" ></script> 
<script>
var app = new Vue({
  el: '#app',
  data: {
    activeKey: '1'
  }
}) 
</script> 
 </body>
</html>

tabs.js

Vue.component('tabs',{
  name: 'pane',
  template:`
    <div class="tabs">
      <div class="tabs-bar">
        <!-- 标签页标题,这里要用 v-for -->
        <div :class='tabCls(item)' v-for="(item,index) in navList" :key='index' @click="handleChange(index)">
          {{item.label}}
        </div>
      </div>
      <div class="tabs-content">
        <!-- 这里的slot就是嵌套的pane -->
        <slot></slot>
      </div>
    </div>
  `,
  props:{
    value :{type:[String,Number]}
  },
  data(){
    return{
      //用于渲染 tabs 的标题
      navList: [],
      //因为不能修改 value,所以复制一份自己维护
      currentValue: this.value,
    }
  },
  methods:{
    tabCls(item){
      return[
        'tabs-tab',
        {
          //给当前选中的tab 加一个 class
          'tabs-tab-active': item.name === this.currentValue
        }
      ]
    },
    handleChange(index){
      var nav = this.navList[index];
      var {name} = nav;
      //改变当前选中的tab,并触发下面的 watch
      this.currentValue = name;
      //更新 value
      this.$emit('input', name);
      //触发一个自定义事件,供父级使用
      this.$emit('on-click', name);
    },
    getTabs(){
      //通过遍历子组件,得到所有的 pane 组件
      return this.$children.filter((item)=>{
        return item.$options.name === 'pane';
      })
    },
    updateNav(){
      this.navList = [];
      this.getTabs().forEach((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();
      tabs.forEach((tab)=>{
        return tab.show = tab.name === this.currentValue;
      })
    }
  },
  watch:{
    value(val){
      this.currentValue = val;
    },
    currentValue(){
      //在当前选中的 tab 发生变化时,更新pane的显示状态
      this.updateStatus();
    }
  }
})


 

pane.js 

 

Vue.component('pane',{
  name: 'pane',
  template:`
    <div class="pane" v-show="show">
      <slot></slot>
    </div>
  `,
  props:{
    name: {type: String},
    label: {type: String, default: ''}
  },
  data(){
    return{
      show: true,
    }
  },
  methods: {
    updateNav(){
      this.$parent.updateNav();
    }
  },
  watch:{
    label(){
      this.updateNav();
    }
  },
  mounted() {
    this.updateNav();
  },
})


 

Vue实现标签组件的基本思路是使用两个组件:Tabs组件和Pane组件。 Tabs组件负责渲染标签的头部,并处理标签的切换逻辑。在Tabs组件中,需要引入一个Vue文件Vuejs_actual_tabs.vue,用于渲染标签切换头。Tabs组件还可以包含一个slot,用于显示当前选中标签的内容。 Pane组件负责渲染标签的内容,并与Tabs组件进行交互。在Pane组件中,需要引入一个Vue文件Vuejs_actual_pane.vue,用于渲染标签显示内容。Pane组件还需要定义一个isShow属性,通过v-show指令来控制内容的显示或隐藏。 在交互方面,点击标签标题时,通过设置isShow属性为true来显示对应的内容。为了识别不同的标签标题,可以在Props中定义一个label属性,用于存放标题。当label值发生变化时,通过监听实现重新初始化标题。可以调用Tabs组件的初始化方法,例如使用this.$parent来调用父组件Tabs的初始化方法。 综上所述,通过Tabs组件和Pane组件的配合,可以实现一个简单的Vue标签组件。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Vue完成标签组件](https://blog.csdn.net/BiangBaing/article/details/118029240)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [说说如何在 Vue.js 中实现标签组件](https://blog.csdn.net/weixin_33708432/article/details/88011159)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值