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 相关文章推荐
jQuery 中关于CSS操作部分使用说明
Jun 10 Javascript
HTML代码中标签的全部属性 中文注释说明
Mar 26 Javascript
用 Javascript 验证表单(form)中多选框(checkbox)值
Sep 08 Javascript
Jquery 插件学习实例1 插件制作说明与tableUI优化
Apr 02 Javascript
js中更短的 Array 类型转换
Oct 30 Javascript
Jquery实现兼容各大浏览器的Enter回车切换输入焦点的方法
Sep 01 Javascript
js实现网页标题栏闪烁提示效果实例分析
Nov 20 Javascript
浅谈html转义及防止javascript注入攻击的方法
Dec 04 Javascript
详解在 Angular 项目中添加 clean-blog 模板
Jul 04 Javascript
js使用highlight.js高亮你的代码
Aug 18 Javascript
浅谈vue-props的default写不写有什么区别
Aug 09 Javascript
vue中data里面的数据相互使用方式
Jun 05 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 addslashes和mysql_real_escape_string
2010/01/24 PHP
php数组函数序列之array_sum() - 计算数组元素值之和
2011/10/29 PHP
关于mysql字符集设置了character_set_client=binary 在gbk情况下会出现表描述是乱码的情况
2013/01/06 PHP
php实现随机显示图片方法汇总
2015/05/21 PHP
php获取当前url地址的方法小结
2017/01/10 PHP
javascript引导程序
2008/10/26 Javascript
整理的比较全的event对像在ie与firefox浏览器中的区别
2013/11/25 Javascript
jquery动态改变onclick属性导致失效的问题解决方法
2013/12/04 Javascript
文本框(input)获取焦点(onfocus)时样式改变的示例代码
2014/01/10 Javascript
jQuery+HTML5实现手机摇一摇换衣特效
2015/06/05 Javascript
jQuery的position()方法详解
2015/07/19 Javascript
javascript经典特效分享 手风琴、轮播图、图片滑动
2016/09/14 Javascript
bootstrap table小案例
2016/10/21 Javascript
JS常见疑难点分析之match,charAt,charCodeAt,map,search用法分析
2016/12/25 Javascript
jQuery.parseHTML() 函数详解
2017/01/09 Javascript
jQuery Position方法使用和兼容性
2017/08/23 jQuery
页面缩放兼容性处理方法(zoom,Firefox火狐浏览器)
2017/08/29 Javascript
利用不到200行代码写一款属于你自己的js类库
2019/07/08 Javascript
Vue根据条件添加click事件的方式
2019/11/09 Javascript
[57:41]Secret vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python实现对字典分别按键(key)和值(value)进行排序的方法分析
2018/12/19 Python
Django对接支付宝实现支付宝充值金币功能示例
2019/12/17 Python
浅谈python锁与死锁问题
2020/08/14 Python
聊聊python中的异常嵌套
2020/09/01 Python
Python爬虫之Selenium鼠标事件的实现
2020/12/04 Python
加拿大国民体育购物网站:National Sports
2018/11/04 全球购物
电气工程及其自动化自我评价四篇
2013/09/24 职场文书
国际会计专业求职信
2014/08/04 职场文书
民政局个人整改措施
2014/09/24 职场文书
单身申明具结书
2015/02/26 职场文书
2015年工程部工作总结
2015/04/30 职场文书
2016年八一建军节活动总结
2016/04/05 职场文书
团组织关系介绍信
2019/06/24 职场文书
如何开发一个渐进式Web应用程序PWA
2021/05/10 Javascript
对象析构函数__del__在Python中何时使用
2022/03/22 Python
win10如何更改appdata文件夹的默认位置?
2022/07/15 数码科技