一、封装轮播组件
1. 首先来捋一下大概的思路
- 组成部分大概有: 最外层盒子包裹, 需要轮播的部分, 指示器 和 左右两边的方向指示器
- 需要设置的属性以及默认值:
Property Deacription type default autoplay 是否开启自动播放 Boolean true duration 滑动间隔时长 Number 3000 instial 默认显示第几项(下标) Number 0 hasDot 是否显示指示器 Boolean true hasDirector 是否显示方向指示器 Boolean true dotBgColor 指示器背景色 String #ff5000 dirBgColor 方向指示器颜色 String #fff
2. 创建项目以及对应文件
- 首选创建一个最简化的 vue2.0 项目, 项目创建这边就不进行细述了
- 项目创建完成, 在 src 目录下创建目录以及文件, index.js文件时入口文件, Carousel 目录中存放的则是轮播图的各个模块
3. 进行代码编写 (整个编写流程, 这边不太好讲解, 所以只能把对应文件的 所有代码贴出)
- 编写最外层盒子, 在 Carousel 目录下新建 index.vue 文件
<template>
<div
class="carousel"
@mouseenter="mouseEnter"
@mouseleave="mouseLeave"
>
<div class="inner">
<slot></slot>
</div>
<!-- 指示器 -->
<DotCar
:currentIndex="currentIndex"
:itemLen="itemLen"
:hasDot="hasDot"
:dotBgColor="dotBgColor"
@dotClick="dotClick"
/>
<!-- 两个方向指示器 -->
<DriCar
v-if="hasDirector"
dir="next"
@dirClick="dirClick"
class="dri-next"
:dirBgColor="dirBgColor"
/>
<DriCar
v-if="hasDirector"
dir="prev"
@dirClick="dirClick"
class="dri-prev"
:dirBgColor="dirBgColor"
/>
</div>
</template>
<script>
import DotCar from './Dot.vue'
import DriCar from './Driector.vue'
export default {
name: 'Carousel',
components: {
DotCar,
DriCar
},
props: {
// 是否自动播放
autoplay: {
type: Boolean,
default: true
},
// 切换时长
duration: {
type: Number,
default: 6000
},
// 默认显示哪一项
instial: {
type: Number,
default: 0
},
// 是否展示指示器
hasDot: {
type: Boolean,
default: true
},
// 是否展示方向按钮
hasDirector: {
type: Boolean,
default: true
},
// 指示器背景色
dotBgColor: String,
// 方向指示器的颜色
dirBgColor: String
},
data() {
return{
currentIndex: this.instial,
time: null, // 定义一个计时器
itemLen: 0, // 轮播的数组长度
}
},
methods: {
// 自动轮播的方法
autoPlayFn() {
if(this.autoplay) {
this.time = setInterval(() => {
this.setIndexFn('next')
}, this.duration)
}
},
// 处理轮播的方向 和
// dir 表示轮播的方向
setIndexFn(dir) {
switch(dir) {
case 'next':
this.currentIndex +=1;
if(this.currentIndex === this.itemLen) {
this.currentIndex = 0
}
break;
case 'prev':
this.currentIndex -=1;
if(this.currentIndex === -1) {
this.currentIndex = this.itemLen - 1
}
break;
}
},
// 选中指示器, 修改展示下标为当前下标
dotClick(index) {
this.currentIndex = index
},
// 鼠标移入事件
mouseEnter() {
this.clearInter()
},
// 鼠标移出事件
mouseLeave() {
this.autoPlayFn()
},
// 左右指示器点击事件
dirClick(val) {
this.setIndexFn(val)
},
//清除定时器
clearInter() {
clearInterval(this.time);
this.time = null
}
},
// 执行自动播放
mounted() {
// 通过 this.$slots 获取到子组件的长度( 也就是遍历了多少项(轮播有多少项))
this.itemLen = this.$slots.default.length
this.autoPlayFn()
},
// 清除定时器, 并置空 time
beforeDestroy() {
this.clearInter()
}
}
</script>
<style scoped>
.carousel{
position: relative;
width: 100%;
height: 100%;
}
.inner{
width: 100%;
height: 100%;
overflow: hidden;
}
.dri-next{
left: 0;
}
.dri-prev{
right: 0;
}
</style>
- 编写需要轮播的选项, 在 Carousel 目录下新建 Item.vue 文件
<template>
<!-- 利用 transition 标签来完成动画的过渡 -->
<transition>
<div class="car-item" v-if="selfIndex === currentIndex">
<slot></slot>
</div>
</transition>
</template>
<script>
export default {
name: 'CarItem',
data() {
return{
selfIndex: '',
currentIndex:''
}
},
mounted() {
// 在 this.$parent 中 可以直接获取到上一级的 props 中所有属性
// this._self 获取当前实例
this.selfIndex = this._self.$vnode.key
this.currentIndex = this.$parent.currentIndex
},
// 监听下标的变化 (监听 this.$parent.currentIndex)
watch: {
'$parent.currentIndex': function (val, oldVal) {
this.currentIndex = val
}
}
}
</script>
<style scoped>
.car-item{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.v-enter-active,
.v-leave-active {
/* 所有样式在 0.3s 的时候, 执行 linear 动画
linear 表示动画从头到尾的速度是相同的
*/
transition: all .3s linear;
}
/* 进入 */
.v-enter-active {
transition: translateX(100%);
}
.v-enter-to{
transition: translateX(0);
}
/* 离开 */
.v-leave-active{
transition: translateX(0);
}
.v-leave-to {
transition: translateX(-100%);
}
</style>
- 在入口文件 index.js 中注册
import Vue from 'vue';
import Carousel from './Carousel/index.vue';
import CarIterm from './Carousel/Item.vue';
let JscyUI = {}
// 全局注册组件
JscyUI.install = ((Vue) => {
// Vue.component('组件name', 组件本身)
Vue.component(Carousel.name, Carousel);
Vue.component(CarIterm.name, CarIterm)
})
// 将组件暴露
export default JscyUI;
4. 这边可以先对写好的组件, 进行简单的使用
- 在 main.js 中引入
-
在 app.vue页面中直接使用 ( 使用时需要注意的是:要给包裹轮播组件的 div 设置宽高, 否则显示不出来 )
!!! 在这里呢, 一个大概的轮播已经成型, 下面我们可以看着页面来编写剩下的两个块指示器部分
5. 指示器的编写
- 新建 Dot.vue 文件, 编写底部指示器
<template>
<div class="dot-wrapper">
<div
class="dot-item"
v-for="item in itemLen"
:key="item"
>
<a
class="dot-link"
href="javascript:;"
:style="{backgroundColor: (item - 1) === currentIndex ? dotBgColor : '#fff'}"
@click="chooseCurrent(item - 1)"
></a>
</div>
</div>
</template>
<script>
export default {
name: 'Dot',
props: {
itemLen: Number, // 轮播的张数
currentIndex: Number, // 当前下标
// 是否展示 指示器
hasDot: {
type: Boolean,
default: true
},
// 指示器背景颜色
dotBgColor: {
type: String,
default: '#ff5000'
}
},
methods: {
// 指示器点击事件
chooseCurrent(index) {
// console.log('点击')
this.$emit('dotClick', index)
}
}
}
</script>
<style scoped>
.dot-wrapper{
width: 100%;
height: 20px;
position: absolute;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
}
.dot-item{
margin: 2px;
}
.dot-item .dot-link{
display: block;
width: 8px;
height: 8px;
border-radius: 8px;
}
</style>
- 新建 Driector.vue 文件, 编写左右两侧方向指示器
<template>
<div class="driector">
<div v-if="dir === 'prev'">
<a
href="javascript:;"
@click="dirClick('prev')"
class="link-dir iconfont icon-the_next_step"
:style="{color: dirBgColor}"
></a>
</div>
<div v-if="dir === 'next'">
<a
href="javascript:;"
@click="dirClick('next')"
class="link-dir iconfont icon-the_previous_step"
:style="{color: dirBgColor}"
></a>
</div>
</div>
</template>
<script>
export default {
name: 'Driector',
props: {
dir: String,
dirBgColor: {
type: String,
default: '#fff'
}
},
methods: {
dirClick(val) {
this.$emit('dirClick', val)
}
}
}
</script>
<style scoped>
@import url('./iconfont/iconfont.css');
.driector{
position: absolute;
top: 0;
width: 20px;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 5px;
}
.link-dir{
text-decoration: none;
font-size: 18px;
}
</style>
- 到这里两块指示器已经编写完成, 具体用法, 直接参考上面 inde.vue 文件, 其实写到这里, 整个轮播组件也已经编写完成
二、如何发布到 npm 上
1. 准备好需要发布的文件
-
在最外层 package.json 中进行打包配置
"package": "vue-cli-service build --target lib ./src/libs/jscy-ui/index.js --dest carouselSlide --name carousel"
- 执行 npm run package 进行打包, 生成 carouselSlide 目录
- 新建 package 目录
- 将 carouselSlide 目录中的 carousel.umd.min.js 复制到 package 目录下
- 将 carouselSlide 目录中的 .css 样式文件 复制到 package 目录下
- 初始化package目录, npm init -y 生成 package.json 文件
- 配置 package.json 文件(我这边只做了简单配置)
2. 对 npm 进行操作
- 首先进到 npm 首页 , 在进行登录, 如果刚注册的, 注意一定要进行邮箱激活
- 使用 nrm ls 查看当前源是否是 npm 官方源, 不是则需要切回
- 没有 nrm , 使用 npm i nrm -g 进行安装
- 使用 nrm use npm 切回到 npm 官方源
- 在终端登录 npm
执行 npm login
-
输入账号密码邮箱进行登录
-
执行 npm publish 进行发布
-
到此时已经发布成功, 刷新 npm 就可以看到