vue3.0封装轮播图组件的步骤


Posted in Vue.js onMarch 04, 2021

       接着上一篇文章,熟悉vue3.0的基本用法,和使用一段时间以后,开始准备开发适用于vue3.0使用的pc端的组件库。会陆续跟新一些组件库的写法和注意事项,有兴趣的同学可以多多关注哦,不多bb,开始。

开发一个轮播图组件,适用pc端,(暂无考虑app), 使用于vue3.0 + TS

大致的实现效果是这样:

vue3.0封装轮播图组件的步骤

图片自由轮播,对应圆点图片跳转,左右指示器跳转等。暴露以下options配置:

vue3.0封装轮播图组件的步骤

以上是主要的options,下面展开来说一下具体如何封装。

一:封装思想

在vue3.0和vue2.0中封装组件其实核心思想都是一样的,需要使用到vue.component();对组件进行注册,之后在main.ts中挂载一下就可以使用。

在 src下面创建: src --> libs --> sqm_ui(自己UI库的名称)-->index.js

这里的index.js就是注册组件的入口。

同级目录下新建一个文件, Carousel, 这个文件包含所有的轮播组件的功能和样式。

目录如下:

vue3.0封装轮播图组件的步骤

要注意一点: 虽然是在vue3.0和ts中使用,但是入口文件还是用js,这也是为了可以适用非ts写法。

在index.js中:

import Carousel from './Carousel/carousel';
import CarItem from './Carousel/item';let SqmUI = {};
SqmUI.install = function(vue) {
 vue.component(Carousel.name, Carousel);
 vue.component(CarItem.name,CarItem);
};
export default SqmUI;

但是为了配合TS使用,我们需要新建一个index.d.ts文件,用来描述库中成员类型来给TS用。

