详解使用vue实现tab 切换操作


Posted in Javascript onJuly 03, 2017

在使用jQuery类库实现tab功能时,是获取鼠标在mousenter或click时的index值,然后切换到当前的标题和内容,把其他的标题和内容的状态去掉:

$('.tab .title').find('.item')
 .removeClass('current').eq(index).addClass('current'); // 为index位置的title添加current
$('.tab .content').find('.item')
 .hide().eq(index).show(); // 显示index位置的内容

那么在使用vue实现tab功能时,就不是像jQuery这种直接操作DOM了。我这里总结了下实现tab功能的3个思路,仅供参考。

1. 切换content或者直接切换内容

这种思路下,我们首先把结构搭建起来,然后用一个变量selected表示tab当前展示的位置,给li标签添加mouseenter或click事件,将当前的index传递进去:

html代码:

<div class="hd">
 <ul class="clearfix">
  <li v-for="(item, index) of list" :class="{active:selected==index}" @mouseenter="change(index)">{{item.title}}</li>
 </ul>
</div>
<div v-for="(item, index) of list" :class="{active:selected==index, item:true}" v-html="item.content"></div>

js代码:

var app = new Vue({
 el: '#app',
 data: {
  selected: 0, //当前位置
  list: [
   {
    title: '11111',
    content: '11111content'
   },
   {
    title: '22222',
    content: '222222content'
   },
   {
    title: '33333',
    content: `<div>
        <span style="color:#f00">hello world</span>
        <p><input type="text" v-model="message"></p>
        <p>{{message}}</p>
       </div>`
   }
  ]
 },
 methods: {
  change(index) {
   this.selected = index;
  }
 }
})

绑定的change(index)事件,每次都将index给了selected,然后tab就会切换到对应的标签。

上面的代码里,我们是通过切换div的显示与隐藏来进行执行的。tab中的content里如果只有纯html内容,我们可以直接把list[selected].content展示到.bd中:

<div class='bd' v-html="list[selected].content"></div>

每次selected变换时,bd的内容都会发生变化。

2. 使用currentView

在上面的实现方式中,第3个tab里有个输入框与p标签双向绑定,但是没有效果,因为vue是把list中的内容作为html元素填充到页面中的,message并没有作为vue的属性绑定给input。那么使用组建和currentView就能弥补这个缺陷。

无论使用全局注册还是局部注册的组件,思路都是一样的,我们暂时使用全局注册的组件来实现。

每个组件里展示的是一个tab里的内容,先注册3个组件:

// tab0
Vue.component('item0',{
 template : '<div>1111111content</div>'
});
// tab1
Vue.component('item1',{
 template : '<div>222222content</div>'
})
// tab2
Vue.component('item2',{
 data(){
  return{
   message : ''
  }
 },
 template : `<div>
     <span style="color:#f00">hello world</span>
     <p><input type="text" v-model="message"></p>
     <p>{{message}}</p>
    </div>`
})

然后在html中使用component来展示对应组件的内容,title的展示方式不变:

<div class="hd">
 <ul class="clearfix">
  <li v-for="(item, index) of list" :class="{active:selected==index}" @mouseenter="change(index)">{{item.title}}</li>
 </ul>
</div>
<component :is="currentView"></component>

currentView属性可以让多个组件可以使用同一个挂载点,并动态切换:

var app = new Vue({
 el: '#app',
 data: {
  selected: 0,
  currentView : 'item0',
  list: [
   {
    title: '11111'
   },
   {
    title: '22222'
   },
   {
    title: '33333'
   }
  ]
 },
 methods: {
  change(index) {
   this.selected = index;
   this.currentView = 'item'+index; // 切换currentView
  }
 }
})

这样 message 在组件里就是一个独立的data属性,能在tab里也使用vue绑定事件了.

3. 使用slot方式等

使用slot方式进行内容分发或者一个独立的组件,可以让我们把代码整合到一块,对外提供一个数据接口,只要按照既定的格式填写数据即可。

3.1 slot

用slot方式写一个子组件:

Vue.component('my-slot-tab', {
 props : ['list', 'selected'],
 template : `<div class="tab">
     <div class="hd">
      <ul class="clearfix">
       <slot name="title" v-for="(item, index) in list" :index="index" :text="item.title"> </slot>
      </ul>
     </div>
     <div class="bd">
      <slot name="content" :content="list[selected].content"></slot>
     </div>
    </div>`
});

父组件模板:

<my-slot-tab :list="list" :selected="selected">
 <template slot="title" scope="props">
  <li :class="{active:selected==props.index, item:true}" @mouseenter="change(props.index)">{{ props.text }}</li>
 </template>
 <template slot="content" scope="props">
  <div v-html="props.content"></div>
 </template>
</my-slot-tab>

父组件中slot="title"会替换子组件中name="title"的slot,父组件中slot="content"会替换子组件中name="content"的slot.最终渲染出来的tab结构与上面之前的代码一样。

3.2 其他组件方式

还有一种方式就是把所有的模板都写到组件中。

子组件:

