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简单实现HTML标签Select联动带跳转
Oct 23 Javascript
jquery基本选择器匹配多个元素的实现方法
Sep 05 Javascript
JavaScript生成验证码并实现验证功能
Sep 24 Javascript
对javascript继承的理解
Oct 11 Javascript
Javascript同时声明一连串(多个)变量的方法
Jan 23 Javascript
利用imgareaselect辅助后台实现图片上传裁剪
Mar 02 Javascript
JS获取一个表单字段中多条数据并转化为json格式
Oct 17 Javascript
AngularJS中的作用域实例分析
May 16 Javascript
vue项目中使用Hbuilder打包app 设置沉浸式状态栏的方法
Oct 22 Javascript
ztree加载完成后显示勾选节点的实现代码
Oct 22 Javascript
微信小程序封装分享与分销功能过程解析
Aug 13 Javascript
三种方式清除vue路由跳转router-link的历史记录
Apr 10 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中几种常见的超时处理全面总结
2012/09/11 PHP
php解决约瑟夫环示例
2014/04/09 PHP
ECSHOP在PHP5.5及高版本上报错的解决方法
2015/08/31 PHP
YII2自动登录Cookie总是失效的解决方法
2017/06/28 PHP
页面中body onload 和 window.onload 冲突的问题的解决
2009/07/01 Javascript
JavaScript 面向对象之命名空间
2010/05/04 Javascript
js中关于new Object时传参的一些细节分析
2011/03/13 Javascript
javascript中的数字与字符串相加实例分析
2011/08/14 Javascript
JavaScript作用域链使用介绍
2013/08/29 Javascript
JavaScript实现班级随机点名小应用需求的具体分析
2014/05/12 Javascript
jquery 插件实现多行文本框[textarea]自动高度
2015/03/04 Javascript
使用jquery插件qrcode生成二维码
2015/10/22 Javascript
Bootstrap每天必学之前端开发框架
2015/11/19 Javascript
JS中this上下文对象使用方式
2016/10/09 Javascript
JS正则表达式之非捕获分组用法实例分析
2016/12/28 Javascript
node.js 核心http模块,起一个服务器,返回一个页面的实例
2017/09/11 Javascript
简单的Vue异步组件实例Demo
2017/12/27 Javascript
详解微信小程序开发用户授权登陆
2019/04/24 Javascript
vue router 跳转时打开新页面的示例方法
2019/07/28 Javascript
[02:51]DOTA2 Supermajor小组分组对阵抽签仪式
2018/06/01 DOTA
python输出当前目录下index.html文件路径的方法
2015/04/28 Python
详解在Python的Django框架中创建模板库的方法
2015/07/20 Python
使用Python画股票的K线图的方法步骤
2019/06/28 Python
Python基于codecs模块实现文件读写案例解析
2020/05/11 Python
Python实现JS解密并爬取某音漫客网站
2020/10/23 Python
Django-simple-captcha验证码包使用方法详解
2020/11/28 Python
不同浏览器对CSS3和HTML5的支持状况
2009/10/31 HTML / CSS
html5使用canvas画一条线
2014/12/15 HTML / CSS
HTML5实现桌面通知 提示功能
2017/10/11 HTML / CSS
澳大利亚领先的在线美容商城:Adore Beauty
2017/04/14 全球购物
幼儿园中秋节活动反思
2014/02/16 职场文书
大班上学期幼儿评语
2014/04/30 职场文书
争先创优公开承诺书
2014/08/30 职场文书
民政局个人整改措施
2014/09/24 职场文书
2014年销售工作总结与计划
2014/12/01 职场文书
团员年度个人总结
2015/02/26 职场文书