declare const _default: ({
 install: (app: import("vue").App<any>, ...options: any[]) => any; // 这里单纯描述一下install});
export default _default;

完成以上配置后,在main.ts中使用:

import SqmUI from '@/libs/sqm_ui/index';
import { createApp } from 'vue';
createApp.use(SqmUI);

二:封装流程

对于轮播图而言,我们需要一个固定的容器,来放置每一张滚动的图片,这时候我们需要定义一个Carousel.vue组件。

<template>
 <div class="carousel">
 <slot></slot> // 这里的slot是用来放置item组件
 </div>
</template>

还需要一个用来存储照片的组件,item.vue

<template>
 <div class="carousel-item">
 <slot></slot> // 这里的slot是用来放置img
 </div>
</template>

基本框架搭好,当用户使用的时候在carousel中配置options。

<carousel
 :autoPlay="true" 
 :durdation="3000" 
 :initial="3" 
 :hasDot="true" 
 :hasDirector="true"> </carousel>

在carousel.vue中:接受传来的配置项

props: { 
 autoplay: {  
 type: Boolean,  
 default: true }, 
 duration: {  
 type: Number,  
 default: 3000 }, 
 initial: {  
 type: Number,  
 default: 0 }, 
 hasDot: {  
 type: Boolean,
 default: true }, 
 hasDirector: { 
 type: Boolean,  
 default: true }
}

(1): 实现autoPlay:

在carousel.vue中:

const autoPlay = () => {
 if (props.autoplay) {
 t = setInterval(() => {
  // 轮播逻辑
 }, props.duration);
};
onMounted(() => {
 autoPlay();
});

逻辑很简单,定义一个autoPlay函数,在mounted阶段挂载。

(2): 实现轮播:

想这样一个问题:如何才能让这一张图片显示?一定需要当前图片的index,等于轮播时的index才可以显示。

在item.vue中:

<div class="carsel-item" v-if="selfIndex === currentIndex"> 
 <slot></slot> 
</div>

只有当自身的index,等于当前的index的时候才能显示。

获取currentIndex:

vue3.0中内置方法: getCurrentInstance()

这是一个很重要的方法,通过这个方法我们可以获取当前组件的实例,然后通过ctx获取该组件的上下文。特别好用。

在item.vue中:

setup() {
 const instance:any = getCurrentInstance(); console.log(instance);
}

vue3.0封装轮播图组件的步骤

在instance.vnode下面有个key是每个图片对应的自身的key也就是index。

在instance.parent.ctx 下面有个定义的currentIndex,是当前的index。

当二者相同时,可以显示当前图片。那么currentIndex在哪里设置呢?

回到carousel.vue中:

setup(props) { 
 const state = reactive({  
 currentIndex: props.initial,  
 itemLen: 0,  
 showDir: false 
 });
}

当前的currentIndex就是传入的initial的值。

在autoPlay中:执行轮播

const setIndex = ((dir:String): void => { 
 switch(dir) { 
 case 'next':  
  state.currentIndex += 1;  
  if (state.currentIndex === state.itemLen) {   
  state.currentIndex = 0;  
  }  
  break; 
 case 'prev':  
  state.currentIndex -= 1;  
  if (state.currentIndex === -1) {   
  state.currentIndex = state.itemLen - 1;  
  }  
  break; 
 default:  
  break; 
 } 
});

当next的时候,让currentIndex++; 直到等于轮播图片的长度。(array.length)

当prev的时候, 让currentIndex--; 直到=== -1

之后在item.vue中监听一下:

watch(() => {  
 return instance.parent.ctx.currentIndex 
 }, (value) => {  
 state.currentIndex = value; 
})

这样就完成图片的轮播。

三: 圆点指示器

实现的思想还是很简单的:

       通过传入的hasDot来确定需不需要显示。传入itemLen根据图片的数量来确定显示几个圆点,点击圆点可以跳转到对应的图片上。

在dot.vue中:

<template>
 <div class="dot-goes-wrapper" v-if="hasDot">
 <div class="dot-item" v-for="item in itemLen" :key="item">
 <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
  class="dot-link"
  :style="{backgroundColor: (item - 1) === currentIndex ? dotBgColor : '#fff'}" 
  @click="dotClick(item - 1)">
 </a> 
 </div> 
 </div>
</template>
<script lang="ts">
import {defineComponent} from 'vue';
export default defineComponent({
 name: 'dot',
 props: { 
 itemLen: Number, 
 currentIndex: Number, 
 dotBgColor: {  
  type: String,
  default: '#ff5000' },
 hasDot: {  
  type: Boolean,  
  default: true } 
 }, 
 setup(props, ctx) { 
 const dotClick = (index: Number) => { 
  ctx.emit('dotClick', index); 
 }; 
 return {  
  dotClick 
 } 
}})
</script>

通过ctx触发dotClick事件,把index传入,在父组件中使用(Carousel.vue):

@dotClick="dotClick"

const dotClick = (index: any): void => {

state.currentIndex = index;

};

这样完成了圆点指示器。

四: 左右指示器

这个很简单,就是移入的时候显示,然后点击图片滑动。

<template> 
 <div v-if="showDir"> 
 <div class="director dir-next" v-if="dir === 'next'">  
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="dirClick(dir)">></a> 
 </div> 
 <div class="director dir-prev" v-else-if="dir === 'prev'">  
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="dirClick(dir)"><</a> 
 </div> 
 </div>
</template>

<script lang="ts">
import {defineComponent} from 'vue';
export default defineComponent({ 
 name: 'direct', 
 props: { 
 dir: String, 
 showDir: {  
  type: Boolean,  
  default: false 
 } 
 }, 
 setup(props, ctx) { 
 const dirClick = (dir: String) => {  
  ctx.emit('dirClick', dir); 
 }; 
 return {  
  dirClick 
 } 
 }
})</script>

一样的传给父组件一个dirClick事件,在父组件中执行点击移动就可以了。

五:最后:

因为轮播图是通过定时器实现的需要销毁定时器。

onBeforeUnmount(() => {

      _clearFunction();

});

function _clearFunction(): void {

     clearInterval(t);

       t= null;

};

在鼠标移入时停止自动播放,显示左右指示器:

const mouseEnter = (): void => { 
 _clearFunction();
 state.showDir = true;
 };

在鼠标移出时开始播放, 左右指示器消失

const mouseLeave = (): void => { 
  autoPlay();
  state.showDir = false; 
};

ok. 大体的思想就是这样,还有一些细节可以自己再多想想。感谢!!

六:往期回顾

以上就是vue3.0封装轮播图组件的步骤的详细内容,更多关于vue3.0封装轮播图组件的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
vue实现树状表格效果
Dec 29 Vue.js
vue项目如何监听localStorage或sessionStorage的变化
Jan 04 Vue.js
vue element和nuxt的使用技巧分享
Jan 14 Vue.js
vue实现简易计算器功能
Jan 20 Vue.js
vue 中this.$set 动态绑定数据的案例讲解
Jan 29 Vue.js
如何在 Vue 中使用 JSX
Feb 14 Vue.js
关于Vue Router的10条高级技巧总结
May 06 Vue.js
Vue接口封装的完整步骤记录
May 14 Vue.js
详细聊聊vue中组件的props属性
Nov 02 Vue.js
详解Vue router路由
Nov 20 Vue.js
VUE中的v-if与v-show区别介绍
Mar 13 Vue.js
vue实现input输入模糊查询的三种方式
Aug 14 Vue.js
vue3.0 项目搭建和使用流程
Mar 04 #Vue.js
vue 数据双向绑定的实现方法
Mar 04 #Vue.js
vue3.0中使用element的完整步骤
Mar 04 #Vue.js
VUE实现吸底按钮
Mar 04 #Vue.js
vue实现可移动的悬浮按钮
Mar 04 #Vue.js
vue中axios封装使用的完整教程
Mar 03 #Vue.js
详解Vue.js 可拖放文本框组件的使用
Mar 03 #Vue.js
You might like
咖啡因含量是由谁决定的?低因咖啡怎么来?低因咖啡适合什么人喝
2021/03/06 新手入门
社区(php&amp;&amp;mysql)五
2006/10/09 PHP
PHP使用递归生成文章树
2015/04/21 PHP
CodeIgniter常用知识点小结
2016/05/26 PHP
javascript游戏开发之《三国志曹操传》零部件开发(二)人物行走的实现
2013/01/23 Javascript
在ASP.NET中使用JavaScript脚本的方法
2013/11/12 Javascript
JavaScript前补零操作实例
2015/03/11 Javascript
详解AngularJS中module模块的导入导出
2015/12/10 Javascript
使用nodejs下载风景壁纸
2017/02/05 NodeJs
SelectPage v2.4 发布新增纯下拉列表和关闭分页功能
2017/09/07 Javascript
详解Vue路由History mode模式中页面无法渲染的原因及解决
2017/09/28 Javascript
web3.js增加eth.getRawTransactionByHash(txhash)方法步骤
2018/03/15 Javascript
nodejs用gulp管理前端文件方法
2018/06/24 NodeJs
JavaScript中的 new 命令
2019/05/22 Javascript
js获取 gif 的帧数的代码实例
2019/09/10 Javascript
jQuery实现倒计时功能完整示例
2020/06/01 jQuery
[03:32]2014DOTA2西雅图邀请赛 CIS外卡赛赛前black专访
2014/07/09 DOTA
Python的__builtin__模块中的一些要点知识
2015/05/02 Python
Python实现二叉堆
2016/02/03 Python
Python图像处理之简单画板实现方法示例
2018/08/30 Python
celery4+django2定时任务的实现代码
2018/12/23 Python
利用python和百度地图API实现数据地图标注的方法
2019/05/13 Python
解决Django Static内容不能加载显示的问题
2019/07/28 Python
Flask项目中实现短信验证码和邮箱验证码功能
2019/12/05 Python
python绘制动态曲线教程
2020/02/24 Python
PyQt5如何将.ui文件转换为.py文件的实例代码
2020/05/26 Python
如何以Winsows Service方式运行JupyterLab
2020/08/30 Python
Reebonz中国官网:新加坡奢侈品购物网站
2017/03/17 全球购物
莱德杯高尔夫欧洲官方商店:Ryder Cup Shop
2019/08/14 全球购物
Diesel美国网上商店:意大利牛仔时装品牌
2020/12/10 全球购物
美国狗旅行和户外用品领先供应商:kurgo
2020/08/18 全球购物
领导干部培训感言
2014/01/23 职场文书
计算机学生求职信范文
2014/01/30 职场文书
四风问题原因分析及整改措施
2014/10/24 职场文书
失职检讨书大全
2015/01/26 职场文书
Spring事务管理下synchronized锁失效问题的解决方法
2022/03/31 Java/Android