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 相关文章推荐
自己整理的一个javascript日期处理函数
Oct 16 Javascript
JS实现动态给图片添加边框的方法
Apr 01 Javascript
Backbone.js框架中简单的View视图编写学习笔记
Feb 14 Javascript
一系列Bootstrap导航条使用方法分享
Apr 29 Javascript
第一次接触神奇的Bootstrap菜单和导航
Aug 01 Javascript
浅析jsopn跨域请求原理及cors(跨域资源共享)的完美解决方法
Feb 06 Javascript
JS实现向iframe中表单传值的方法
Mar 24 Javascript
简单实现js鼠标跟随效果
Aug 02 Javascript
JS实现TITLE悬停长久显示效果完整示例
Feb 11 Javascript
vue实现的多页面项目如何优化打包的步骤详解
Jul 19 Javascript
基于vue实现微博三方登录流程解析
Nov 04 Javascript
教你一步步实现一个简易promise
Nov 02 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 已经成熟
2006/12/04 PHP
php文件服务实现虚拟挂载其他目录示例
2014/04/17 PHP
PHP获取某个月最大天数(最后一天)的方法
2015/07/29 PHP
Zend Framework教程之Zend_Registry对象用法分析
2016/03/22 PHP
PHP中Socket连接及读写数据超时问题分析
2016/07/19 PHP
Laravel构建即时应用的一种实现方法详解
2017/08/31 PHP
纯CSS3实现质感细腻丝滑按钮
2021/03/09 HTML / CSS
用Javascript评估用户输入密码的强度实现代码
2011/11/30 Javascript
struts2+jquery组合验证注册用户是否存在
2014/04/30 Javascript
jQuery中attr()和prop()在修改checked属性时的区别
2014/07/18 Javascript
JavaScript动态插入CSS的方法
2015/12/10 Javascript
JavaScript中关联原型链属性特性
2016/02/13 Javascript
JavaScript编程学习技巧汇总
2016/02/21 Javascript
带有定位当前位置的百度地图前端web api实例代码
2016/06/21 Javascript
vue多级多选菜单组件开发
2020/09/08 Javascript
easyui combotree加载静态数据问题(选不上)解决方法
2016/12/26 Javascript
折叠菜单及选择器的运用
2017/02/03 Javascript
JavaScript实现鼠标点击导航栏变色特效
2017/02/08 Javascript
利用SpringMVC过滤器解决vue跨域请求的问题
2018/02/10 Javascript
基于vue-cli vue-router搭建底部导航栏移动前端项目
2018/02/28 Javascript
[03:03]DOTA2校园争霸赛 济南城市决赛欢乐发奖活动
2013/10/21 DOTA
python中将函数赋值给变量时需要注意的一些问题
2017/08/18 Python
Jupyter中直接显示Matplotlib的图形方法
2018/05/24 Python
如何使用python把ppt转换成pdf
2019/06/29 Python
浅谈python多进程共享变量Value的使用tips
2019/07/16 Python
python matplotlib库直方图绘制详解
2019/08/10 Python
python中not、and和or的优先级与详细用法介绍
2020/11/03 Python
酒店管理毕业生自荐信
2013/10/24 职场文书
给学校的建议书范文
2014/05/15 职场文书
习近平在党的群众路线教育实践活动总结大会上的讲话全文
2014/10/25 职场文书
2014年教研工作总结
2014/12/06 职场文书
寻衅滋事罪辩护词
2015/05/21 职场文书
ORM模型框架操作mysql数据库的方法
2021/07/25 MySQL
mysql中varchar类型的日期进行比较、排序等操作的实现
2021/11/17 MySQL
Kubernetes部署实例并配置Deployment、网络映射、副本集
2022/04/01 Servers
【海涛DOTA】D-cup邀请赛NV.cn vs DT.Love
2022/04/01 DOTA