Vue.component('my-tab', {
 props : ['list'],
 template : `<div class="tab">
     <div class="hd">
      <ul class="clearfix">
       <li v-for="(item, index) in list" :class="{active:selected==index, item:true}" @mouseenter="change(index)">{{item.title}}</li>
      </ul>
     </div>
     <div class="bd">
      <div v-for="(item, index) of list" :class="{active:selected==index, item:true}" v-html="item.content"></div>
     </div>
    </div>`,
 data(){
  return{
   selected:0
  }
 },
 methods : {
  change(index){
   this.selected = index;
  }
 }
});

父组件:

<my-tab :list="list"></my-tab>

 这种只需要传递一个list即可。

对比这两种方法,slot中可以自定义更多的内容,而下面的方法使用起来更加简单,只是自定义的东西比较少。

4. 总结

上面讲解了几种实现tab功能的方式,没有说哪种方式最好,选择最适合自己项目需求的方式就是最好的。文中有哪有错误或不足,欢迎批评指正。也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery之Document元素选择器篇
Aug 14 Javascript
JS判断是否为数字,是否为整数,是否为浮点数的代码
Apr 24 Javascript
使用jQuery和PHP实现类似360功能开关效果
Feb 12 Javascript
浅谈jquery.fn.extend与jquery.extend区别
Jul 13 Javascript
跟我学习javascript的arguments对象
Nov 16 Javascript
基于jquery实现即时检查格式是否正确的表单
May 06 Javascript
js实现精确到毫秒的倒计时效果
Aug 05 Javascript
基于jQuery实现中英文切换导航条效果
Sep 18 Javascript
BootStrap的双日历时间控件使用
Jul 25 Javascript
浅析node.js的模块加载机制
May 25 Javascript
Node绑定全局TraceID的实现方法
Nov 14 Javascript
详解React的回调渲染模式
Sep 10 Javascript
关于jQuery.ajax()的jsonp碰上post详解
Jul 02 #jQuery
Angular4项目中添加i18n国际化插件ngx-translate的步骤详解
Jul 02 #Javascript
React学习笔记之事件处理(二)
Jul 02 #Javascript
React学习笔记之条件渲染(一)
Jul 02 #Javascript
vue.js学习之vue-cli定制脚手架详解
Jul 02 #Javascript
如何通过非数字与字符的方式实现PHP WebShell详解
Jul 02 #Javascript
关于使用axios的一些心得技巧分享
Jul 02 #Javascript
You might like
PHP递归调用的小技巧讲解
2013/02/19 PHP
通过table标签,PHP输出EXCEL的实现方法
2013/07/24 PHP
浅析虚拟主机服务器php fsockopen函数被禁用的解决办法
2013/08/07 PHP
PHP从二维数组得到N层分类树的实现代码
2016/10/11 PHP
WHOOPS PHP调试库的使用
2017/09/29 PHP
wordpress自定义标签云与随机获取标签的方法详解
2019/03/22 PHP
JavaScript 大数据相加的问题
2011/08/03 Javascript
使用jQuery实现的掷色子游戏动画效果
2014/03/14 Javascript
javascript:window.open弹出窗口的位置问题
2014/03/18 Javascript
JavaScript定义类和对象的方法
2014/11/26 Javascript
javascript获取四位数字或者字母的随机数
2015/01/09 Javascript
kindeditor编辑器点中图片滚动条往上顶的bug
2015/07/05 Javascript
JavaScript观察者模式(经典)
2015/12/09 Javascript
JS验证图片格式和大小并预览的简单实例
2016/10/11 Javascript
jQuery autoComplete插件两种使用方式及动态改变参数值的方法详解
2016/10/24 Javascript
jquery获取table指定行和列的数据方法(当前选中行、列)
2016/11/07 Javascript
element-ui组件table实现自定义筛选功能的示例代码
2019/03/15 Javascript
微信小程序之滑动页面隐藏和显示组件功能的实现代码
2020/06/19 Javascript
微信小程序实现音乐播放页面布局
2020/12/11 Javascript
vue3.0 项目搭建和使用流程
2021/03/04 Vue.js
python 中的列表解析和生成表达式
2011/03/10 Python
对python GUI实现完美进度条的示例详解
2018/12/13 Python
python 日期排序的实例代码
2019/07/11 Python
Django框架视图介绍与使用详解
2019/07/18 Python
pymysql 开启调试模式的实现
2019/09/24 Python
python实现程序重启和系统重启方式
2020/04/16 Python
Python如何设置指定窗口为前台活动窗口
2020/08/12 Python
基于Python的接口自动化unittest测试框架和ddt数据驱动详解
2021/01/27 Python
HTML5中通过li-canvas轻松实现单图、多图、圆角图绘制,单行文字、多行文字等
2018/11/30 HTML / CSS
简单整理HTML5的基本特性和语法
2016/02/18 HTML / CSS
HTML5跳转小程序wx-open-launch-weapp的示例代码
2020/07/16 HTML / CSS
2014年学生会主席工作总结
2014/11/07 职场文书
2016年公司中秋节致辞
2015/11/26 职场文书
Nginx Rewrite使用场景及配置方法解析
2021/04/01 Servers
python 使用tkinter与messagebox写界面和弹窗
2022/03/20 Python
MySQL 原理与优化之Update 优化
2022/08/14 MySQL