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代码
Feb 11 Javascript
jquery $.ajax()取xml数据的小问题解决方法
Nov 20 Javascript
jquery得到font-size属性值实现代码
Sep 30 Javascript
js将json格式内容转换成对象的方法
Nov 01 Javascript
jquery 合并内容相同的单元格(示例代码)
Dec 13 Javascript
js四舍五入数学函数round使用实例
May 09 Javascript
AngularJS表格详解及示例代码
Aug 17 Javascript
前端主流框架vue学习笔记第一篇
Jul 26 Javascript
layui自定义插件citySelect实现省市区三级联动选择
Jul 26 Javascript
关于layui时间回显问题的解决方法
Sep 24 Javascript
详解Vue 单文件组件的三种写法
Feb 19 Javascript
让JavaScript代码更加精简的方法技巧
Jun 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中的命名空间详细介绍
2015/07/02 PHP
Javascript 日期对象Date扩展方法
2009/05/30 Javascript
jQuery 使用手册(四)
2009/09/23 Javascript
js url传值中文乱码之解决之道
2009/11/20 Javascript
选择TreeView控件的树状数据节点的JS方法(jquery)
2010/02/06 Javascript
JQuery 获得绝对,相对位置的坐标方法
2010/02/09 Javascript
电子商务网站上的常用的js放大镜效果
2011/12/08 Javascript
项目中常用的JS方法整理
2015/01/30 Javascript
Javascript闭包(Closure)详解
2015/05/05 Javascript
JS+CSS实现美化的下拉列表框效果
2015/08/11 Javascript
jQuery实现批量判断表单中文本框非空的方法(2种方法)
2015/12/09 Javascript
一种新的javascript对象创建方式Object.create()
2015/12/28 Javascript
JS中关于事件处理函数名后面是否带括号的问题
2016/11/16 Javascript
JQuery Ajax 异步操作之动态添加节点功能
2017/05/24 jQuery
利用Javascript实现一套自定义事件机制
2017/12/14 Javascript
vue路由跳转传参数的方法
2019/05/06 Javascript
layui上传图片到服务器的非项目目录下的方法
2019/09/26 Javascript
详解关于Vue单元测试的几个坑
2020/04/26 Javascript
[18:20]DOTA2 HEROS教学视频教你分分钟做大人-昆卡
2014/06/11 DOTA
python通过apply使用元祖和列表调用函数实例
2015/05/26 Python
Python实现接受任意个数参数的函数方法
2018/04/21 Python
Scrapy使用的基本流程与实例讲解
2018/10/21 Python
Python zip函数打包元素实例解析
2019/12/11 Python
django框架基于queryset和双下划线的跨表查询操作详解
2019/12/11 Python
pytorch实现Tensor变量之间的转换
2020/02/17 Python
解决flask接口返回的内容中文乱码的问题
2020/04/03 Python
Python sklearn中的.fit与.predict的用法说明
2020/06/28 Python
django rest framework使用django-filter用法
2020/07/15 Python
Python csv文件记录流程代码解析
2020/07/16 Python
如何判断计算机可能已经中马
2013/03/22 面试题
申请任职学生会干部自荐书范文
2014/02/13 职场文书
《长城和运河》教学反思
2014/04/14 职场文书
处级领导干部四风问题自我剖析材料
2014/09/29 职场文书
2015年大学生入党自荐书
2015/03/24 职场文书
python中数组和列表的简单实例
2022/03/25 Python
Windows Server 2016 配置 IIS 的详细步骤
2022/04/28 Servers