vue.js
`vue.js` 是一套用於構建用戶界面的漸進式框架
漸進式
Vue 核心
- 聲明式渲染
- 組件
引入
我們還是先通過 \<script\> 的方式來引入 <u>vue</u>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
組件
`vue` 的核心功能之一就是組件
組件基本分類
- 根組件
- 可複用的功能組件
根組件的創建
通過 `vue` 提供的構造函數可以實例化出來一個跟組件實例對象
let app = new Vue
可複用的功能組件
通過 `Vue` 提供的靜態方法 `component` 窗口可複用的功能組件
let component1 = Vue.component
組件配置選項:https://cn.vuejs.org/v2/api/
組件內容渲染
渲染一個組件的內容可以通過兩種方式來進行
- template 選項(模板)
- render 選項(函數)
template(模板)
type : string
組件的模板結構(HTML),模板內容會被 `vue` 進行渲染,生成最終的 `HTML` 內容,並替換佔位(掛載)元素
el
type : string | Element
提供一個在頁面上已存在的 DOM 元素作爲 Vue 實例的掛載目標。可以是 CSS 選擇器,也可以是一個 HTMLElement 實例,
- 該選擇只對 `new` 創建的實例有效
- 如果提供 `el` ,但是沒有提供 `template` ,則 `el` 的內容講作爲 `template`
render函數
type : (createElement: () => VNode) => VNode
發揮 `JavaScript` 最大的編程能力,直接創建 `VNode` (虛擬dom對象),優先級高於 `el` 和 `template`
- 有更強大的編程能力
- 有更高的性能
https://cn.vuejs.org/v2/guide/render-function.html
HTML模板解析成虛擬DOM再解析成DOM元素
使用 $mount 方法延遲 `Vue` 實例的掛載
當 `Vue` 實例沒有 `el` 選項的時候,它會處於一種 未掛載 的狀態,我們可以通過組件 `Vue` 實例對象的 `$mount` 方法來手動掛載,
通過該方式,我們也可以達到延遲 `Vue` 實例的掛載的目的
組件中的數據(狀態)
data
組件內部使用的數據,`data` 是一個對象,`data` 中的值可以中模板中直接訪問
- `Vue` 實例組件(根組件)的 `data` 是一個對象
- 可複用功能組件的 `data` 必須是一個函數,且該函數必須返回一個對象(因爲複用性,避免多個組件實例引用同一個對象。
換句話說,組件中使用的數據必須是一個對象,但是可複用組件的這個數據對象必須通過函數返回
data 的訪問
`data` 數據可以直接通過組件實例對象訪問,也可以通過實例對象下的 `$data` 屬性進行訪問
組件實例對象下有很多的以 `$` 開頭的屬性,這些都是實例對象內置的一些屬性和方法,`vue` 爲了區分數據與內置屬性方法,
內置的屬性和方法默認都是以 `$` 開始的,所以我們中數據中應該避免使用 `$` 開頭的數據
模板語法
vue 使用了基於 html 的模板語法,使用聲明式的方式把實例中的數據(`data`)與 DOM 進行綁定,`data` 中的數據在模板中可以
直接使用
Mustache(雙大括號,大鬍子) 語法
在 vue 中,我們是通過一對雙大括號把實例中的數據渲染到模板內容中
插值表達式
在 {{ }} 中,我們可以放置表達式值
數據到視圖的更新
vue 會把 `data` 中的數據掛載到實例屬性下,同時對它們進行主動的監聽攔截,當數據發生變化的時候,重新渲染模板。我們可以
通過實例對象對數據進行修改
檢測變化的注意事項
在 vue3 之前,數據的監聽是通過 `Object.defineProperty` 方法來實現的,但是該方法只能監聽攔截單個數據,對於對象新增屬性無法
監聽攔截。所以,對於數據對象中新增的屬性,我們需要調用 vue 提供的方法來進行處理
擴展
通過 `Object.defineProperty` 監聽攔截中存在一些問題
- 屬性新增屬性
- 數組方法:push、pop、shift、unshift、splice、sort、reverse
- 數組新增值:[ ]
- 數組 length 屬性
以上的操作中並不會觸發監聽攔截
`vue` 對數組中的 `push`、`pop` 等方法進行重新包裝,所以在 `vue` 中調用這些方法,可以對數組的修改進行監聽攔截
[https://cn.vuejs.org/v2/guide/list.html#%E5%8F%98%E5%BC%82%E6%96%B9%E6%B3%95-mutation-method]
(https://cn.vuejs.org/v2/guide/list.html#變異方法-mutation-method)
使用 Vue.set 方法添加新數據
在模板中,我們使用了一個不存在的數據 `user.gender`
如果我們通過 `app.user.gender = '男' `的方式來新增,是不會被 vue 攔截監聽處理的,我們需要使用
這樣的方式,`set` 方法給 `app.user` 添加 `gender` 屬性的同時,對它進行了 `defineProperty`
指令
表達式的值除了可以出現內容中,也可以使用在其它位置,比如:屬性。但是不能使用 `{{ }}` 語法,而是需要 `指令`
在 `vue` 中,指令是一個帶有 `v-` 前綴的屬性,與普通屬性不一樣的地方在於,指令的值是引號括起來的 `表達式`,不同的指令有不同
的作用,`vue` 內置了一些常用的指令,後期我們還可以自定義屬於自己的指令
- 內容輸出
- 循環
- 邏輯
- 屬性綁定
- 事件
- 其它
內容輸出
通過 `{{ }}` 我們可以很方便的中模板中輸出數據,但是這種方式會有一個問題,當頁面加載渲染比較慢的時候,頁面中會
出現 `{{ }}` ,`vue` 提供了幾個指令來解決這個問題
指令中的表達式不需要使用 `{{ }}`
v-text
弊端:`v-text` 會填充整個 `innerHTML`,會把整個title填充掉,p再寫數據也沒用
v-cloak(這種寫法用的比較多,結合{{}}和v-text的優點)
這樣寫可以避免html加載完前出現{{ }}
需要配合 css 進行處理
v-html
爲了防止 `xss` 攻擊,默認情況下輸出是不會作爲 `html` 解析的,通過 `v-html` 可以讓內容作爲 `html` 進行解析
v-once
只渲染元素和組件一次,後期的更新不再渲染
v-pre
忽略這個元素和它子元素內容的編譯
邏輯處理
v-show
根據表達式的值(布爾值),切換元素的顯示與隱藏(display 屬性)
適用於狀態切換比較頻繁的情況
v-if
根據表達式的值(布爾值),創建或銷燬元素
適用於狀態切換不頻繁的情況
v-else / v-else-if
與 `v-else` 配合
循環與列表
v-for
根據數據循環渲染 `v-for` 指令所在的元素及其子元素
可以循環的數據:Array | Object | number | string | Iterable (2.6 新增)
v-for 中也可以使用 of 語法,在 vue 中兩者沒有什麼區別
:key
默認情況下,在渲染 `DOM` 過程中使用 原地複用 ,這樣一般情況下會比較高效,但是對於循環列表,特別是依賴某種狀態的列表,
會有一些問題,我們可以通過 `:key` 屬性,來給每個循環節點添加一個標識
屬性綁定
v-bind
綁定數據(表達式)到指定的屬性上,`<div v-bind:參數="值/表達式"></div>`,這裏的參數就是指定的屬性名稱
縮寫
有的一些常用指令會有對應的縮寫,`v-bind` 對應的縮寫爲 `:`
樣式
針對樣式屬性,`v-bind` 值有一些特殊的寫法
style
原生普通寫法
v-bind 寫法
對象寫法
數組寫法
class
原生普通寫法
v-bind 寫法
數組寫法
對象寫法
使用對象寫法,可以根據值(boolean)動態添加對應的 class
單向數據流
通過上面的知識點和案例,我們可以看到,當數據更新的時候,頁面視圖就會更新,但是頁面視圖中綁定的元素更新的時候,
對應的數據是不會更新的
我們稱爲:單向數據流 數據 -> 視圖
在 vue 中,還有一種雙向數據流綁定的方式
v-model
數據 `title` 更新,視圖中 `input` 的 `value` 就會更新。同時,當 input 中的 `value` 更新的時候,數據 `title` 也會更新,這就是我們說的
數據雙向綁定 [與 React 中的受控組件類似]
表單
針對一般元素,比如 div、span、p、img 等,採用的是單向綁定:v-bind,只需要把數據綁定到視圖中就可以,但是對於表單這種交互
性比較強的元素或組件,我們一般可能需求雙向綁定,即:用戶對視圖元素的操作同時更新數據
v-model 在內部爲不同的輸入元素使用不同的屬性和事件來處理數據
`text` 和 `textarea`
`checkbox` 和 `radio`
單選框綁定一個值
綁定的v3不是value,是單選框的check值
多選框綁定到一個布爾值或數組
`select`
單選綁定到值,多選綁定到數組
指令修飾符
一個指令可以包含的內容包括:
- 指令名稱
- 指令值
- 指令參數
- 指令修飾符
.lazy(懶)
取代 `input` 監聽 `change` 事件,焦點失去後觸發
.number
輸入字符串轉爲有效的數字
.trim
輸入首尾空格過濾