Vue是一個<font color='red'>漸進式框架</font>, 什麼是漸進式的呢?css
Vue有不少特色和Web開發中常見的高級功能html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--一、導入Vue的包--> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script> </head> <body> <!--這個div區域就是MVVM中的 View--> <div id="app"> {{message}} </div> </body> <script> // 二、建立一個Vue的實例 var app = new Vue({ el: '#app', //用於掛載要管理的元素 data: {// 定義數據 message: '學習Vue.js' } }); </script> </html>
View層前端
Model層vue
VueModel層算法
屬性名 | 類型 | 做用 | |
---|---|---|---|
el |
<font color='blue'>類型: string \ | HTMLElement</font> | 決定Vue實例會管理哪個DOM |
data |
<font color='blue'>類型: Object \ | Function (組件當中data必須是一個函數)</font> | Vue實例對應的數據對象 |
methods |
<font color='blue'>類型: { [key: string]: Function }</font> | 定義屬於Vue的一些方法, 能夠再其餘地方調用, 也能夠在指令中使用 |
數據綁定最多見的形式就是使用 「Mustache」 語法(雙大括號)的文本插值。例如:npm
<span>Message: {{ msg }}</span>Mustache 標籤將會被替代爲對應數據對象上 msg 屬性(msg定義在data對象中)的值。 數組
不管什麼時候,綁定的數據對象上 msg 屬性發生了改變,插值處的內容都會自動更新。瀏覽器
語法 | {{}} JavaScript 表達式支持 |
---|---|
普通表達式 | {{ number + 1 }} |
三元表達式 | {{ ok ? 'YES' : 'NO' }} |
三元表達式 | {{ name == 'smyhvae' ? 'true' : 'false' }} |
調用方法 | {{ message.split('').reverse().join('') }} |
該指令後面不須要跟任何表達
該指令表示元素<font color='red'>只渲染一次</font>,不會隨着數據的改變而改變。
<h2 v-once>{{message}}</h2>
解析<font color='red'>數據中的html</font>代碼,渲染到頁面中
<h2 v-html="url"></h2>
v-text做用和Mustache比較類似:都是用於將<font color='red'>數據顯示在界面</font>中, 不一樣的是 v-text 是寫在屬性中
v-text一般狀況下,接收一個string類型
<h2 v-text="text"></h2>
v-pre用於跳過這個元素和它子元素的編譯過程,用於<font color='red'>顯示本來的Mustache</font>語法。
<h2 v-pre>{{message}}</h2>
在某些狀況下,咱們瀏覽器可能會直接顯然出未編譯的Mustache標籤。
v-cloak指令和CSS 規則一塊兒用的時候,可以解決插值表達式閃爍的問題(即:能夠隱藏未編譯的標籤直到實例準備完畢)
<!-- 在vue解析以前, div中有一個屬性v-cloak 在vue解析以後, div中沒有一個屬性v-cloak --> <div id="app" v-cloak> <h2>{{message}}</h2> </div>
做用:能夠給html元素或者組件動態地綁定一個或多個特性,例如動態綁定style
和class
緩存
這個時候,咱們可使用v-bind指令:服務器
:
綁定class有兩種方式
- 對象語法
- 數組語法
對象語法
:class
後面跟的是一個<font color='red'>對象</font>。<!-- 用法一:直接經過{}綁定一個類 --> <h2 :class="{'active': isActive}">Hello World</h2> <!-- 用法二:也能夠經過判斷,傳入多個值 --> <h2 :class="{'active': isActive, 'line': isLine}">Hello World</h2> <!-- 用法三:和普通的類同時存在,並不衝突 --> <!--注:若是isActive和isLine都爲true,那麼會有title/active/line三個類--> <h2 class="title" :class="{'active': isActive, 'line': isLine}">Hello World</h2> <!-- 用法四:若是過於複雜,能夠放在一個methods或者computed中 --> <!--注:classes是一個計算屬性 --> <h2 class="title" :class="classes">Hello World</h2>
數組語法
:class
後面跟的是一個<font color='red'>數組</font>。<!-- 1. ['active','news'] 當字符串使用 --> <h2 class="title" :class="['active','news']">{{message}}</h2> <!-- [active, new] 當變量使用 --> <h2 class="title" :class="[active,news]">{{message}}</h2> <!-- 3. 函數返回值使用 --> <h2 class="title" :class="getClasses()">{{message}}</h2>
綁定class有兩種方式
對象語法
style
後面跟的是一個對象類型key
是css屬性名value
是具體賦的值, 能夠來自data
中的屬性:style="{color: currentColor, fontSize: fontSize + 'px'}"
數組語法
style
後面跟的是一個數組類型, 多個值以 , 分隔<div v-bind:style="[baseStyles, fontColor]"></div> /* js */ baseStyle: {background: 'lime'}, fontSize: {fontSize: '80px'}
在某些狀況,咱們可能須要對數據進行一些轉化後再顯示,或者須要將多個數據結合起來進行顯示
firstName
和lastName
兩個變量,咱們須要顯示完整的名稱。{{firstName}} {{lastName}}
將上面代碼轉換成計算屬性
/* html */ <h2>{{fullNmae}}</h2> /* js */ computed: { fullNmae: function () { return this.firstNmae + ' ' + this.lastNmae; } }
每一個計算屬性都包含一個getter
和一個setter
getter
來讀取。methods和computed區別
methods
裏面的數據無論發沒發生變化, 只要調用了都會執行函數(有的時候數據沒發生變化咱們不但願調用函數)computed
計算屬性會進行緩存, 若是數據沒發生變化,函數只會被調用一次(數據發生變化纔會調用函數)總結:
methods
無論數據發沒發生變化都會調用函數computed
只有在依賴數據發生變化時纔回調函數在前端開發中,咱們須要常常和用戶交互
v-on 介紹
@
methods
中定義方法, 以供@click
調用時, 須要注意參數問題狀況一: 若是該方法不須要額外參數, 方法後()
能夠省略
event
參數傳遞進去event
時, 能夠經過$event
傳入事件v-on
提供了不少事件修飾符來輔助實現一些功能。事件修飾符有以下修飾符 | 做用 | |
---|---|---|
.stop | 阻止冒泡。本質是調用 event.stopPropagation() | |
.prevent | 阻止默認事件行爲 本質是調用 event.preventDefault() | |
.{keyCode \ | keyAlias } | 當事件是從特定鍵觸發時才觸發回調 |
.once | 事件只觸發一次 |
<h2 v-if="score>=90">優秀</h2> <h2 v-else-if="score>=80">良好</h2> <h2 v-else-if="score>=60">及格</h2> <h2 v-else>不及格</h2>
v-if-else-if
一個問題: 涉及到了Vue底層, 虛擬DOM virtual DOM
點擊切換表單後,input的value值並無被清空,爲何?
input
表單時, 咱們輸入上的value
, 點擊按鈕切換表單時會發現value
值還存在, 可是input
元素確實切換了, 這是由於什麼呢?<span v-if="isUser"> <label for="user">用戶名</label> <input type="text" placeholder="用戶名" id="user" key="user"> </span> <span v-else> <label for="email">郵箱</label> <input type="text" placeholder="郵箱" id="email" key="email"> </span> <button @click="isUser=!isUser">切換類型</button> <script> const app = new Vue({ el: '#app', data: { isUser: true } }) </script>
緣由:
解決方案
Vue
出現相似重複利用的問題, 能夠給對應的 input
添加 key
key
不一樣, 這樣 vue
就會建立一個全新 input
元素v-show的用法和v-if很是類似,也用於決定一個元素是否渲染
v-if 和 v-show對比
開發中如何選擇呢?
<h2 v-show="isShow">{{message}}</h2>
v-for="(item, index) in items"
<ul> <!-- item: 是每一項元素 index: 下標/索引 --> <li v-for="(item, index) in name"> {{index+1}}.{{item}} </li> </ul>
v-for="(value, key, index) in items"
<ul> <!-- value:屬性值 key:屬性名 index:下標/索引 --> <li v-for="(value, key, index) in info"> {{index+1}}.{{value}} </li> </ul>
v-for
時,給對應的元素或組件添加上一個:key
屬性。爲何須要這個key屬性呢(瞭解) ?
Diff
算法有關係。當某一層有不少相同的節點時,也就是列表節點時,咱們但願插入一個新的節點
因此咱們須要使用key來給每一個節點作一個惟一標識
使用v-for
更新已渲染的元素列表時,默認用<font color='red'>就地複用</font>策略; 若是列表數據修改的時候, 它會根據key值去判斷某個值是否修改, 若是修改, 則從新渲染這一項, 不然複用以前的元素; 咱們在使用的使用常常會使用index
(即數組的下標)來做爲key
,但其實這是不推薦的一種使用方法;
Vue中包含了一組觀察數組編譯的方法, 使它們改變數組也會觸發更新視圖
Vue.set(vm.items, indexOftem, newValue)
vm.$set(vm.items ,indexOften,newValue)
當它們處於同一節點,v-for
的優先級比v-if
更高,這意味着
v-if
將分別重複運行於每一個v-for
循環中。避免
v-if
和v-for
用在一塊兒
緣由
使用計算屬性的好處
Vue中使用v-model指令
來實現表單元素和<font color='red'>數據的雙向綁定</font>
引出:
v-model
這個屬性。區別:
v-bind
: 只能實現數據的單向綁定, 從M自動綁定到v。v-model
: 只有v-model
才能實現雙向數據綁定。注意, v-model後
面不須要跟冒號注意
v-model
只能運用在表單元素中, 或者用於自定義組件。常見的表單元素包括: input(radio,text,address,email...) ,select, checkbox, textarea.
v-model實際上是一個語法糖, 他背後本質是包含兩個操做
<input type="text" v-model="message"> <!-- 等同於下面的代碼 --> <input type="text" :value="message" @input="message = $event.target.value">
v-model
指令來實現表單元素和數據的雙向綁定案例解析:
v-model
表單類型 | 單選/多選狀況 | 綁定的值 |
---|---|---|
v-model: radio |
多個單選框時 | 綁定的值是value |
v-model: checkbox |
單個勾選框 | v-model即爲布爾值 |
多個複選框 | 選中多個, 對應的data 屬性是一個數組 |
|
v-model: select |
單選 | v-model 綁定的是一個值 |
多選 | v-model 綁定的是一個數組 |
動態的給value
賦值而已
value
中的值, 都是在定義input中直接給定的v-bind:value
動態的給value綁定值修飾符 | 做用 |
---|---|
.lazy |
當表單失去焦點 或按下回車 時,data 中的數據纔會更新 |
.number |
輸入的內容轉換爲number 數據類型 |
.trim |
過濾內容的兩側空格 |
爲什麼須要自定義指令
- 內置指令不知足需求
Vue.directive('focus', { inserted: function (el) { el.focus()// 獲取元素的焦點 } }) // 使用自定義指令 <input type="text" v-focus>
Vue.directive('color', { // bind聲明週期, 只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置 // el 爲當前自定義指令的DOM元素 // binding 爲自定義的函數形參 經過自定義屬性傳遞過來的值 存在 binding.value 裏面 bind: function(el, binding){ // 根據指令的參數設置背景色 // console.log(binding.value.color) el.style.backgroundColor = binding.value.color; } }); // 使用帶參數自定義指令 <input type="text" v-color='msg'>
directives
的選項 用法和全局用法同樣directives: { focus: { inserted: function(el) { el.focus(); } } }
偵聽器的應用場景
- 數據變化時執行
異步
或開銷較大的操做
- 注意: watch 中的屬性 必定是data 中 已經存在的數據
// 當data中的: firstName屬性或lastNames屬性改變時, 會自動觸發對應的watch watch: { firstName(val) { // val: 表示變化後的值 this.fullName = val + ' ' + this.lastName; }, lastName(val) { this.fullName = this.firstName + ' ' + val; } }
- 概念: Vue.js容許咱們自定義過濾器,可被用做一些常見的
文本格式化/處理
。- 過濾器能夠用在兩個地方: mustache插值表達式、v-bind表達式。
- 過濾器應該被添加在JavaScript表達式的尾部,由「管道」符指示。
- 過濾器不改變真正的
data
,而只是改變渲染的結果,並返回過濾後的版本
- 全局註冊時是filter,沒有s的。而局部過濾器是filters,是有s的
- 支持級聯操做(對前一個過濾的數據再次進行過濾處理)
Vue.filter()
自定義一個全局過濾器。這樣的話,每個Vue的對象實例(每個VM實例
)均可以拿到這個過濾器。它接收兩個參數
: 過濾器的名稱
、過濾器函數
。<div>{{msg | upper}}</div> <div>{{msg | upper | lower}}</div> <div :class="msg | upper"></div> <!-- 帶參數過濾 --> <div>{{date | format('yyyy-MM-dd')}}</div> <script> // 1.全局過濾器 Vue.filter('upper', (val) => { // val就是要處理的數據 return val.charAt(0).toUpperCase() + val.slice(1); }) // 2.處理帶參數過濾器 Vue.filter('format', (date, arg) => { // arg: 傳遞的參數 if (arg === 'yyyy-MM-dd') { return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate(); } }) </script>
當前vue對象
的el指定的監管區域
有用。<!-- 管道符前面的price: 要把price這段文本進行過濾 --> <!-- 管道符後面的showPrice: 是經過showPrice這個過濾器來進行操做 --> <td>{{price | showPrice}}</td> <script> const app = new Vue({ filters: { showPrice(price) { return '¥' + price.toFixed(2); } } }) </script>
掛載(初始化相關屬性)
更新(元素或組建的變動操做)
銷燬(銷燬相關屬性)
鉤子函數 | 過程 |
---|---|
beforeCreate | 在實例初始化以後, 數據觀測和事件配置以前被調用此時data和methods以及頁面的DOM結構都沒有初始化什麼都作不了 |
created | 在實例建立完成後被當即調用此時data 和 methods已經可使用可是頁面尚未渲染出來 |
beforeMount | 在掛載開始以前被調用此時頁面上還看不到真實數據只是一個模板頁面而已 |
mouted | el被新建立的vm.$el替換, 並掛載到實例上去以後調用該鉤子。數據已經真實渲染到頁面上在這個鉤子函數裏面咱們可使用一些第三方的插件 |
beforeUpdate | 數據更新時調用,發生在虛擬DOM打補丁以前。 頁面上數據仍是舊的 |
update | 因爲數據更改致使的虛擬DOM從新渲染和打補丁, 在這以後會調用該鉤子。頁面上數據已經替換成最新的 |
beforeDestroy | 實例銷燬以前調用 |
destroyed | 實例銷燬後調用 |