vue轮播组件实现$children和$parent 附带好用的gif录制工具

 更新时间:2019年09月26日 13:17:37   投稿:mrr  
这篇文章主要介绍了vue轮播组件实现,$children和$parent,附带好用的gif录制工具,需要的朋友可以参考下

1、先提前预祝大家国庆节玩的愉快,我国庆要见家长去了(忐忑)

2、忍不住想要为小米正名,虽然我是米粉但是我是理智粉。

24号不是mix alpha发布会啊,看了真滴是惊艳(现场直接有人喊“ 牛逼 ”,看过好多发布会,就没有看到这样直接喊出来“牛逼”的)。不知道大家还记不记得13年那会吹苹果的时候的一块ppt手机(其实是媒体做的图),但是现在小米做出来了,甚至更好。但是我最近在uc上面那真是到处黑。以前我不相信水军说法,现在信了。如果关注小米mix alpha新闻的在uc下面经常能看到一个叫“决胜千里”的人,每次都是千篇一律的复制黏贴黑。

我想说,没买过没资格。就像写代码,没写过别说懂。写了你才知道这里面有哪些细节和关键因素。

写这个组件起因

记得就这两天有掘友发一个沸点说找女票千万别找同行,好了,曾经我是erp软件实施,现在转前端。女票也是前端。然后她发我一个链接(打不开看gif图):http://ipark.jsboon.com/static/dashboard/yjw/yjw.html

这个链接的最右侧有一个轮播的效果。说起来这整个页面是不咋的,不过里面涉及的东西都比较复杂。 附带gif录制工具:http://www.zdfans.com/html/1754.html

回到刚才说的,女票,对女票。不懂问我,就像之前评论的,干脆让我写得了。这下好了报应来了。(说起来真是无语,她比我早干一年,结果还不如我写了1年前端)

说起来我还没写过这种轮播组件,但是之前去看过源码,并且了解过。如果是写死的那种确实比较简单。但是我们今天用vue封装一个组件。

一、知识点涉及

1、vue组件化开发

2、vue组件嵌套组,就是两个组件相互耦合,然后必须配合使用的那种。参考elementUI里面的表单组件(分为from组件,item组件)或者轮播组件。

vue的 $children和 $parent

3、css动画和形变

二、开始写组件

1、先写你的框,主组件

这个是容器,负责组件定位和组件的整体运作的

html部分

<div
 @mouseenter.stop="handleMouseEnter"
 @mouseleave.stop="handleMouseLeave"
 class="dht-swiper-side"
 :style="{ zIndex: zIndex }"
>
 <slot></slot>
</div>

主要两个鼠标事件: mouseenter和 mouseleave

第一个就是鼠标在元素上负责停止定时器,第二个就是鼠标离开重启定时器

对应的props和监听

props: {
 // 时间间隔
 interval: {
  type: Number,
  default: 8000
 },
 //是否自动播放
 autoplay: {
  type: Boolean,
  default: true
 },
 zIndex: {
  type: Number,
  default: 2000
 },
 // x轴变化
 axisx: {
  type: Number,
  default: 1000
 }
},
watch: {
 autoplay(val) {
  val ? this.startTimer() : this.stopTimer();
 }
},
data() {
 return {
  // 计时器
  timer: "",
  //子元素
  items: [],
  // 当前显示的元素
  active: 0
 };
},

看看就好,没啥多说的,我感觉挺清晰的

2、写你的子组件

这里必须跳跃一下,为什么呢?

因为:主组件主要负责动画运作和容器的作用。定义好你要的参数之后,其实主组件你直接看代码是不不符合编写逻辑的

有了主组件之后,我需要有子元素才能动起来,所以先把子元素加载进来

html部分

<div class="dht-swiper-side-item" :style="itemStyle">
 <slot></slot>
</div>

js核心部分

