vue中修改子組件樣式

1、問題敘述

  項目裏須要新添加一個表單頁面,裏面就只是幾個select,這個幾個select是本來封裝好的組件,有本身本來的樣式,而此次的原型圖卻沒有和以前的樣式統一塊兒來,須要微調一下,這裏就涉及到父組件修改子組件的樣式。不想混用本地和全局樣式,因此選擇了>>>,可是並不起做用,就換成/deep/,其實到這裏我也沒有繼續深刻這個知識點,由於在瀏覽器裏預覽後已經實現了原型圖的樣式,直到打包在手機上測試,發現問題,在手機上瀏覽並無將樣式修改過來。以下圖:css

 

問題:①爲何使用>>>不起做用?②爲何我使用了/deep/卻沒有成功的在手機上將樣式修改過來?vue

2、相關知識點

  ㈠關於vue中使用scoped屬性web

在vue組件中,在style標籤中添加scoped屬性,這樣在這裏定義的css只做用於當前組件中的元素,可以使組件之間的樣式不會相互污染,使樣式私有化。好比在父組件內使用子組件,父組件的樣式不會滲透到子組件中。瀏覽器

  Ⅰ、在加上scoped後,會爲DOM節點自動添加一個惟一的屬性(data-v-f3f3eg9後面這串數字像是獨一無二的hash值),以保證其惟一性。同時在相應的css選擇器末尾,也加上了當前組件的data-v-f3f3eg9屬性,來使其私有化。app

如Vue Loader中所給出的代碼示例:佈局

<template>
  <div class="example">hi</div>
</template>

<style scoped>
.example {
  color: red;
}
</style>

轉化後:測試

<template>
  <div class="example" data-v-f3f3eg9>hi</div>
</template>

<style>
.example[data-v-f3f3eg9] {
  color: red;
}
</style>

  ㈡關於深度做用選擇器:/deep/(>>>)flex

  使用了scoped後,儘管實現組件樣式的私有化,但在咱們實際的項目中,在不少地方使用重複的子組件或其餘的樣式庫時,在個別地方須要微調樣式,這個時候不能直接改子組件樣式,並且在父組件裏的樣式又不能滲透到子組件去。這個時候文檔中有一句話:spa

不過一個子組件的根節點會同時受其父組件的 scoped CSS 和子組件的 scoped CSS 的影響。這樣設計是爲了讓父組件能夠從佈局的角度出發,調整其子組件根元素的樣式。設計

  因此仍是有辦法解決剛纔那個問題的,當咱們但願 scoped 樣式中的一個選擇器可以做用得「更深」,例如影響子組件,你可使用 >>> 操做符,編譯後會在相應的選擇器後面增長獨有的屬性;以下:

<style scoped>
.a >>> .b { /* ... */ }
</style>

上述代碼將會編譯成:

.a[data-v-f3f3eg9] .b { /* ... */ }

  在這裏須要注意的是,有些像 Sass 、scss之類的預處理器沒法正確解析 >>>。這種狀況下咱們可使用 /deep/ 或 ::v-deep 操做符來取代>>>,這是兩個都是 >>> 的別名,一樣能夠正常工做。以下:

<style lang='scss' scoped>
.a {
    /deep/ .b{
                /* ... */
    }
}
</style>

3、問題解決

  ①爲何使用>>>不起做用?

  由於這個項目使用的scss,因此沒法正常解析>>>,因此在父組件沒有滲透下去。

.pop-content {
   .input-wrapper >>>  .form-item {
    .form-label {
     /*...*/
  }

  在瀏覽器查看轉換的結果發現,仍是本來組件的樣式,我新定義的並無出現。以下圖:

  ②爲何我使用了/deep/卻沒有成功的在手機上將樣式修改過來?

  由於引用的這個子組件裏還包裹了一層子組件,我使用了兩個/deep/,不理解/deep/的實現原理,自覺得每個組件都要滲透一次。

/*錯誤代碼:寫了兩次/deep */
.pop-content {
  /deep/ .input-wrapper /deep/  .form-item {
      ...
  } 
 }

轉換後在瀏覽器看到的代碼,發現第二個是沒法轉換的。

.pop-content[data-v-b93cf8e0] .input-wrapper /deep/ .form-item {}

 

/*修改後的代碼*/
.pop-content {  
     .input-wrapper /deep/  .form-item {  
    }
  }​

/*編譯轉換後的代碼*/
 .pop-content .input-wrapper[data-v-b93cf8e0] .form-item 

  ③隨之而來第三個問題,我只寫一個/deep/的話,我寫在哪一個位置呢,是否是寫在哪都行,它們之間有什麼區別。

  ⅰ嘗試一:將/deep/寫在input-wrapper後面

.pop-content { 
   .input-wrapper /deep/  .form-item {
    padding: 0.4rem 2rem 0.3rem 1.5rem;
    .form-label {
      -webkit-box-flex: 0;
      -ms-flex: 0 0 8rem;
      flex: 0 0 50%;
      font-size: 15px;
      color: black;
      position: relative;
    }
  }

轉換後的樣式代碼:本來的樣式已經失效了,並在input-wrapper後面添加了相應惟一的data-v屬性值。

  ⅱ嘗試二:將/deep/寫在pop-content後面

.pop-content {
  /deep/  .input-wrapper .form-item {
    padding: 0.4rem 2rem 0.3rem 1.5rem;
    .form-label {
      -webkit-box-flex: 0;
      -ms-flex: 0 0 8rem;
      flex: 0 0 50%;
      font-size: 15px;
      color: black;
      position: relative;
    }
  }

轉換後的樣式代碼:本來的樣式已經失效了,並在pop-content後面添加了相應惟一的data-v屬性值。

  ⅲ嘗試三:將/deep/寫在form-item或者form-label後面,均不起做用。看了一下DOM結構,我以爲多是由於這樣作的css的優先級並無比原來的高,因此無法改變。還有就是這個子組件內部的組件嵌套也比較複雜,因此從最外面的父組件看不出,因此對/deep/位置的放置對其優先級的影響仍是比較大的。大體這樣理解。

相關文章
相關標籤/搜索