Vue.js组件实现选项卡以及切换特效


Posted in Javascript onJuly 24, 2019

Vue.js组件实现选项卡以及切换动画特效,供大家参考,具体内容如下

最近在学习Vue,当看梁灏大神写的《Vue.js实战》时看到了关于用组件实现选项卡功能,我也根据课后的练习加上自己的理解重新编写了一下。

组件分为pane.jstabs.js两个部分,话不多说,直接上代码。

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <link rel="stylesheet" href="style.css" rel="external nofollow" >
 <title>Document</title>
</head>

<body>
 <div id="app">
  <tabs v-model="activeKey">
   //transiton是Vue自带封装的,不懂的同学可以去找文档,主要是可以实现动画
   <transition name="slide-fade"> 
    <pane label="标签一" name="1">
     标签一的内容
    </pane>
   </transition>
   <transition name="slide-fade">
    <pane label=" 标签二" name="2">
     标签二的内容
    </pane>
   </transition>
   <transition name="slide-fade">
    <pane label="标签三" name="3">
     标签三的内容
    </pane>
   </transition>

  </tabs>
 </div>


 <script src="vue/vue.js"></script>
 <script src="pane.js"></script>
 <script src="tabs.js"></script>
 <script src="text.js"></script>
</body>

</html>
//tabs.js
Vue.component('tabs', {
 template: `
 <div class="tabs">
  <div class="tabs-bar">
  <div :class="tabCls(item)" v-for="(item, index) in navList" @click="handleChange(index)">
   {{item.label}}
  </div>
  <button @click="removePane()"> 关闭/打开 </button>
  </div>

  <div class="tabs-content">
    <slot></slot> 
  </div>
 </div>
 `,
 props: {
  value: {
   type: [String, Number],
  },
 },
 data: function () {
  return {
   currentValue: this.value,
   navList: [],
  };
 },
 methods: {
  tabCls: function (item) {
   return [
    'tabs-tab',
    {
     'tabs-tab-active': item.name === this.currentValue,
    },
   ];
  },
  getTabs() {
   return this.$children.filter(function (item) {
    return item.$options.name === 'pane';
   });
  },
  updateNav() {
   this.navList = [];
   var _this = this;

   this.getTabs().forEach(function (pane, index) {
    _this.navList.push({
     label: pane.label,
     name: pane.name || index,
     bool: pane.closable,
    });
    if (!pane.name) pane.name = index;
    if (index === 0) {
     if (!_this.currentValue) {
      _this.currentValue = pane.name || index;
     }
    }
   });
   this.updateStatus();
  },
  updateStatus() {
   var tabs = this.getTabs();
   var _this = this;
   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);
  },
  removePane: function () {
   var bool = this.navList[1].bool;
   console.log(bool);
   if (bool) {
    this.navList[1].bool = false;
    this.currentValue = '0';
   }
   if (!bool) {
    this.navList[1].bool = true;
    this.currentValue = '1';
    this.$emit('input', '1');
   }
  },
 },
 watch: {
  value: function (val) {
   this.currentValue = val;
  },
  currentValue: function () {
   console.log('demo');
   this.updateStatus();
  },
 },
});
//pane.js
Vue.component('pane', {
 name: 'pane',
 template: `
 <div class="pane" v-if="show">
  <slot> </slot>
 </div>
 `,
 props: {
  name: {
   type: String
  },
  label: {
   type: String,
   default: ''
  },
  closable: {
   type: Boolean,
   default: true
  }
 },

 data: function () {
  return {
   show: true
  }
 },
 methods: {
  updateNav() {
   this.$parent.updateNav();
  }
 },
 watch: {
  label() {
   this.updateNav();
  }
 },
 mounted() {
  this.updateNav();
 }
})
//style.css
.tabs {
 font-size: 14px;
 color: black;
}

.tabs-bar:after {
 content: '';
 display: block;
 width: 100%;
 height: 1px;
 position: relative;
 background: rgba(78, 81, 128, 0.5);
}

.tabs-tab {
 display: inline-block;
 padding: 4px 16px;
 margin-right: 6px;
 color: rgba(0, 0, 0, 0.6);
 background: rgba(134, 134, 131, 0.137);
 border: 1px solid rgba(154, 214, 248, 0.856);
 cursor: pointer;
 position: relative;
}

.tabs-tab-active {
 background: rgb(252, 251, 251);
 color: rgba(0, 0, 0, 1);
 border-top: 1px solid rgba(154, 214, 248, 0.856);
 border-bottom: 1px solid white;
}

/* .tabs-tab-active:before {
 content: '';
 display: block;
 height: 5px;
 background: grey;
 position: absolute;
 top: 0;
 left: 0;
 right: 0;
} */

.tabs-content {
 position: relative;
 left: 10px;
 top: 30px;
 padding: 8px 0;
}

