详解使用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 相关文章推荐
javascript编程起步(第四课)
Feb 27 Javascript
jQeury淡入淡出需要注意的问题
Sep 08 Javascript
Eclipse配置Javascript开发环境图文教程
Jan 29 Javascript
javascript跨域方法、原理以及出现问题解决方法(详解)
Aug 06 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
Jun 02 Javascript
BootStrap使用popover插件实现鼠标经过显示并保持显示框
Jun 23 Javascript
layer.open关闭父窗口 以及调用父页面的方法
Aug 17 Javascript
vue+webpack中配置ESLint
Nov 07 Javascript
微信小程序实现图片滚动效果示例
Dec 05 Javascript
Vue.js结合bootstrap前端实现分页和排序效果
Dec 29 Javascript
Centos7 安装Node.js10以上版本的方法步骤
Oct 15 Javascript
JS实现简易留言板增删功能
Feb 08 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
基于PHPExcel的常用方法总结
2013/06/13 PHP
Bootstrap+PHP实现多图上传功能实例详解
2018/04/08 PHP
PhpStorm本地断点调试的方法步骤
2018/05/21 PHP
2020最新版 PhpStudy V8.1版本下载安装使用详解
2020/10/30 PHP
Jquery知识点三 jquery表单对象操作
2011/01/17 Javascript
JS的框架Polymer中的dom-if和is属性使用说明
2015/07/29 Javascript
jquery+ajax+text文本框实现智能提示完整实例
2016/07/09 Javascript
javascript数组常用方法汇总
2016/09/10 Javascript
通过网页查看JS源码中汉字显示乱码的解决方法
2016/10/26 Javascript
easyui tree带checkbox实现单选的简单实例
2016/11/07 Javascript
TypeScript入门-基本数据类型
2017/03/28 Javascript
ionic3 懒加载
2017/08/16 Javascript
从parcel.js打包出错到选择nvm的全部过程
2018/01/23 Javascript
ES6关于Promise的用法详解
2018/05/07 Javascript
Vue触发隐藏input file的方法实例详解
2019/08/14 Javascript
vue quill editor 使用富文本添加上传音频功能
2020/01/14 Javascript
JavaScript如何判断input数据类型
2020/02/06 Javascript
python网络编程之UDP通信实例(含服务器端、客户端、UDP广播例子)
2014/04/25 Python
python opencv人脸检测提取及保存方法
2018/08/03 Python
Python设计模式之迭代器模式原理与用法实例分析
2019/01/10 Python
Python整数与Numpy数据溢出问题解决
2019/09/11 Python
python实现字典嵌套列表取值
2019/12/16 Python
使用python快速实现不同机器间文件夹共享方式
2019/12/22 Python
Python实现在Windows平台修改文件属性
2020/03/05 Python
Python中SQLite如何使用
2020/05/27 Python
PyTorch安装与基本使用详解
2020/08/31 Python
python爬取招聘要求等信息实例
2020/11/20 Python
关于CSS Tooltips(鼠标经过时显示)的效果
2013/04/10 HTML / CSS
JBL英国官网:JBL UK
2018/07/04 全球购物
幼儿园义卖活动方案
2014/01/17 职场文书
公司会计主管岗位责任制
2014/03/01 职场文书
自我检讨书怎么写
2015/05/07 职场文书
Java 在线考试云平台的实现
2021/11/23 Java/Android
springboot应用服务启动事件的监听实现
2022/04/06 Java/Android
Python按顺序遍历并读取文件夹中文件
2022/04/29 Python
利用Apache Common将java对象池化的问题
2022/06/16 Servers