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实现计算加载页面所用的时间
Apr 02 Javascript
js弹窗返回值详解(window.open方式)
Jan 11 Javascript
Node.js和PHP根据ip获取地理位置的方法
Mar 14 Javascript
JavaScript函数定义的常见注意事项小结
Sep 16 Javascript
详谈JavaScript 匿名函数及闭包
Nov 14 Javascript
js构造函数、索引数组和属性的实现方式和使用
Nov 16 Javascript
原生JS发送异步数据请求
Jun 08 Javascript
node结合swig渲染摸板的方法
Apr 11 Javascript
对node.js中render和send的用法详解
May 14 Javascript
在NPM发布自己造的轮子的方法步骤
Mar 09 Javascript
基于vue实现一个禅道主页拖拽效果
May 27 Javascript
适合后台管理系统开发的12个前端框架(小结)
Jun 29 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/10/09 PHP
从手册去理解分析PHP session机制
2011/07/17 PHP
php漏洞之跨网站请求伪造与防止伪造方法
2013/08/15 PHP
PHP数据库编程之MySQL优化策略概述
2017/08/16 PHP
javascript下arguments,caller,callee,call,apply示例及理解
2009/12/24 Javascript
javascript禁用键盘功能键让右击及其他键无效
2013/10/09 Javascript
使用Jquery获取带特殊符号的ID 标签的方法
2014/04/30 Javascript
JavaScript中isPrototypeOf函数作用和使用实例
2015/06/01 Javascript
利用JavaScript实现拖拽改变元素大小
2016/12/14 Javascript
结合mint-ui移动端下拉加载实践方法总结
2017/11/08 Javascript
浅谈webpack对样式的处理
2018/01/05 Javascript
微信小程序实现弹出菜单功能
2018/06/12 Javascript
浅谈高大上的微信小程序中渲染html内容—技术分享
2018/10/25 Javascript
vue3.0 搭建项目总结(详细步骤)
2019/05/20 Javascript
详解Vue中的watch和computed
2020/11/09 Javascript
Vue多选列表组件深入详解
2021/03/02 Vue.js
[48:30]LGD vs infamous Supermajor小组赛D组 BO3 第一场 6.3
2018/06/04 DOTA
Python运行报错UnicodeDecodeError的解决方法
2016/06/07 Python
Python win32com 操作Exce的l简单方法(必看)
2017/05/25 Python
python实现list元素按关键字相加减的方法示例
2017/06/09 Python
python3实现字符串的全排列的方法(无重复字符)
2018/07/07 Python
解决每次打开pycharm直接进入项目的问题
2018/10/28 Python
简单易懂Pytorch实战实例VGG深度网络
2019/08/27 Python
Python图像处理模块ndimage用法实例分析
2019/09/05 Python
快速解决jupyter启动卡死的问题
2020/04/10 Python
python输出数学符号实例
2020/05/11 Python
利用css3画个同心圆示例代码
2017/07/03 HTML / CSS
Made in Design德国:设计师家具、灯具和装饰
2019/10/31 全球购物
行政主管职责范本
2014/03/07 职场文书
医院安全生产月活动总结
2014/07/05 职场文书
优秀应届本科生求职信
2014/07/19 职场文书
责任书范本大全
2015/05/11 职场文书
九年级历史教学反思
2016/02/19 职场文书
《我的长生果》教学反思
2016/02/20 职场文书
利用ajax+php实现商品价格计算
2021/03/31 PHP
Python Flask实现进度条
2022/05/11 Python