带你玩转 ui 框架 ——scoped及样式穿透问题详解
前言
在我們前端的開發(fā)中經(jīng)常會(huì)使用到各種 ui 框架 下面這兩個(gè)是比較火的,也是我常用的兩個(gè)ui框架。
問(wèn)題描述
但是在使用框架的時(shí)候難免會(huì)遇到需要改變組件中的一些樣式,當(dāng)然如果我們所有頁(yè)面的組件樣式都是統(tǒng)一的話,我們可以進(jìn)行全局設(shè)置樣式,但是如果我們僅僅在一個(gè)頁(yè)面中需要個(gè)性化的樣式設(shè)置,我們平常會(huì)下面這樣操作:
<style lang="less" scoped> #main {width: 100%;height: 90%; } .ivu-form .ivu-form-item-label {color: #fff; } .ivu-table th {height: 60px !important; } .ivu-table td {height: 45px !important; } .conLeft {width: 78%;height: 100%;padding: 10px;position: relative;img {width: 100%;height: 100%;}.smaBox {cursor: pointer;position: absolute;width: 40px;height: 40px;} } </style>不難看出我們上面的很多類名就是我們組件中自帶的,我們只有通過(guò)這些類名去更改我們當(dāng)前頁(yè)面組件呈現(xiàn)的樣式,但是因?yàn)槲覀冊(cè)诋?dāng)前頁(yè)面中去編寫的樣式只想讓其應(yīng)用在當(dāng)前的頁(yè)面中,所以我們?cè)趕tyle中去添加了scoped屬性,關(guān)于scoped屬性的講解我們放到下面去講解;
先回到我們上面的代碼中,看似沒(méi)有任何問(wèn)題我們?nèi)ネㄟ^(guò)類名改變組件的樣式,但是他不會(huì)生效,就是因?yàn)閟coped屬性導(dǎo)致的問(wèn)題,在我們的Vue項(xiàng)目中scoped屬性真的很好用,為我們避免了組件之間的樣式覆蓋,使我們定的樣式不會(huì)造成全局的污染!
解決辦法 - 樣式穿透即可
首先我們要搞明白添加上scoped屬性后發(fā)生了什么,如果您著急解決問(wèn)題可以直接看我們這個(gè)小節(jié)的問(wèn)題解決,如果您想知其然知其所以然,那么您現(xiàn)在可以先去看文章的下一小節(jié)——scoped屬性的原理。
使用樣式穿透去解決 scoped 帶來(lái)的問(wèn)題,樣式穿透有四種形式:
不太推薦第一種寫法,不同瀏覽器的展示形式不一樣,容易出問(wèn)題,2、3、4這幾種都是有預(yù)處理器(less, scss, sass)的寫法,推薦大家使用第二、三種,
將scoped屬性去掉。雖然很方便 但是失去了樣式的保護(hù),我們就需要用原始的方法保護(hù)該組件的樣式作用域,可通過(guò)后臺(tái)選擇器等等方式實(shí)現(xiàn)樣式的保護(hù),使其不受污染。好像更麻煩了。
上面我通過(guò)使用第二種方式 輕松實(shí)現(xiàn)了
scoped屬性的原理
為了使樣式私有化(模塊化),不對(duì)全局造成污染,可以在style標(biāo)簽上添加scoped屬性以表示它的只屬于當(dāng)下的模塊,這是一個(gè)非常好的舉措
我們可能只了解他的作用就是為了讓當(dāng)前組中的style中的樣式,僅僅對(duì)當(dāng)前組件生效,對(duì)原理可能不太懂,那下面小編就帶大家梳理一下scoped的原理。
scoped的用法
<template><div class="box">歡迎您的光臨</div> </template><style lang="less" scoped>.box{background-color:green;} </style>- 從上面的代碼中我們可以看出我們的scoped屬性就是直接寫到我們的style標(biāo)簽當(dāng)中,使用就是這么簡(jiǎn)單
設(shè)置scoped屬性后發(fā)生了什么
設(shè)置上了scoped 實(shí)際上我們是將代碼通過(guò) PostCss 進(jìn)行了轉(zhuǎn)換,下面我們進(jìn)行一下對(duì)比
PostCss是一個(gè)樣式處理工具,它通過(guò)自定義的插件和工具生態(tài)體系來(lái)重新定義css,有興趣的同學(xué)可以去了解一下關(guān)于PostCss中的一些常用插件,讓你的css更哇塞
轉(zhuǎn)換前:
<template><div class="box">歡迎您的光臨</div> </template><style lang="less" scoped>.box{background-color:green;} </style>轉(zhuǎn)換后:
<template><div class="box" data-v-21aa888a>歡迎您的光臨</div> </template><style>.example[data-v-21aa888a] {color: red;} </style>- 上面對(duì)比后大家應(yīng)該就懂了是怎么回事了吧,其實(shí)說(shuō)白了加上scoped后vue編譯過(guò)程中會(huì)生成一個(gè)唯一的data-xxx標(biāo)志,樣式后面會(huì)跟上該標(biāo)志,以避免污染全局樣式
- 在父組件中設(shè)置了scoped中的樣式 如果該組件中有子組件 那子組件的根元素中也會(huì)繼承父組件中生成的style的唯一標(biāo)識(shí)
慎用scoped
上面我們看到了scoped這個(gè)屬性很香,其實(shí)他隱藏了很多坑
- 大家都知道css樣式有一個(gè)優(yōu)先級(jí)的說(shuō)法,scoped的這一操作,雖然達(dá)到了組件樣式模塊化的目的,但是會(huì)造成一種后果:每個(gè)樣式的權(quán)重加重了:理論上我們要去修改這個(gè)樣式,需要更高的權(quán)重去覆蓋這個(gè)樣式。這是增加復(fù)雜度的其中一個(gè)維度,所以如果要達(dá)到修改樣式的目的,就必須加重我們要修改樣式的權(quán)重(增加選擇器層級(jí),ID選擇器,并列選擇器,impotant等)
- 還有一種情況就是我們的兩個(gè)組件中均含有scoped 而且一個(gè)組件中包含了另一個(gè)組件,所以在Dom渲染的時(shí)候會(huì)在dom節(jié)點(diǎn)上加上很多唯一style的標(biāo)識(shí),有的是繼承的,有的是自己組件的,所以我們?cè)谛薷臉邮降臅r(shí)候還是會(huì)涉及到上面所說(shuō)的權(quán)重問(wèn)題,如果做不好可能會(huì)出現(xiàn)尷尬的問(wèn)題就是自己的組件修改不了自己組件的樣式哈哈
- 最后的問(wèn)題就是我們上面拋出的問(wèn)題,當(dāng)我們?cè)O(shè)置此屬性后我們想要改變組件中的樣式是改變不了的,當(dāng)然我們可以通過(guò)強(qiáng)大樣式穿透進(jìn)行解決!
總結(jié)
以上是生活随笔為你收集整理的带你玩转 ui 框架 ——scoped及样式穿透问题详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 最详细的讲解 JS 原型与原型链
- 下一篇: 看完就会的文件编程