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 相关文章推荐
用js实现手把手教你月入万刀(转贴)
Nov 07 Javascript
Mootools 1.2教程 正则表达式
Sep 15 Javascript
jQuery与其它库冲突的解决方法
Jun 25 Javascript
JS合并数组的几种方法及优劣比较
Sep 19 Javascript
JavaScript判断IE版本型号
Jul 27 Javascript
JavaScript实现定时隐藏与显示图片的方法
Aug 06 Javascript
Bootstrap选项卡动态切换效果
Nov 28 Javascript
jQuery和CSS仿京东仿淘宝列表导航菜单
Jan 04 Javascript
微信小程序去哪里找 小程序到底如何使用(附小程序名单)
Jan 09 Javascript
JavaScript下拉菜单功能实例代码
Mar 01 Javascript
jQuery 改变P标签文本值方法
Feb 24 jQuery
Vuex中mutations与actions的区别详解
Mar 01 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使用post数组的键值创建同名变量并赋值的方法
2015/04/03 PHP
PHP随机数 C扩展随机数
2016/05/04 PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
2020/02/27 PHP
用Js实现的动态增加表格示例自己写的
2013/10/21 Javascript
js调用后台、后台调用前台等方法总结
2014/04/17 Javascript
Javascript实现字数统计
2015/07/03 Javascript
深入解读JavaScript中的Hoisting机制
2015/08/12 Javascript
bootstrap datetimepicker实现秒钟选择下拉框
2017/01/05 Javascript
深入理解基于vue-cli的vuex配置
2017/07/24 Javascript
一种angular的方法级的缓存注解(装饰器)
2018/03/13 Javascript
Angularjs实现页面模板清除的方法
2018/07/20 Javascript
Vue 中如何正确引入第三方模块的方法步骤
2019/05/05 Javascript
ES6 Symbol数据类型的应用实例分析
2019/06/26 Javascript
Jquery ajax书写方法代码实例解析
2020/06/12 jQuery
JS实现悬浮球只在一侧滑动并且是横屏状态下
2020/08/19 Javascript
Web服务器框架 Tornado简介
2014/07/16 Python
Phantomjs抓取渲染JS后的网页(Python代码)
2016/05/13 Python
使用Python脚本实现批量网站存活检测遇到问题及解决方法
2016/10/11 Python
Python 网页解析HTMLParse的实例详解
2017/08/10 Python
python opencv之分水岭算法示例
2018/02/24 Python
详解Python的hasattr() getattr() setattr() 函数使用方法
2018/07/09 Python
Python中对数组集进行按行打乱shuffle的方法
2018/11/08 Python
Python程序包的构建和发布过程示例详解
2019/06/09 Python
Python完成哈夫曼树编码过程及原理详解
2019/07/29 Python
对Pytorch中nn.ModuleList 和 nn.Sequential详解
2019/08/18 Python
Python django框架开发发布会签到系统(web开发)
2020/02/12 Python
Python查找不限层级Json数据中某个key或者value的路径方式
2020/02/27 Python
OpenCV 之按位运算举例解析
2020/06/19 Python
使用keras实现BiLSTM+CNN+CRF文字标记NER
2020/06/29 Python
css3加js做一个简单的3D行星运转效果实例代码
2017/01/18 HTML / CSS
门诊挂号室室长岗位职责
2013/11/27 职场文书
汽车运用工程专业毕业生推荐信
2013/12/25 职场文书
现场施工员岗位职责
2014/03/10 职场文书
马云北大演讲完整版:真心话,什么才是阿里的核心竞争力?
2014/04/04 职场文书
基于Apache Hudi在Google云构建数据湖平台的思路详解
2022/04/07 Servers
postgreSQL数据库基础知识介绍
2022/04/12 PostgreSQL