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 相关文章推荐
按下回车键指向下一个位置的一个函数代码
Mar 10 Javascript
使用jquery+CSS实现控制打印样式
Dec 31 Javascript
基于CSS3和jQuery实现跟随鼠标方位的Hover特效
Jul 25 Javascript
基于JS实现checkbox全选功能实例代码
Oct 31 Javascript
jQuery中animate的几种用法与注意事项
Dec 12 Javascript
微信小程序之蓝牙的链接
Sep 26 Javascript
Node.js使用MySQL连接池的方法实例
Feb 11 Javascript
JavaScript 隐性类型转换步骤浅析
Mar 15 Javascript
JS实现为动态添加的元素增加事件功能示例【基于事件委托】
Mar 21 Javascript
jquery获取select选中值的文本,并赋值给另一个输入框的方法
Aug 21 jQuery
对angularJs中ng-style动态改变样式的实例讲解
Sep 30 Javascript
详解Vue的异步更新实现原理
Dec 22 Vue.js
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的远程图片抓取函数分享
2013/09/25 PHP
浅谈PHP中如何实现Hook机制
2017/11/14 PHP
PHP实现常用排序算法的方法
2020/02/05 PHP
Wordpress ThickBox 点击图片显示下一张图的修改方法
2010/12/11 Javascript
为指定的元素添加遮罩层的示例代码
2014/01/15 Javascript
js 判断浏览器使用的语言示例代码
2014/03/22 Javascript
JavaScript获取当前运行脚本文件所在目录的方法
2016/02/03 Javascript
leaflet的开发入门教程
2016/11/17 Javascript
javascript入门之window对象【新手必看】
2016/11/22 Javascript
基于JavaScript表单脚本(详解)
2017/10/18 Javascript
在Vue中使用highCharts绘制3d饼图的方法
2018/02/08 Javascript
React 组件转 Vue 组件的命令写法
2018/02/28 Javascript
vue项目使用axios发送请求让ajax请求头部携带cookie的方法
2018/09/26 Javascript
H5+C3+JS实现五子棋游戏(AI篇)
2020/05/28 Javascript
使用RxJS更优雅地进行定时请求详析
2019/06/02 Javascript
vue 使用高德地图vue-amap组件过程解析
2019/09/07 Javascript
js实现数字从零慢慢增加到指定数字示例
2019/11/07 Javascript
Vue2.x-使用防抖以及节流的示例
2021/03/02 Vue.js
通过Python来使用七牛云存储的方法详解
2015/08/07 Python
为何人工智能(AI)首选Python?读完这篇文章你就知道了(推荐)
2019/04/06 Python
Django的models模型的具体使用
2019/07/15 Python
Python中的sys.stdout.write实现打印刷新功能
2020/02/21 Python
python GUI库图形界面开发之PyQt5信号与槽基本操作
2020/02/25 Python
python中upper是做什么用的
2020/07/20 Python
python3从网络摄像机解析mjpeg http流的示例
2020/11/13 Python
Python大批量搜索引擎图像爬虫工具详解
2020/11/16 Python
使用phonegap查找联系人的实现方法
2017/03/31 HTML / CSS
Anya Hindmarch官网:奢侈设计师手袋及配饰
2018/11/15 全球购物
Juicy Couture Beauty官方网站:香水和化妆品
2019/03/12 全球购物
求职信范文英文版
2014/01/05 职场文书
秋天的雨教学反思
2014/04/27 职场文书
大学班级学风建设方案
2014/05/01 职场文书
四风对照检查材料范文
2014/09/27 职场文书
新教师教学工作总结
2015/08/14 职场文书
一篇合格的广告文案,其主要目的是什么?
2019/07/12 职场文书
如何利用js在两个html窗口间通信
2021/04/27 Javascript