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使用vant中的checkbox实现全选功能
Nov 17 Vue.js
在Vue中使用CSS3实现内容无缝滚动的示例代码
Nov 27 Vue.js
vue+element_ui上传文件,并传递额外参数操作
Dec 05 Vue.js
vue+element实现动态加载表单
Dec 13 Vue.js
Vue中ref和$refs的介绍以及使用方法示例
Jan 11 Vue.js
Vue实现圆环进度条的示例
Feb 06 Vue.js
Vue实现todo应用的示例
Feb 20 Vue.js
vue实现倒计时功能
Mar 24 Vue.js
Vue中插槽slot的使用方法与应用场景详析
Jun 08 Vue.js
vue整合百度地图显示指定地点信息
Apr 06 Vue.js
vue elementUI批量上传文件
Apr 26 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
php异常:Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE  eval()'d code error
2011/05/19 PHP
php生成zip文件类实例
2015/04/07 PHP
隐藏Nginx或Apache以及PHP的版本号的方法
2016/01/03 PHP
js实现数组去重、判断数组以及对象中的内容是否相同
2013/11/29 Javascript
JavaScript获取XML数据附示例截图
2014/03/05 Javascript
file控件选择上传文件确定后触发的js事件是哪个
2014/03/17 Javascript
js 验证身份证信息有效性
2014/03/28 Javascript
jQuery中noconflict函数的实现原理分解
2015/02/03 Javascript
jQuery晃动层特效实现方法
2015/03/09 Javascript
只需五句话搞定JavaScript作用域(经典)
2016/07/26 Javascript
轻松掌握JavaScript代理模式
2016/08/26 Javascript
JavaScript trim 实现去除字符串首尾指定字符的简单方法
2016/12/27 Javascript
详解Vue路由History mode模式中页面无法渲染的原因及解决
2017/09/28 Javascript
JS添加或删除HTML dom元素的方法实例分析
2019/03/05 Javascript
python获得一个月有多少天的方法
2015/06/04 Python
python 3.5实现检测路由器流量并写入txt的方法实例
2017/12/17 Python
Python+selenium 获取一组元素属性值的实例
2018/06/22 Python
Python实现九宫格式的朋友圈功能内附“马云”朋友圈
2019/05/07 Python
python 机器学习之支持向量机非线性回归SVR模型
2019/06/26 Python
Python3 pandas 操作列表实例详解
2019/09/23 Python
iPython pylab模式启动方式
2020/04/24 Python
使用python实现名片管理系统
2020/06/18 Python
在django中查询获取数据,get, filter,all(),values()操作
2020/08/09 Python
html5给汉字加拼音加进度条的实现代码
2020/04/07 HTML / CSS
阿迪达斯印度官方商城:adidas India
2017/03/26 全球购物
L*SPACE官网:比基尼、泳装和度假服装
2019/03/18 全球购物
Joseph官网:英国小众奢侈品牌
2019/05/17 全球购物
什么是数据抽象
2016/11/26 面试题
结婚典礼证婚词
2014/01/08 职场文书
《唯一的听众》教学反思
2014/02/20 职场文书
学生会副主席竞聘书
2014/03/31 职场文书
检察机关个人对照检查材料
2014/09/15 职场文书
企业与个人合作经营协议书
2014/11/01 职场文书
社区党员群众路线教育实践活动心得体会
2014/11/03 职场文书
2014年就业工作总结
2014/11/26 职场文书
装修公司管理制度
2015/08/05 职场文书