created() {
 //元素创建和需要更新父元素属性
 this.$parent && this.$parent.updateItems();
},
beforeMount() {},
mounted() {},
destroyed() {
 //元素销毁和需要更新父元素属性
 this.$parent && this.$parent.updateItems();
},

这里主要是创建元素的时候需要把元素加入主组件的items中,销毁的时候同样进行更新

主组件的更新代码

// 更新元素
updateItems() {
 this.items = this.$children.filter(
  // 更新元素需要确认为指定的子元素
  child => child.$options.name === "dhtSwiperSideItem"
 );
},

css核心部分

css部分主要是定义动画效果,和基础css,主要是看动画部分

.dht-swiper-side-item {
 position: absolute;
 transition: all 1s ease;
 transform: translateX(1000px);
 // 抖动动画
 @keyframes mymove {
  0% {
   left: 0;
  }
  50% {
   left: 15px;
  }
  100% {
   left: 0;
  }
 }
}

3、一般弹窗动画之类的编写原理讲解

1、不能用display:none,因为那样元素是直接显示出来的,动画是无法有的。

2、举例:下方弹窗划出

其实在写这些弹窗的时候元素已经在页面上面加载好了,只是被我们隐藏到显示器之外了。

所以我们要做的是在点击显示的时候把元素位移回来

3、所以其实页面上基本的动画都是先放在你看不到的地方,然后再通过 transform

形变css给移动回来的。我这次的组件也是一样的。

4、主组件操作

1、回顾一下,刚才我们先写了主组件,主组件加载子组件,子组件会调用主组件函数,让主组件去更新自己的items,提前存好。方便使用

2、既然我们主组件拿到了子组件了,那么就可以直接操作子组件进行操作,其实核心原理在于主组件之间操作子组件。(我看了elementUI源码的走马灯部分,写的比我复杂。)

3、定时器部分

//开始计时器
startTimer() {
 //预先执行一次,保证不会出现第一次运行延迟双倍实际
 this.play();
 // 拦截处理
 if (this.interval <= 0 || !this.autoplay || this.timer) return;
 this.timer = setInterval(() => {
  this.play();
 }, this.interval);
},

这块其实没啥,除了预先的拦截剩下的就是启动定时器,然后运行动画播放函数

4、核心播放函数部分

//播放实际运行函数
play() {
 let len = this.items.length - 1;
 let now = this.active > len ? 0 : this.active;
 let old = this.active - 1 < 0 ? 0 : this.active - 1;
 //console.log("当前", now, "老的", old);
 //关闭老元素
 this.items[old].show = false;
 this.items[old].itemStyle = {
  transition: "all 1.5s ease",
  transform: `translateX(${this.axisx}px)`
 };
 //显示新元素
 this.items[now].show = true;
 this.items[now].itemStyle = {
  transition: "all 1.5s ease",
  transform: "translateX(0)",
  animation: "mymove 1.5s 2"
 };
 //记录数据
 this.active = now + 1;
}

这个其实很简单,每次运行的时候处理一下数据,拿到当前要运行的子元素id和老的元素,当前的展示,老的移动回去。最后记录一下新的id

这里有一个坑点:就是animation部分,记得运行2次,不然只是一次会导致下面的元素看不到抖动效果。原因是在移动的时候就抖动完毕了。

5、主组件css部分

.dht-swiper-side {
 position: absolute;
 z-index: 2000;
 right: 0;
 display: flex;
 flex-flow: row;
 width: 100%;
}

三、组件文档

dht-swiper-side 侧边轮播组件 interval Number 5000 时间间隔,默认5秒转换一次 必须给该组件指定宽度,否则无法正常显示。 内部子元素展示做最侧位置主要由该组件的宽度定义
autoplay Boolean TRUE 是否自动播放,咱不支持false
zIndex Number 2000 组件层级
axisx Number 1000 隐藏的子元素位置,px单位,默认1000。当内部元素宽度过大时可以调节该参数
dht-swiper-side-item dht-swiper-side dht-swiper-side的子组件,用于存放内容

