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基本概念初级讲解论坛贴的学习记录
Feb 22 Javascript
JavaScript asp.net 获取当前超链接中的文本
Apr 14 Javascript
jquery中prop()方法和attr()方法的区别浅析
Sep 06 Javascript
jquery等待效果示例
May 01 Javascript
javascript学习笔记(六)数据类型和JSON格式
Oct 08 Javascript
javascript中call和apply的用法示例分析
Apr 02 Javascript
Javascript封装id、class与元素选择器方法示例
Mar 13 Javascript
详解vue表单验证组件 v-verify-plugin
Apr 19 Javascript
微信小程序访问node.js接口服务器搭建教程
Apr 25 Javascript
Vue 2中ref属性的使用方法及注意事项
Jun 12 Javascript
微信运维交互机器人的示例代码
Nov 12 Javascript
react antd表格中渲染一张或多张图片的实例
Oct 28 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/04/30 PHP
PHP实现的只保留字符串首尾字符功能示例【隐藏部分字符串】
2019/03/11 PHP
使用Zookeeper分布式部署PHP应用程序
2019/03/15 PHP
laravel利用中间件防止未登录用户直接访问后台的方法
2019/09/30 PHP
PHP网站常见安全漏洞,及相应防范措施总结
2021/03/01 PHP
jquery连缀语法如何实现
2012/11/29 Javascript
jquery实现点击弹出带标题栏的弹出层(从右上角飞入)效果
2015/09/19 Javascript
angular.bind使用心得
2015/10/26 Javascript
ES6的新特性概览
2016/03/10 Javascript
基于socket.io+express实现多房间聊天
2016/03/17 Javascript
JS实现商品筛选功能
2020/08/19 Javascript
AngularJS 控制器 controller的详解
2017/10/17 Javascript
Vue加载组件、动态加载组件的几种方式
2018/08/31 Javascript
vue基础之使用get、post、jsonp实现交互功能示例
2019/03/12 Javascript
Vue 2.0 侦听器 watch属性代码详解
2019/06/19 Javascript
对numpy中的where方法嵌套使用详解
2018/10/31 Python
Python实现的列表排序、反转操作示例
2019/03/13 Python
Python数据类型之String字符串实例详解
2019/05/08 Python
Django框架用户注销功能实现方法分析
2019/05/28 Python
Python中一个for循环循环多个变量的示例
2019/07/16 Python
Python 用三行代码提取PDF表格数据
2019/10/13 Python
keras 特征图可视化实例(中间层)
2020/01/24 Python
使用pth文件添加Python环境变量方式
2020/05/26 Python
Python 合并拼接字符串的方法
2020/07/28 Python
UI自动化定位常用实现方法代码示例
2020/10/27 Python
美国爆米花工厂:The Popcorn Factory
2019/09/14 全球购物
什么是命名空间(NameSpace)
2015/11/24 面试题
C#如何判断当前用户是否输入某个域
2015/12/07 面试题
恒华伟业笔试面试题
2015/02/26 面试题
Delphi软件工程师试题
2013/01/29 面试题
材料物理专业个人求职信
2013/12/15 职场文书
拾金不昧表扬信范文
2014/01/11 职场文书
小学生暑假感言
2014/02/06 职场文书
感恩节红领巾广播稿
2014/02/11 职场文书
未受刑事制裁公证证明
2014/09/20 职场文书
不服从公司安排检讨书
2014/09/24 职场文书