内容简介:最近做的商城项目需要在首页展示一个轮播图,秉承着“有现成轮子就绝不自己写”(其实是懒和菜)的想法,在网上搜索了一下,最后选择使用前两个其实是一样的问题,我这里轮播图的数据放在
问题复现
最近做的商城项目需要在首页展示一个轮播图,秉承着“有现成轮子就绝不自己写”(其实是懒和菜)的想法,在网上搜索了一下,最后选择使用 vue-awesome-swiper 。安装和使用就不说了,可以直接看 GitHub 的文档。按照文档写完基础结构后,实际使用的时候遇到了几个问题:
-
图片轮播到最后一张时自动停止,无法循环播放
-
分页器不显示
-
无法修改分页器样式
前两个其实是一样的问题,我这里轮播图的数据放在 banners
里,一开始没赋值的时候默认是空数组,没有数据,所以这时候会导致轮播图运行不正常。解决这个问题只需要在 swiper
加一个判断就好: v-if="banners.length != 0"
。第三个问题则是因为 style
标签使用了 scoped
声明,导致无法修改第三方组件库的样式。之前写单文件组件都是习惯性地加 scoped
,没有考虑太多。这次遇到了问题,所以花时间研究了一下这个东西,然后查找了一些合适的解决方案,在这里做一个记录。
为什么需要 scoped
官方文档的介绍: https://vue-loader.vuejs.org/guide/scoped-css.html
为了实现样式的模块化、私有化,防止全局样式污染,我们可以给单文件组件中的 style
标签添加 scoped
属性,这样,里面书写的 CSS 样式就只能应用于当前的组件。其原理是通过 PostCSS 实现的,经过编译后, template
中手写的元素会与 style
中的样式通过自定义属性 data-v-xxx
形成对应。也就是说,我们写的样式实际上只对 具有对应自定义属性的元素 生效,而由于这样的元素只存在于组件模板中,所以确保了样式只对当前组件生效。例如:
// test.vue <template> <div> <a><img></a> </div> </template> <style scoped> div img{ width:100%; } </style>
上面的代码经过编译后,实际上会变成:
// test.vue <template> <div data-v-1a0c5ce5> <a data-v-1a0c5ce5> <img data-v-1a0c5ce5> </a> </div> </template> <style scoped> div img[data-v-1a0c5ce5]{ width:100%; } </style>
如果没有加 scoped
,那么宽度 100% 这个样式会作用于所有的图片;由于使用了 scoped
,所以这个样式只对当前组件生效。
同样的,如果是父子组件:
// 父组件 <template> <div> <son> <span>我是插槽</span> </son> </div> </template> <style scoped> .parent .son{ border:2px solid red } .parent .son h1{ color: green } span{ color:yellow } </style> //子组件 <template> <div> <h1>我是子组件</h1> <slot></slot> </div> </template>
我们会发现,可以在父组件中修改子组件根元素( div.son
)以及子组件插槽的样式,但是无法修改子组件子元素( h1
)的样式。在控制台中可以看到,代码编译后是这样的:
<div data-v-1a0c5ce5> <div data-v-1a0c5ce5> <h1>我是子组件</h1> <span data-v-1a0c5ce5>我是插槽</span> </div> </div> <style> .parent .son[data-v-1a0c5ce5]{ border:2px solid red } h1{ color: green } span[data-v-1a0c5ce5]{ color:yellow } </style>
这是因为,不管是子组件根元素还是子组件的插槽,最终都是实际书写在父组件的 template
中的,所以父组件中书写的样式能够对应地在父组件模板中找到 DOM;而子组件的子元素(比如上面的 h1
),它实际上是 在子组件模板书写 的,此时没法通过自定义属性建立样式与 DOM 的对应关系。因此这个样式不生效,这样也就防止了在父组件的层面上修改子组件的样式。
回到一开始的问题
再回到一开始的问题,轮播图的结构大概是这样的:
<template> <swiper> <swiper-slide v-for="item in banners"> <!--渲染部分--> </swiper-slide> <div v-for="item in banners" slot="pagination"></div> </swiper> </template>
div.swiper-pagination
只是包裹每个圆点 span.swiper-pagination-bullets
的容器,实际上没有在 template
中直接书写 span.swiper-pagination-bullets
。这里我看了下源文件,还是没有找到这几个圆点是怎么来的,但可以肯定是动态生成的,所以猜测可能是组件样式的 scoped
为样式和 DOM 建立对应关系的时候,此时这些圆点还没有生成,也就是说,圆点“错过了”添加自定义属性的过程。当然这个只是猜测,如果有大佬知道这里面的具体过程,也欢迎在下面评论区指出。
如何修改第三方组件库的样式
虽然 scoped
可以防止全局样式污染,但是给我们修改第三方组件库的样式带来了困难 —— 就像上面的问题一样,这些第三方插件通常都是项目中的子组件,而我们又需要根据项目需求修改组件样式。那么怎么办呢?这里记录一些 可能的 解决方案:
-
去掉
scoped
:破坏样式的封装,不推荐 -
在
App.vue
中书写全局样式,不推荐,理由同上 -
新建一个
css
样式文件,在里面书写需要覆盖的样式,并在main,js
引入该文件 -
同时使用带
scoped
与不带scoped
的script
标签,在后者书写需要覆盖的样式 -
使用 深度选择器 实现样式穿透:
对于普通 CSS 或者 stylus,使用
>>>
;对于 sass 和 less,使用/deep/
。以上面代码为例,如果要实现样式穿透,可以这么写:
<style scoped> .swiper-pagination >>> .swiper-pagination-bullet-active{ background-color: var(--color-tint); } /* 或者是 .swiper-pagination /deep/ .swiper-pagination-bullet-active{ background-color: var(--color-tint); } */ </style>
以上所述就是小编给大家介绍的《在项目中使用 vue-awesome-swiper 遇到的问题》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 旧项目在xcode10遇到的问题
- vue项目中的遇到的坑和感悟
- vue项目中遇到的一点小问题记录
- golang安装遇到问题和解决,初始化beego项目
- MUI在项目中使用时遇到的问题的个人总结
- 我在实际项目开发中遇到的关于ElementUI各种表单验证
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
亿级流量网站架构核心技术
张开涛 / 电子工业出版社 / 2017-4 / 99
《亿级流量网站架构核心技术》一书总结并梳理了亿级流量网站高可用和高并发原则,通过实例详细介绍了如何落地这些原则。本书分为四部分:概述、高可用原则、高并发原则、案例实战。从负载均衡、限流、降级、隔离、超时与重试、回滚机制、压测与预案、缓存、池化、异步化、扩容、队列等多方面详细介绍了亿级流量网站的架构核心技术,让读者看后能快速运用到实践项目中。 不管是软件开发人员,还是运维人员,通过阅读《亿级流......一起来看看 《亿级流量网站架构核心技术》 这本书的介绍吧!