四、个人组件效果展示

<dht-swiper-side class="main">
 <dht-swiper-side-item>
  <div class="item">我是组件1</div>
 </dht-swiper-side-item>
 <dht-swiper-side-item>
  <div class="item">我是组件2</div>
 </dht-swiper-side-item>
 <dht-swiper-side-item>
  <div class="item">我是组件3</div>
 </dht-swiper-side-item>
 <dht-swiper-side-item>
  <div class="item">我是组件4</div>
 </dht-swiper-side-item>
</dht-swiper-side>

.main {
 width: 500px;
 .item {
  width: 100px;
  height: 100px;
  background: #009966;
  border: #409eff 1px solid;
  text-align: center;
  line-height: 100px;
 }
}

主组件全部代码

<template>
 <div
  @mouseenter.stop="handleMouseEnter"
  @mouseleave.stop="handleMouseLeave"
  class="dht-swiper-side"
  :style="{ zIndex: zIndex }"
 >
  <slot></slot>
 </div>
</template>

<script>
export default {
 name: "dhtSwiperSide",
 props: {
  // 时间间隔
  interval: {
   type: Number,
   default: 8000
  },
  //是否自动播放
  autoplay: {
   type: Boolean,
   default: true
  },
  zIndex: {
   type: Number,
   default: 2000
  },
  // x轴变化
  axisx: {
   type: Number,
   default: 1000
  }
 },
 watch: {
  autoplay(val) {
   val ? this.startTimer() : this.stopTimer();
  }
 },
 data() {
  return {
   // 计时器
   timer: "",
   //子元素
   items: [],
   // 当前显示的元素
   active: 0
  };
 },
 beforeCreate() {},
 created() {
  this.$nextTick(() => {
   this.updateItems();
   this.startTimer();
   this.$children[0].show = true;
  });
 },
 beforeMount() {},
 mounted() {},
 destroyed() {
  clearInterval(this.timer);
 },
 methods: {
  handleMouseEnter() {
   this.stopTimer();
  },

  handleMouseLeave() {
   this.startTimer();
  },
  //开始计时器
  startTimer() {
   //预先执行一次,保证不会出现第一次运行延迟双倍实际
   this.play();
   // 拦截处理
   if (this.interval <= 0 || !this.autoplay || this.timer) return;
   this.timer = setInterval(() => {
    this.play();
   }, this.interval);
  },
  // 停止计时器
  stopTimer() {
   clearInterval(this.timer);
  },
  // 更新元素
  updateItems() {
   this.items = this.$children.filter(
    // 更新元素需要确认为指定的子元素
    child => child.$options.name === "dhtSwiperSideItem"
   );
  },
  //播放实际运行函数
  play() {
   let len = this.items.length - 1;
   let now = this.active > len ? 0 : this.active;
   let old = this.active - 1 < 0 ? 0 : this.active - 1;
   //console.log("当前", now, "老的", old);
   //关闭老元素
   this.items[old].show = false;
   this.items[old].itemStyle = {
    transition: "all 1.5s ease",
    transform: `translateX(${this.axisx}px)`
   };
   //显示新元素
   this.items[now].show = true;
   this.items[now].itemStyle = {
    transition: "all 1.5s ease",
    transform: "translateX(0)",
    animation: "mymove 1.5s 2"
   };
   //记录数据
   this.active = now + 1;
  }
 }
};
</script>

<style lang="scss">
.dht-swiper-side {
 position: absolute;
 z-index: 2000;
 right: 0;
 display: flex;
 flex-flow: row;
 width: 100%;
}
</style>

子组件全部代码

<template>
 <div class="dht-swiper-side-item" :style="itemStyle">
  <slot></slot>
 </div>
</template>

