博客 / 詳情

返回

Vue 中的 deep、v-deep 和 >>> 有什麼區別?什麼時候該用?

🧑‍💻 寫在開頭

點贊 + 收藏 === 學會🤣🤣🤣

“你用 Element Plus 寫了個按鈕,想改下 hover 顏色,結果死活不生效!最後查了半天,發現得加個 :deep() 才行”

其實,這是 Vue 中一個非常常見的坑:樣式作用域衝突。那為什麼用 UI 庫時,加上 :deep()::v-deep>>>後,樣式就能生效呢?

它們是什麼?有什麼區別?什麼時候該用哪個?

一、先説背景

我們在 Vue 單文件組件(.vue 文件)裏寫樣式時,通常會加上 scoped 屬性:

<template>
  <el-button>點我</el-button>
</template>

<style scoped>
.el-button {
  background: red;
}
</style>

加了 scoped 後,Vue 會自動給這個組件裏的所有元素加上一個唯一的屬性(比如 data-v-123456),然後把 CSS 選擇器也加上這個屬性,變成:

.el-button[data-v-123456] {
  background: red;
}

這樣做的好處是:樣式只作用於當前組件,不會污染全局。、

但問題來了:Element Plus 的 <el-button> 組件內部結構,是在它自己的組件裏定義的。也就是説,你寫的 .el-button 元素,其實是 Element Plus 渲染出來的子組件,它身上沒有你當前組件的 data-v-xxx 屬性!

所以你的樣式根本匹配不到它,自然就失效了。


二、那怎麼辦?

為了解決這個問題,Vue 提供了樣式穿透(style penetration)的語法,讓你能穿透當前組件的作用域,去影響子組件內部的元素。

Vue 社區出現過三種寫法:

ScreenShot_2026-02-03_105557_840

下面我們一個個拆解。


1. >>>:曾經的快捷方式,但問題很多

早期 Vue2 時代,很多人用:

<style scoped>
.parent >>> .child {
  color: blue;
}
</style>

它的意思是:從 .parent 開始,穿透到所有後代中的 .child

但問題在於:

  • Sass/Less 等預處理器不認 >>>,會報錯。
  • 不是標準 CSS 語法。
  • Vue3 已經明確不再支持。

所以現在基本可以忘掉它了。


2. ::v-deep:Vue2 到 Vue3 的橋樑

為了兼容預處理器,Vue 引入了 ::v-deep

<style scoped lang="scss">
.parent ::v-deep(.child) {
  color: blue;
}
</style>

或者更常見的寫法:

.parent {
  ::v-deep(.child) {
    color: blue;
  }
}

它在 Vue2 和 Vue3 中都能用,算是一個安全的過渡方案。

但注意:在 Vue3 中,官方文檔已經明確建議使用 :deep() 替代它。


3. :deep():Vue3 的標準答案

Vue3 引入了更簡潔、更符合 CSS 規範的偽類函數寫法:

<style scoped>
:deep(.el-button) {
  background: red !important;
}
</style>

或者配合父級選擇器:

<style scoped>
.my-wrapper :deep(.el-input__inner) {
  border-radius: 10px;
}
</style>

優點

  • 語法清晰,像原生 CSS。
  • 支持所有預處理器(Sass/Less/Stylus)。

:deep() 本質上是一個編譯時轉換,Vue 在構建時會把它展開成帶 data-v-xxx 的複雜選擇器,從而實現穿透。


三、怎麼正確修改 Element Plus 的樣式?

舉個真實例子:你想把 Element Plus 的輸入框圓角改成 8px。

錯誤寫法(不生效):

<style scoped>
.el-input__inner {
  border-radius: 8px;
}
</style>

正確寫法:

<template>
  <div class="my-form">
    <el-input v-model="value" />
  </div>
</template>

<style scoped>
.my-form :deep(.el-input__inner) {
  border-radius: 8px;
}
</style>

為什麼要加 .my-form 這個父級?

避免全局污染!如果直接寫 :deep(.el-input__inner),那麼這個頁面裏所有 Element 輸入框都會被改掉。加上父級限定,就能精準控制範圍。

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文檔,大家一起討論學習,一起進步。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.