工作中封装的一些移动端轮播组件 用的是 vue写的 react后期有时间的话会补上
2020-01-13 01:39
489 查看
原理什么的就不说了 这些都比较简单 直接上代码 来点干货 下图是我的文件目录
components 是子组件 page放的父组件 一共封装了四种 最后引入home里
第一种 原生js实现
page文件里的 Lunbo组件 index.vue
<template> <div class='Lunbo'> <div v-if="swiperList.length" class="slider-wrapper" ref="sliderWrapper"> <!-- 第一种方案(原生) --> <h3>第一种方案(原生)</h3> <protogenesis-swiper ref="swiper"> <protogenesis-swiper-item v-for="item in swiperList" :key="item.id"> <a :href="item.linkUrl"> <img :src="item.imgUrl" alt=""> </a> </protogenesis-swiper-item> </protogenesis-swiper> </div> </div> </template> <script> // 第一种方案(原生) import ProtogenesisSwiper from '../../components/ProtogenesisSwiper' import ProtogenesisSwiperItem from '../../components/ProtogenesisSwiperItem' export default { name: "Lunbo", data() { return { swiperList: [ { imgUrl: require("../../assets/img/lun.1.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "1" }, { imgUrl: require("../../assets/img/lun.2.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "2" }, { imgUrl: require("../../assets/img/lun.3.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "3" }, { imgUrl: require("../../assets/img/lun.1.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "4" }, { imgUrl: require("../../assets/img/lun.5.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "5" }, { imgUrl: require("../../assets/img/lun.2.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "6" } ] }; }, components: { ProtogenesisSwiper, ProtogenesisSwiperItem }, methods: { // 启动轮播图(原生实现) startTimer() { this.$refs.swiper && this.$refs.swiper.startTimer && this.$refs.swiper.startTimer(); }, // 停止轮播图(原生实现) stopTimer() { this.$refs.swiper && this.$refs.swiper.stopTimer && this.$refs.swiper.stopTimer(); } }, destroyed() { // 停止轮播图(原生实现) this.stopTimer(); } }; </script> <style lang="scss" scoped> </style>
components 里面的ProtogenesisSwiper 文件夹 index.vue
<template> <div id="hy-swiper"> <div class="swiper" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd"> <slot></slot> </div> <slot name="indicator"></slot> <div class="indicator"> <slot name="indicator" v-if="showIndicator && slideCount>1"> <div v-for="(item, index) in slideCount" class="indi-item" :class="{active: index === currentIndex-1}" :key="index" ></div> </slot> </div> </div> </template> <script> export default { name: "ProtogenesisSwiper", props: { // interval: 每次定时器的间隔时间 interval: { type: Number, // default: 默认的内容 default: 3000 }, // animDuration: 每一张图片切换的时间 animDuration: { type: Number, default: 300 }, // moveRation: 手指移动对应的距离切换到下一张 moveRatio: { type: Number, default: 0.25 }, // showIndicator: 是否开启指示器 showIndicator: { type: Boolean, default: true } }, data() { return { slideCount: 0, // 元素个数 totalWidth: 0, // swiper的宽度 swiperStyle: {}, // swiper样式 currentIndex: 1, // 当前的index scrolling: false // 是否正在滚动 }; }, mounted() { // 1.操作DOM, 在前后添加 Slider setTimeout(() => { this.handleDom(); // 2.开启定时器 this.startTimer(); }, 100); }, methods: { /** * 开启定时器 */ startTimer() { this.playTimer = window.setInterval(() => { this.currentIndex++; this.scrollContent(-this.currentIndex * this.totalWidth); }, this.interval); }, /** * 停止定时器 */ stopTimer() { window.clearInterval(this.playTimer); }, /** * 滚动到正确位置 */ scrollContent(currentPosition) { // 1.设置滚动开始 this.scrolling = true; // 2.开始滚动动画 this.swiperStyle.transition = "transform" + this.aninDuration + "ms"; this.setTransform(currentPosition); // 3.判断滚动的位置 this.checkPosition(); // 4.滚动完成 this.scrolling = false; }, /** * 校验正确的位置 */ checkPosition() { window.setTimeout(() => { // 1.校验正确的位置 this.swiperStyle.transition = "0ms"; // 判断临界点 if (this.currentIndex >= this.slideCount + 1) { this.currentIndex = 1; this.setTransform(-this.currentIndex * this.totalWidth); // 判断当前的索引值是否小于或者等于 0 } else if (this.currentIndex <= 0) { this.currentIndex = this.slideCount; this.setTransform(-this.currentIndex * this.totalWidth); } // 2.结束移动后的回调 this.$emit("transitionEnd", this.currentIndex - 1); }, this.animDuration); }, /** * 设置滚动的位置 */ setTransform: function(position) { this.swiperStyle.transform = `translate3d(${position}px, 0, 0)`; this.swiperStyle[ "-webkit-transform" ] = `translate3d(${position}px), 0, 0`; this.swiperStyle["-ms-transform"] = `translate3d(${position}px), 0, 0`; }, /** * 操作DOM, 在DOM前后添加Slide */ handleDom: function() { // 1.获取要操作的元素 let swiperEl = document.querySelector(".swiper"); let slidesEls = swiperEl.getElementsByClassName("slide"); // 2.保存个数 this.slideCount = slidesEls.length; // 3.如果大于1个, 那么在前后分别添加一个slide if (this.slideCount > 1) { let cloneFirst = slidesEls[0].cloneNode(true); let cloneLast = slidesEls[this.slideCount - 1].cloneNode(true); // 添加标签插入到相对应的位置 swiperEl.insertBefore(cloneLast, slidesEls[0]); swiperEl.appendChild(cloneFirst); // 设置 totalWidth 来接收 swiperEl的可以区域的宽度 this.totalWidth = swiperEl.offsetWidth; // 设置 swiperStyle 来接收 swiperEl 的属性 this.swiperStyle = swiperEl.style; } // 4.让swiper元素, 显示第一个(目前是显示前面添加的最后一个元素) this.setTransform(-this.totalWidth); }, /** * 拖动事件的处理 */ touchStart: function(e) { // 1.如果正在滚动, 不可以拖动 if (this.scrolling) return; // 2.停止定时器 this.stopTimer(); // 3.保存开始滚动的位置 this.startX = e.touches[0].pageX; }, /** * 手指移动事件 */ touchMove: function(e) { // 1.计算出用户拖动的距离 this.currentX = e.touches[0].pageX; this.distance = this.currentX - this.startX; let currentPosition = -this.currentIndex * this.totalWidth; let moveDistance = this.distance + currentPosition; // 2.设置当前的位置 this.setTransform(moveDistance); }, /** * 手指抬起事件 */ touchEnd: function(e) { // 1.获取移动的距离 let currentMove = Math.abs(this.distance); // 2.判断最终的距离 if (this.distance === 0) { return; } else if ( this.distance > 0 && currentMove > this.totalWidth * this.moveRatio ) { // 右边移动超过0.5 this.currentIndex--; } else if ( this.distance < 0 && currentMove > this.totalWidth * this.moveRatio ) { // 向左移动超过0.5 this.currentIndex++; } // 3.移动到正确的位置 this.scrollContent(-this.currentIndex * this.totalWidth); // 4.移动完成后重新开启定时器 this.startTimer(); }, /** * 控制上一个, 下一个 */ previous: function() { this.changeItem(-1); }, next: function() { this.changeItem(1); }, changeItem: function(num) { // 1.移除定时器 this.stopTimer(); // 2.修改index和位置 this.currentIndex += num; this.scrollContent(-this.currentIndex * this.totalWidth); // 3.添加定时器 this.startTimer(); } } }; </script> <style lang="scss" scoped> #hy-swiper{ overflow: hidden; position: relative; } .swiper{ display: flex; } .indicator{ display: flex; justify-content: center; position: absolute; width: 100%; bottom: 0.2rem; } .indi-item{ box-sizing: border-box; width:0.15rem; height:0.15rem; border-radius: 50%; line-height:0.2rem; text-align:center; font-size: 12px; margin-right:0.08rem; border: 1px solid rgba(0,0,0,.05); background: rgba(255,255,255,.4); } .indi-item.active{ background: #FFF; } </style>
components 里面的ProtogenesisSwiperItem 文件夹 index.vue
<template> <div class="slide"> <slot></slot> </div> </template> <script> export default { name: "Slide" }; </script> <style lang="scss" scoped> .slide{ width: 100%; flex-shrink: 0; } .slide img{ width: 100%; } </style>
上张图片吧 没做效果视频
**第二种方式 原生zoom缩放 **
page 文件里 Lunbo2
<template> <div> <Lunbo :list="this.list" height="3.4rem" :options="this.options" effect="zoom"></Lunbo> </div> </template> <script> import Lunbo from '../../components/carousel' export default { name: "lunbo", data() { return { list: [ { img: require("../../assets/img/lun.1.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "1" }, { img: require("../../assets/img/lun.2.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "2" }, { img: require("../../assets/img/lun.3.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "3" }, { img: require("../../assets/img/lun.1.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "4" }, { img: require("../../assets/img/lun.5.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "5" }, { img: require("../../assets/img/lun.2.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "6" } ], options:{ showDots: true, // 是否显示分页器 interval: 3000, // 轮播间隔时间,默认3s autoplay: true, // 是否自动播放 loop: true // 是否循环轮播 } }; }, components: { Lunbo }, methods: { }, }; </script> <style lang="scss" scoped> </style>
components 里面的carousel index.vue
<template> <div class="swiper-component" @touchstart="onTouchStart" @touchend="onTouchEnd" :style="{height:height}"> <H3>第二种方式 原生zoom缩放</H3> <ul :style="[ulStyle, swiperStyle]"> <li v-for="(item, ind) in list" :key="ind" :style="{width: itemWidth + 'px'}" :class="[index===ind?'active':'', effect]" @click="handleClick(item)"> <a :href="item.linkUrl"> <img :src="item.img"> </a> </li> </ul> <div v-show="options.showDots" class="swiper-dots"> <div v-for="(item, ind) in list" :key="ind" class="dots-item" :class="{active:index===ind}"></div> </div> </div> </template> <script> export default { name:'Lunbo2', data() { return { ulStyle: { width: "7.5rem", paddingLeft: "0.2rem" }, // 轮播图容器宽度 itemWidth: 750, // 单个轮播图容器的宽度,默认屏幕宽度, swiperStyle: {}, // 控制轮播的样式 index: 0, // 当前显示的轮播图索引,默认第一张 touchStart: {}, // 触摸开始点位 touchEnd: {}, // 触摸结束点位 intervalTime: "" // 循环轮播定时器 }; }, props: { height: { type: String, default: "3rem" }, options: { type: Object, default: { showDots: false, // 是否显示分页器 interval: 3000, // 轮播间隔时间,默认3s autoplay: true, // 是否自动播放 loop: true // 是否循环轮播 } }, list: { type: Array, default: [] }, effect: { type: String, default: "normal" // 轮播图的样式类型,默认正常类型 normal,可选:zoom(缩放) } }, mounted() { this.calcWidth(); this.handleLoopMove(); }, methods: { /** * 初始化时的一些宽度计算操作 */ calcWidth() { // 页面更新后执行宽度计算 this.$nextTick(function() { if (this.effect === "normal") { // 如果是正常模式,一张图的宽度为屏幕宽度 this.itemWidth = document.body.clientWidth; // 获取屏幕的宽度 } else if (this.effect === "zoom") { // 如果是缩放模式,控制轮播图显示的宽度,两边流出空隙 this.itemWidth = document.body.clientWidth - 40; // 获取屏幕的宽度 } this.handleType(); var length = this.list.length; // 获取列表的个数 this.ulStyle.width = parseInt((this.itemWidth + 40) * length) + "px"; // 容器总宽度 }); }, /** * 轮播图点击事件 */ handleClick(val) { // 触发外部事件,将点击的轮播图详情数据返回 this.$emit("onClick", val); }, /** * 判断轮播类型,根据类型执行对应的操作 */ handleType() { if (this.effect === "normal") { this.ulStyle.paddingLeft = 0; // 将起始位置左侧的padding置为0 } else if (this.effect === "zoom") { this.ulStyle.paddingLeft = "20px"; // 保证左侧有一定的位移 } }, /** * 移动处理 */ handleMove() { let moveX = this.itemWidth * this.index; if (this.index === 0) { moveX = 0; this.handleType(); } else { this.ulStyle.paddingLeft = 0; // 将起始位置左侧的padding置为0 if (this.effect === "zoom") { moveX = moveX - 20; } } this.swiperStyle = { transform: "translateX(-" + moveX + "px)" }; }, /** * 循环移动处理 */ handleLoopMove() { // 当设置自动播放时,执行自动循环播放操作,否则,只执行下一次轮播效果 if (this.options.autoplay) { let interval = this.options.interval ? this.options.interval : 3000; this.intervalTime = setInterval(() => { this.index++; if (this.index > this.list.length - 1) { this.index = 0; // 置为-1,下次轮播时index就会变成0,图片定位到起始位置 } this.handleMove(); }, interval); } }, /** * 触摸开始事件,记录下触摸点 */ onTouchStart(e) { this.touchStart = e.changedTouches[0]; // 记录开始触摸点 // 清除定时器 clearInterval(this.intervalTime); }, /** * 触摸结束事件,记录下触摸点,比较当前点和触摸开始点,判断触摸方向 */ onTouchEnd(e) { this.touchEnd = e.changedTouches[0]; // 比较移动的点位差,正数就是右滑,负数就是左滑 if (this.touchEnd.clientX - this.touchStart.clientX > 60) { this.index--; if (this.index <= 0) { this.index = 0; } } else if (this.touchEnd.clientX - this.touchStart.clientX < -60) { this.index++; if (this.index >= this.list.length - 1) { this.index = this.list.length - 1; } } // 处理当前的滑动 this.handleMove(); // 同时开启自动轮播 this.handleLoopMove(); } }, watch: { list: function(e) { this.calcWidth(); } }, destroyed() { // 清除定时器 if (this.autoplay) { clearInterval(this.intervalTime); } } }; </script> <style lang="scss" scoped> .swiper-component { overflow: hidden; height: 3rem; position: relative; ul { white-space: nowrap; height: 100%; transition: 0.5s ease; li { list-style: none; height: 100%; float: left; overflow: hidden; img { width: 100%; height: 100%; } &.zoom { border-radius: 0.16rem; transform: scale(0.93); transition: 0.5s ease; &.active { transform: scale(1); } } } } .swiper-dots { position: absolute; bottom: 0.16rem; left: 50%; transform: translateX(-50%); display: flex; .dots-item { width: 0.1rem; height: 0.1rem; border-radius: 50%; background: rgba(255, 255, 255, 0.7); margin: 0rem 0.04rem; &.active { background: #409eff; } } } } </style>
上张图片 两边留边
第三种方案(better-scroll) 现在特别火的一款插件
需要下载插件
npm install better-scroll --save
page 里面的 Lunbo3
<template> <div class='some'> <div v-if="swiperList.length" class="slider-wrapper" ref="sliderWrapper"> <h3 style="margin-top: 30px;">第三种方案(better-scroll)</h3> <slider> <div v-for="item in swiperList" :key="item.id"> <a :href="item.linkUrl"> <img :src="item.imgUrl" alt=""> </a> </div> </slider> </div> </div> </template> <script> import Slider from "../../components/slider"; export default { name: "Lunbo3", data() { return { swiperList: [ { imgUrl: require("../../assets/img/lun.1.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "1" }, { imgUrl: require("../../assets/img/lun.2.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "2" }, { imgUrl: require("../../assets/img/lun.3.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "3" }, { imgUrl: require("../../assets/img/lun.1.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "4" }, { imgUrl: require("../../assets/img/lun.5.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "5" }, { imgUrl: require("../../assets/img/lun.2.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "6" } ] }; }, components: { Slider, } }; </script> <style lang="scss" scoped> .some{ width: 7.5rem; overflow: hidden; } img{ height: 3.5rem; } </style>
components 里面的 slider index.vue
<template> <div class="slider" ref="slider"> <div class="slider-group" ref="sliderGroup"> <slot></slot> </div> <div class="dots"> <span class="dot" v-for="(item, index) in dots" :key="index" :class="{active: currentPageIndex === index}" ></span> </div> </div> </template> <script> import BScroll from "better-scroll"; import { addClass } from "../../util/dom"; export default { name: "Slider", props: { loop: { // 是否无缝循环轮播 type: Boolean, default: true }, autoPlay: { // 是否自动轮博 type: Boolean, default: true }, interval: { // 轮播的毫秒数 type: Number, default: 3000 } }, data() { return { dots: [], currentPageIndex: 0 // 控制器默认的下标 }; }, mounted() { setTimeout(() => { // 设置 slider 的宽度 this._setSliderWidth(); // 初始化控制器 this._initDots(); // 初始化 slider this._initSlider(); // 判断是否开启了循环轮播 if (this.autoPlay) { this._play(); } }, 20); }, destroyed() { clearTimeout(this.timer); }, methods: { // 设置 slider 的宽度 _setSliderWidth() { this.children = this.$refs.sliderGroup.children; let width = 0; let sliderWidth = this.$refs.slider.clientWidth; for (let i = 0; i < this.children.length; i++) { let child = this.children[i]; addClass(child, "slider-item"); child.style.width = sliderWidth + "px"; width += sliderWidth; } if (this.loop) { // 当设置无缝循环轮播的时候, 默认加两张图片的宽度方便滚动 width += 2 * sliderWidth; } // 设置轮播图的总宽度 this.$refs.sliderGroup.style.width = width + "px"; }, // 初始化 slider _initSlider() { this.slider = new BScroll(this.$refs.slider, { scrollX: true, // 滚动方向为 X 轴 scrollY: false, // 滚动方向为 Y 轴 momentum: false, // 当快速滑动时是否开启滑动惯性 snap: { loop: this.loop, // 是否可以无缝循环轮播 threshold: 0.3, // 用手指滑动时页面可切换的阈值,大于这个阈值可以滑动的下一页 speed: 400 // 轮播图切换的动画时间 }, // 该属性是给 slider 组件使用的,普通的列表滚动不需要配置 click: true // 是否派发click事件,通常判断浏览器派发的click还是betterscroll派发的click,可以用_constructed,若是bs派发的则为true }); this.slider.on("scrollEnd", () => { // 滚动结束 let pageIndex = this.slider.getCurrentPage().pageX; this.currentPageIndex = pageIndex; if (this.autoPlay) { this._play(); } }); // 滚动开始之前 this.slider.on("beforeScrollStart", () => { if (this.autoPlay) { clearTimeout(this.timer); } }); }, // 初始化控制器 _initDots() { this.dots = new Array(this.children.length); }, // 开始轮播 _play() { let pageIndex = this.currentPageIndex + 1; this.timer = setTimeout(() => { this.slider.next(); }, this.interval); } } }; </script> <style lang="scss" scoped> .slider{ min-height: 1px; } .slider-group{ position: relative; overflow: hidden; white-space: nowrap; } .slider-item{ float: left; box-sizing: border-box; overflow: hidden; text-align: center; } a{ display: block; width: 100%; overflow: hidden; text-decoration: none; } img{ width: 100%; display: block; } .dots{ position: relative; text-align: center; bottom: 0.3rem; font-size: 0; } .dot{ display: inline-block; margin: 0 4px; width: 8px; height: 8px; border-radius: 50%; background: #fff; &.active{ width: 20px; border-radius: 5px; background: red; } } </style>
建立个文件夹 util 里面的dom.js 引入上面的组件中
export function addClass(el, className){ if(hasClass(el, className)){ // 判断需要添加的类名是否存在 return } // 先将变量转换成数组 let newClass = el.className.split(' '); // 然后将类名添加到数组中 newClass.push(className); // 将数组里面的值转换成字符串] el.className = newClass.join(' '); } export function hasClass(el, className){ let reg = new RegExp('(^|\\s)' + className + '(\\s|$)'); return reg.test(el.className); }
上图
**第四种方案(vue-awesome-swiper) **
page 文件里面的 Lunbo4
<template> <div class='mome'> <div v-if="swiperList.length" class="slider-wrapper" ref="sliderWrapper"> <!-- 第三种方案(vue-awesome-swiper) --> <h3 style="margin-top: 30px;">第四种方案(vue-awesome-swiper)</h3> <swiper :list="swiperList"></swiper> </div> </div> </template> <script> // 第三种方案(vue-awesome-swiper) import Swiper from '../../components/Swiper' export default { name: "Home", data() { return { swiperList: [ { imgUrl: require("../../assets/img/lun.1.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "1" }, { imgUrl: require("../../assets/img/lun.2.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "2" }, { imgUrl: require("../../assets/img/lun.3.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "3" }, { imgUrl: require("../../assets/img/lun.1.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "4" }, { imgUrl: require("../../assets/img/lun.5.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "5" }, { imgUrl: require("../../assets/img/lun.2.jpg"), // 图片路径 linkUrl: "", // 跳转路径 id: "6" } ] }; }, components: { Swiper, }, }; </script> <style lang="scss" scoped> .mome{ width: 7.5rem; overflow: hidden; } .slider-wrapper{ position: relative; } </style>
components 里面的Swiper index.vue
<template> <div> <div class="wrapper"> <swiper :options="swiperOption"> <!-- slides --> <swiper-slide v-for="(img, index) of list" :key="index" ref="mySwiper"> <img class="swiper-img" :src="img.imgUrl" alt="img.imgUrl"> </swiper-slide> <div class="swiper-pagination" slot="pagination"></div> </swiper> </div> </div> </template> <script> export default { name: "Lunbo4", props: { list: { type: Array, default: [] } }, data() { return { swiperOption: { autoplay: { disableOnInteraction: false, //手动滑动后可以自动滑动 delay: 2500 }, loop: true, // 无缝轮播 pagination: { el: ".swiper-pagination" } } }; }, computed: {} }; </script> <style lang="scss" scoped> /* 设置分页器未选中的样式 */ .wrapper >>> .swiper-pagination-bullet{ box-sizing: border-box; width: 8px; height: 8px; border-radius: 4px; background-color: #fff; line-height: 8px; text-align: center; font-size: 12px; margin: 0 5px; } /* 设置分页器选中的样式 */ .wrapper >>> .swiper-pagination-bullet-active{ width: 20px; border-radius: 5px; background-color: rgba(212, 62, 46, 1); } .wrapper{ width: 100%; overflow: hidden; background :#eee; .swiper-img{ width: 100%; } } img{ height: 3.5REM; } </style>
在min.js 里引入
import VueAwesomeSwiper from 'vue-awesome-swiper' import 'swiper/dist/css/swiper.css' Vue.use(VueAwesomeSwiper)
最后 引入到自己想放入的组件中 我是放到 home组件里了 样式什么的自己微调一下吧
<template> <div class='home'> <lunbo1></lunbo1> <Lunbo2></Lunbo2> <Lunbo3></Lunbo3> <Lunbo4></Lunbo4> </div> </template> <script> import Lunbo1 from '../page/Lunbo' import Lunbo2 from '../page/Lunbo2' import Lunbo3 from '../page/Lunbo3' import Lunbo4 from '../page/Lunbo4' export default { name: "home", data() { return { }; }, components: { Lunbo3, Lunbo1, Lunbo2, Lunbo4 }, methods: { }, }; </script> <style lang="scss" scoped> .home{ height: 100%; width: 7.5rem; } </style>
如果觉得哪里写得有问题 欢迎指正!!
- 点赞 2
- 收藏
- 分享
- 文章举报
相关文章推荐
- 利用Vue实现移动端图片轮播组件的方法实例
- 【vue 组件 mint-ui】 看了一下源码,给轮播图Swiper封装自定义跳转的函数
- 时间日期工具类 封装工作中常用的一些时间日期计算方法(转+自己修改)
- Omi-touch实战 移动端图片轮播组件的封装
- vue移动端轻量级的轮播组件实现代码
- wc-swiper:基于 Vue 实现的 移动端图片轮播组件
- vue.js移动端tab组件的封装实践实例
- vue封装一个简单的div框选时间的组件的方法
- 封装Vue组件的一些技巧
- Vue2.0 多 Tab切换组件的封装实例
- 移动端商城 Vue 组件库
- Vue开发之封装上传文件组件与用法示例
- react-native IOS端原生组件封装步骤
- vue 父子组件的一些问题
- 基于cropper.js封装vue在线图片裁剪组件
- vue中组件的封装,组件间的传值
- Vue实现内部组件轮播切换效果的示例代码
- vue移动端微信授权登录插件封装的实例
- vue 2.0封装model组件的方法
- React-Native中一些常用组件的用法详解(二)