<script>
export default {
 name: "dhtSwiperSideItem",
 data() {
  return {
   show: false,
   defaultStyle: {},
   itemStyle: {}
  };
 },
 watch: {},
 beforeCreate() {},
 created() {
  //元素创建和需要更新父元素属性
  this.$parent && this.$parent.updateItems();
 },
 beforeMount() {},
 mounted() {},
 destroyed() {
  //元素销毁和需要更新父元素属性
  this.$parent && this.$parent.updateItems();
 },
 methods: {}
};
</script>

<style lang="scss">
.dht-swiper-side-item {
 position: absolute;
 transition: all 1s ease;
 transform: translateX(1000px);
 // 抖动动画
 @keyframes mymove {
  0% {
   left: 0;
  }
  50% {
   left: 15px;
  }
  100% {
   left: 0;
  }
 }
}
</style>

致谢

感谢elementUI开源代码,本组件有部分是直接拷贝的elementUI的Carousel的代码。

总结

以上所述是小编给大家介绍的vue轮播组件实现$children和$parent 附带好用的gif录制工具,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

相关文章

  • vue3的defineExpose宏函数是如何暴露方法给父组件使用

    vue3的defineExpose宏函数是如何暴露方法给父组件使用

    当子组件使用setup后,父组件就不能像vue2那样直接就可以访问子组件内的属性和方法,这个时候就需要在子组件内使用defineExpose宏函数来指定想要暴露出去的属性和方法,本文介绍vue3的defineExpose宏函数是如何暴露方法给父组件使用,需要的朋友可以参考下
    2024-05-05
  • vue-cli之引入Bootstrap问题(遇到的坑,以及解决办法)

    vue-cli之引入Bootstrap问题(遇到的坑,以及解决办法)

    这篇文章主要介绍了vue-cli之引入Bootstrap问题(遇到的坑,以及解决办法),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • vue elementui上传图片限制格式、大小和尺寸方式

    vue elementui上传图片限制格式、大小和尺寸方式

    这篇文章主要介绍了vue elementui上传图片限制格式、大小和尺寸方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Vue用v-for给循环标签自身属性添加属性值的方法

    Vue用v-for给循环标签自身属性添加属性值的方法

    这篇文章主要介绍了Vue用v-for给循环标签自身属性添加属性值的方法,文中大家给大家列举了三种方法 ,需要的朋友可以参考下
    2018-10-10
  • Vue组件简易模拟实现购物车

    Vue组件简易模拟实现购物车

    这篇文章主要为大家详细介绍了Vue组件简易模拟实现购物车,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • 利用vue-i18n实现多语言切换效果的方法

    利用vue-i18n实现多语言切换效果的方法

    这篇文章主要给大家介绍了关于利用vue-i18n实现多语言切换效果的方法,文中通过示例代码介绍的非常详细,对大家学习或者使用vue-i18n具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • vue-week-picker实现支持按周切换的日历

    vue-week-picker实现支持按周切换的日历

    这篇文章主要为大家详细介绍了vue-week-picker实现支持按周切换的日历,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06
  • Vue CLI 3.x 自动部署项目至服务器的方法

    Vue CLI 3.x 自动部署项目至服务器的方法

    本教程讲解的是 Vue-CLI 3.x 脚手架搭建的vue项目, 利用scp2自动化部署到静态文件服务器 Nginx。非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧
    2019-04-04
  • vue实现批量下载文件

    vue实现批量下载文件

    这篇文章主要为大家详细介绍了vue实现批量下载文件的方法(不走后端接口的方法),文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-12-12
  • Vue3+El-Plus实现表格行拖拽功能完整代码

    Vue3+El-Plus实现表格行拖拽功能完整代码

    在vue3+elementPlus网站开发中,详细完成el-table表格的鼠标拖拽/拖曳/拖动排序,下面这篇文章主要给大家介绍了关于Vue3+El-Plus实现表格行拖拽功能的相关资料,需要的朋友可以参考下
    2024-05-05

最新评论