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 表单输入框不支持focus及blur事件的解决方案
Nov 17 Vue.js
vue 在单页面应用里使用二级套嵌路由
Dec 19 Vue.js
vue项目如何监听localStorage或sessionStorage的变化
Jan 04 Vue.js
vue element el-transfer增加拖拽功能
Jan 15 Vue.js
Vue.js 带下拉选项的输入框(Textbox with Dropdown)组件
Apr 17 Vue.js
详解Vue的sync修饰符
May 15 Vue.js
vue2实现provide inject传递响应式
May 21 Vue.js
Vue过滤器(filter)实现及应用场景详解
Jun 15 Vue.js
详解gantt甘特图可拖拽、编辑(vue、react都可用 highcharts)
Nov 27 Vue.js
Vue如何清空对象
Mar 03 Vue.js
vue生命周期钩子函数以及触发时机
Apr 26 Vue.js
vue实现在data里引入相对路径
Jun 05 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出错界面
2006/10/09 PHP
PHP 线程安全与非线程安全版本的区别深入解析
2013/08/06 PHP
PHP程序员常见的40个陋习,你中了几个?
2014/11/20 PHP
php堆排序实现原理与应用方法
2015/01/03 PHP
php给每个段落添加空格的方法
2015/03/20 PHP
PHP生成plist数据的方法
2015/06/16 PHP
js 动态文字滚动的例子
2011/01/17 Javascript
探索Emberjs制作一个简单的Todo应用
2012/11/07 Javascript
javascript简单实现图片预加载
2014/12/03 Javascript
javascript的replace方法结合正则使用实例总结
2016/06/16 Javascript
Angular 4依赖注入学习教程之FactoryProvider配置依赖对象(五)
2017/06/04 Javascript
分分钟学会vue中vuex的应用(入门教程)
2017/09/14 Javascript
详解如何快速配置webpack多入口脚手架
2018/12/28 Javascript
使用Vue中 v-for循环列表控制按钮隐藏显示功能
2019/04/23 Javascript
javascript中如何判断类型汇总
2019/05/14 Javascript
vue控制多行文字展开收起的实现示例
2019/10/11 Javascript
微信小程序点击生成朋友圈分享图(遇到的坑)
2020/06/17 Javascript
Python实现的最近最少使用算法
2015/07/10 Python
Python元组操作实例分析【创建、赋值、更新、删除等】
2017/07/24 Python
Python如何通过subprocess调用adb命令详解
2017/08/27 Python
Python配置mysql的教程(推荐)
2017/10/13 Python
Python排序搜索基本算法之选择排序实例分析
2017/12/09 Python
Pycharm+Scrapy安装并且初始化项目的方法
2019/01/15 Python
Python读取stdin方法实例
2019/05/24 Python
PyTorch加载自己的数据集实例详解
2020/03/18 Python
python递归函数求n的阶乘,优缺点及递归次数设置方式
2020/04/02 Python
使用Html5 Stream开发实时监控系统
2020/06/02 HTML / CSS
英国Iceland杂货店:网上食品购物
2020/12/16 全球购物
团委书记的竞聘演讲稿
2014/04/24 职场文书
《他得的红圈圈最多》教学反思
2014/04/24 职场文书
化工操作工岗位职责
2014/04/29 职场文书
春节超市活动方案
2014/08/14 职场文书
医药公司采购员岗位职责
2014/09/12 职场文书
好媳妇事迹材料
2014/12/24 职场文书
面试复试通知单
2015/04/24 职场文书
利用JavaScript写一个简单计算器
2021/11/27 Javascript