vue3在打包之后只有一個html文件,為了避免樣式污染可以為style標簽引入scope屬性,它的原理十分簡單,它會為每一個dom元素都添加一個data屬性,這個屬性是不重復的,然后會在當前組件的選擇器的末尾,追加一個屬性選擇器,當兩者匹配上時,會把樣式命中到dom上
scope渲染規(guī)則:
1.每個dom元素會自帶一層data
2.當前組件的選擇器會追加一個屬性選擇器來保證一一對應
3.當一個組件引入另一個組件時,scope的唯一data屬性只會添加到最外層標簽
此時,我們就在backstage這個單文件組件里引入elementplus的組件,我們觀察一下此時data屬性的位置?
發(fā)現(xiàn)只有最外層的div有data屬性?
現(xiàn)在我們有一個需求,把邊框的白線給去掉?
打開調試工具可知我們需要選中截圖紅框的元素并修改其css屬性
?如果我們做出如下修改
?
發(fā)現(xiàn)頁面并沒有變化,原因就在于container這個容器是由一層data的,此時的屬性選擇器是被加到了el-table_cell后面,我們并沒有命中到container,所以樣式不生效
做出如下修改
?我們再觀察此時頁面的情況
?發(fā)現(xiàn)此時的屬性選擇器被追加到了container后,此時我們就成功命中父級元素container,后面操作它的子元素樣式就可以順利生效。所以這個:deep()深度選擇器就干了一件事情,deep寫在誰后面,就會把data屬性選擇器追加到誰后面
使用樣式穿透后可以寫的更優(yōu)雅一點
?文章來源地址http://www.zghlxwxcb.cn/news/detail-771637.html
現(xiàn)在我們來看看他的源碼
vue3源碼在此
scope的具體實現(xiàn)在compiler-src里,這個文件主要就是用于處理后綴名.vue的單文件組件的,
這里寫了三個解析器分別解析template標簽、script標簽、style標簽
?這里觀察到會首先判斷是否開啟scope屬性,如果有,則會往postcss plugin 里添加一個插件,
我們點進去看看這個插件具體做了什么事情
?發(fā)現(xiàn)這個插件主要是將css轉化成AST,有點類似babel,babel主要操作就是將高階es6語法先轉義成AST,得到這么一個樹之后我們就可以隨意操作它的節(jié)點,甚至做一些定制化的操作
我們點進processRule
它首先先聲明了一個弱集合processeRules,然后判斷rule是否存在,這里的rule是AST,如果有,就return出去,如果沒有就往里面添加AST
然后會遍歷這個AST,為每個item都調了rewirteSelector 這個函數
我們再看看這個函數
首先判斷我們所使用的深度選擇器,如果是vue2的這兩種,就不給我們做樣式穿透并彈出警告,我們接著往下看
?首先還是會判斷類型,類型pseudo如下
?然后再判斷我們的深度選擇器是否符合vue3規(guī)范,如果符合,則幫我們做樣式穿透,實現(xiàn)的方式其實就是挪動下屬性選擇器的追加位置,第三個框框就是挪動的實現(xiàn)
?觀察這里的挪動
文章來源:http://www.zghlxwxcb.cn/news/detail-771637.html
?
到了這里,關于詳解源碼vue3的樣式穿透scope的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!