為什麼 Vue3.js / Element+ 組件屬性前面有的需要添加冒號,有的不需要?

背景

使用 Element+ Layout 布局:

 <el-row>
   <el-col :span="12"><div class="grid-content bg-purple"></div></el-col>
   <el-col :span="12"><div class="grid-content bg-purple-light"></div></el-col>
 </el-row>

Element+ Layout 將每一行的寬度平均分成 24 格,使用 span 描述每一列佔用的格數,相當於每一列的寬度。

這段程式碼表示 1 行被拆分為 2 列,每一列佔用 12 格,使用 span 屬性指定,有一個奇怪的現象:

span 的屬性值就是一個整數,不是變數名稱,用不到屬性綁定,前面為什麼會有一個冒號?

去掉這個冒號行不行? 實際測試,不行!

為什麼會注意到這個冒號現象?這裡需要提一下 Vue3.js 的重要特性:屬性綁定

Element+ 是基於 Vue3.js 實現的組件庫。

<div id="1"></div>

這是一個簡單的 div,且指定它的屬性 id 值為 1;假設我們需要 動態 地指定它的 id,應該怎麼做呢?

Vue3.js 提供的解決方案:可以定義一個變數 dynamicId,用於實際存儲 id 值;然後將這個 div 的屬性 id 綁定 到變數 dynamicId 上面,這個特性稱之為 屬性綁定

<div v-bind:id="dynamicId"></div>

屬性 id 使用 屬性綁定 時需要使用 v-bind: 進行標識,id 的值為需要綁定的變數名稱 dynamicId;這樣屬性 id 的值就是變數 dynamicId 的值,如果變數 dynamicId 的值發生變化,屬性 id 的值也會隨之變化。

敲黑板!!! v-bind: 實際使用時可以簡化為 : ,即單獨的一個冒號,這就是屬性名稱前面冒號的由來。

問題

既然使用屬性值是一個變數名稱時才需要使用 v-bind: 或者 : 進行標識,為什麼屬性值為整數時,

<el-col :span="12">...</el-col>

v-bind: 或者 : 也必須被設置?

分析

既然問題和 屬性綁定 有關,帶著問題把 Vue3.js 官網相關文檔又看了一遍:

重點:

對於所有的數據綁定,Vue.js 都提供了完全的 JavaScript 表達式支援。

表達式示例:

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div v-bind:id="'list-' + id"></div>

疑問:

number + 1 是一個表達式,屬於屬性綁定;
number 是一個變數,屬於屬性綁定;
1 是什麼?它只是一個整數字面量,也屬於屬性綁定?

帶著疑問百度搜索相關問題,直到看到某個同學的文章:

加冒號的,說明後面的是一個變數或者表達式;沒加冒號的後面就是對應的字元串字面量!

為什麼vue組件的屬性,有的需要加冒號「:」,有的不用?

解釋說明:

  • 加冒號的
    屬性名稱前面使用 v-bind: 或者 : ,表示屬性值部分為變數名或表達式;
  • 沒加冒號的
    屬性值部分為 字元串字面量

問題關鍵:字元串字面量!!! 也就是說,“1” 表示的是字元串的 1,而不是整數的 1;即字元串 1 並不會被內部轉換為整數 1 使用。

這也就解釋了為什麼去掉冒號,Element+ Layout 布局會失敗?

屬性 span 要求的值類型是一個整數,如果去掉屬性 span 前面的冒號,像這樣:

<el-col span="12">...</el-col>

這裡的 12 表面看起來是一個整數,實際 Vue3.js/Element+ 是按照字元串處理的,屬性值類型異常,設置無效,因此布局失敗。

屬性 span 前面添加冒號,像這樣:

<el-col :span="12">...</el-col>

這裡的 12 很明顯不是一個變數名,但會按照表達式處理;這個表達式的值為整數值 12,屬性值類型正常,設置有效,因此布局成功。

敲黑板!!! 單個整數也是一個表達式。

結論

在 Vue3.js/Element+ 的世界裡:

  • 屬性名稱前面沒加冒號的
    屬性值部分按普通字元串處理
  • 屬性名稱前面加冒號的
    屬性值部分按屬性綁定處理,屬性值可能是以下三種類型:

    1. 變數名稱
    2. 單個表達式
    3. 單個整數、布爾、字元串或其它數據類型的字面值

屬性綁定時,如果屬性值是一個字元串,Vue3.js 會優先判斷是否存在名稱為該字元串的變數名:

  • 如果存在,按變更名稱處理
  • 如果不存在,按字元串字面值處理

@萌貓他爸,互聯網從業者/大數據架構師/全棧開發者

  • Blog
  • Github @leaderman
  • 微博 @萌貓他爸(知乎/小紅書/…)
  • 公眾號 @淵深海闊
  • 微訊號 @meetuagent