/* 可以设置不同的进入和离开动画 */
/* 设置持续时间和动画函数 */
.slide-fade-enter-active {
 transition: all 1.3s ease;
}

.slide-fade-leave-active {
 transition: all 1.8s cubic-bezier(1, 0.5, 0.8, 1);
}

.slide-fade-enter,
.slide-fade-leave-to

/* .slide-fade-leave-active for below version 2.1.8 */
 {
 transform: translateY(30px);
 opacity: 0;
}
//text.js
var app = new Vue({
 el: '#app',
 data: {
  activeKey: '1',
 },
})

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
取选中的radio的值
Jan 11 Javascript
js常用排序实现代码
Dec 28 Javascript
深入理解JavaScript系列(12) 变量对象(Variable Object)
Jan 16 Javascript
Firefox下无法正常显示年份的解决方法
Sep 04 Javascript
canvas时钟效果
Feb 16 Javascript
JS中cookie的使用及缺点讲解
May 13 Javascript
js轮播图无缝滚动效果
Jun 17 Javascript
JS的函数调用栈stack size的计算方法
Jun 24 Javascript
JavaScript函数apply()和call()用法与异同分析
Aug 10 Javascript
JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【圆形情况】
Dec 13 Javascript
layui动态渲染生成左侧3级菜单的方法(根据后台返回数据)
Sep 23 Javascript
p5.js实现简单货车运动动画
Oct 23 Javascript
javascript中call,apply,callee,caller用法实例分析
Jul 24 #Javascript
javascript关于“时间”的一次探索
Jul 24 #Javascript
javascript面向对象三大特征之封装实例详解
Jul 24 #Javascript
解决vue-cli webpack打包开启Gzip 报错问题
Jul 24 #Javascript
Vue  webpack 项目自动打包压缩成zip文件的方法
Jul 24 #Javascript
JavaScript面向对象中接口实现方法详解
Jul 24 #Javascript
IE11下处理Promise及Vue的单项数据流问题
Jul 24 #Javascript
You might like
在php中判断一个请求是ajax请求还是普通请求的方法
2011/06/28 PHP
php实现文件下载代码分享
2014/08/19 PHP
Zend Framework实现多文件上传功能实例
2016/03/21 PHP
详谈PHP面向对象中常用的关键字和魔术方法
2017/02/04 PHP
PHP实现合并两个排序链表的方法
2018/01/19 PHP
laravel 之 Eloquent 模型修改器和序列化示例
2019/10/17 PHP
基于jquery的划词搜索实现(备忘)
2010/09/14 Javascript
jquery zTree异步加载简单实例分享
2013/02/05 Javascript
js图片闪动特效可以控制间隔时间如几分钟闪动一下
2014/08/12 Javascript
JavaScript html5 canvas绘制时钟效果
2016/03/01 Javascript
AnjularJS中$scope和$rootScope的区别小结
2016/09/18 Javascript
Mac中安装nvm的教程分享
2017/12/11 Javascript
vue中使用vee-validator完成表单校验方案
2019/11/01 Javascript
jQuery实现鼠标拖动图片功能
2021/03/04 jQuery
[03:28]2014DOTA2国际邀请赛 EG战队官方纪录片
2014/07/21 DOTA
Python 抓取动态网页内容方案详解
2014/12/25 Python
详解常用查找数据结构及算法(Python实现)
2016/12/09 Python
python 读写中文json的实例详解
2017/10/29 Python
Python DataFrame 设置输出不显示index(索引)值的方法
2018/06/07 Python
Python爬取商家联系电话以及各种数据的方法
2018/11/10 Python
解决PyCharm的Python.exe已经停止工作的问题
2018/11/29 Python
使用Python 统计高频字数的方法
2019/01/31 Python
python Tkinter的图片刷新实例
2019/06/14 Python
PyTorch实现更新部分网络,其他不更新
2019/12/31 Python
pytorch逐元素比较tensor大小实例
2020/01/03 Python
Python实现钉钉订阅消息功能
2020/01/14 Python
Python图像处理库PIL中图像格式转换的实现
2020/02/26 Python
CSS3实战第一波 让我们尽情的圆角吧
2010/08/27 HTML / CSS
利用CSS3参考手册和CSS3代码生成工具加速来学习网页制
2012/07/11 HTML / CSS
墨尔本照明批发商店:Mica Lighting
2017/12/28 全球购物
MCAKE蛋糕官方网站:一直都是巴黎的味道
2018/02/06 全球购物
土木工程建筑专业毕业生求职信
2013/10/21 职场文书
公司员工检讨书
2014/02/08 职场文书
幼儿生日活动方案
2014/08/27 职场文书
工程合作意向书范本
2015/05/09 职场文书
人民调解协议书
2016/03/21 职场文书