Vue-1 Vue的基礎語法
三大主流框架的對比
背景 | 版本 | 小結 | |
---|---|---|---|
Angular | 09年發佈,Google | 1.x,2.x,4.x,5.x(beta) | 基於html的大而全的MVC框架 |
React | Facebook於2013年5月開園 | 最新版本: 16.x | 基於js的視圖層框架 |
Vue | 尤雨溪團隊2014年2月開源 | 0.1x,1.x,2.x,虞姬2019年下半年發佈3.x版本 | 基於html視圖層框架 |
組織方式 | 數據綁定 | 模板能力 | 自由度 | 路由 | |
---|---|---|---|---|---|
Angular | MVC | 雙向綁定 | 模板能力 | 較小 | 靜態路由 |
React | 模塊化 | 單向綁定 | 自由 | 大 | 動態路由 |
Vue | 模塊化 | 雙向綁定 | 簡潔 | 較大 | 動態路由 |
適用場景:
Angular:後端開發人員構建CURD(用戶管理)類型應用;
React:前端開發人員構建複雜的web應用;
Vue:前端開發人員快速構建web應用。
Vue的數據渲染
Vue.js 的語法非常簡潔,要使用它,我們可以通過兩種方式,一種是將 Vue.js 當做一個單獨的庫,在HTML中引入,然後使用其中封裝好的各種語法,一種是,利用Node.js提供的服務器,安裝 Vue-cli 腳手架,然後在此基礎上開發。
我們先使用第一種方式,熟悉Vue的基礎語法。
<!-- vue-1.html -->
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<!-- 引入vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
// 當前頁面的邏輯代碼
</script>
</body>
</html>
在傳統的開發模式中,要將複雜的數據渲染在DOM中,需要使用各種DOM操作方式,對於DOM節點的增、刪、改、查操作非常的頻繁,代碼冗長,且容易產生各種冗餘。
框架的數據渲染非常方便,代碼簡潔,清晰,而且就開發角度而言,大大提高了開發效率,降低了代碼冗餘。
Vue.js 的核心是一個允許採用簡潔的模板語法來聲明式地將數據渲染進 DOM 的系統。
但是Vue的 DOM 操作系統,只針對 Vue 實例中按照指定方式聲明的數據和允許使用 Vue 語法的DOM區域,普通數據無法使用Vue語法渲染。
<div id="app">
<!-- 想要在這個區域中使用Vue語法 -->
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
// 在Vue實例的data對象中,以鍵值對的形式聲明數據,這些數據可以被Vue語法渲染在DOM節點上
}
});
接下來,我們就看Vue提供的具體的渲染DOM的方式。
一、聲明式的渲染
<div id="app">
<h2>{{ message }}</h2>
</div>
// vue-1.js
let app = new Vue({
// el聲明當前Vue實例中的數據作用的DOM區域
el: '#app',
data: {
message: 'Hello World'
}
});
這種渲染方式看起來跟模板字符串比較相似,但是實際上現在數據和 DOM 已經被建立了關聯,所有東西都是響應式的。只要 app 中的 message數據改變,頁面中的渲染會立刻隨之改變。
二、條件渲染
1. v-if
Vue 提供了條件渲染,用來控制切換一個元素是否顯示。
<div id="app">
<!-- 當flag爲true時,h2標籤在頁面上可見,flag爲false則不可見 -->
<h2 v-if="flag">Hello World</h2>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
flag: true
}
});
這裏我們遇到了一點新東西。h2標籤上的 v-if 特性被稱爲指令。指令帶有前綴 v-,以表示它們是 Vue 提供的特殊特性。每個指令,都會在渲染的 DOM 上應用特殊的響應式行爲。
指令其實就是 Vue 下達給DOM的命令,不同的指令代表代碼的不同行爲模式。v-if 指令代表的就是條件渲染,根據綁定的值決定要不要渲染這個 DOM 節點。
2. v-else
除了根據一個值,確定要不要渲染某個節點之外,我們還可以根據一個值確定要不要兩個節點交替互斥的顯示(比如購物類的app中,當購物車中有貨物時,就顯示購物車,否則顯示其他的提示信息)。
<div id="app">
<!-- 當flag爲true時,顯示Hello,爲false顯示World -->
<h2 v-if="flag">Hello</h2>
<h2 v-else="flag">World</h2>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
flag: true
}
});
v-else指令也可以不用寫具體的數據:
<h2 v-if="flag">Hello</h2>
<h2 v-else>World</h2>
效果不變,else 總會找到它之前最近的未被匹配的if,與之共用一個判斷值。
3. v-else-if
我們還可以使用數據,做多個元素的切換展示。
<div id="app">
<!-- num < 0 時顯示 -->
<h2 v-if="num < 0 ">I</h2>
<!-- num == 0時顯示 -->
<h2 v-else-if="num == 0 ">am</h2>
<!-- num爲其他值時顯示 -->
<h2 v-else>tom</h2>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
num: 0
}
});
注:
v-else 、v-else-if 必須跟在 v-if 或者 v-else-if之後。
4. v-show
也可以根據v-show指令確定要不要顯示元素。
<div id="app">
<!-- flag爲true時顯示,爲false隱藏 -->
<h2 v-show="flag">Hello World</h2>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
flag: true
}
});
注:
v-if系列是控制要不要創建元素,v-show系列是控制要不要顯示元素。如果這個元素在頁面中是不斷地被顯示/隱藏,就使用v-show,如果這個元素在某次操作之後就確定要不要渲染,之後也不會更改,就使用v-if。
三、循環渲染
Vue 提供 v-for 指令來渲染列表類的數據到DOM節點。
1. 渲染數組
<div id="app">
<!-- user是自定義聲明的一個局部變量,只作用當前這個循環內部,代表每次循環到的userList中的數據 -->
<div v-for="user in userList">
<strong>{{ user.name }}</strong>
<span>{{ user.age }}</span>
</div>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
userList: [{
name: 'tom',
age: 18
},{
name: 'jerry',
age: 17
},
{
name: 'jim',
age: 19
}]
}
});
除了可以循環到數組中的元素之外,還可以循環到當前元素的下標。
<div id="app">
<div v-for="(user,index) in userList">
<!-- index就是下標 -->
<i>{{ index }}</i>
<strong>{{ user.name }}</strong>
<span>{{ user.age }}</span>
</div>
</div>
2. 渲染對象
可以使用 v-for 指令渲染對象。
<div id="app">
<div v-for="(val, key, i) in user">
<!-- 鍵值對在對象中的順序 -->
<i>{{ i }}</i>
<!-- 值 -->
<strong>{{ val }}</strong>
<!-- 鍵 -->
<span>{{ key }}</span>
</div>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
user: {
name: 'tom',
age: 19,
sex: '女'
}
}
});
3. 渲染字符串
可以使用v-for指令渲染字符串。
<div id="app">
<div v-for="(val, i) in str">
<!-- 字符 -->
<strong>{{ val }}</strong>
<!-- val在str中的位置 -->
<span>{{ i }}</span>
</div>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
str: 'hello'
}
});
4. 根據數字循環渲染指定數量的節點
<div id="app">
<!-- img會被渲染5次 -->
<img src="star.png" v-for="n in 5">
</div>
練習:
渲染一個後臺系統中的用戶列表,還可以對用戶進行修改和刪除的操作(要有對應的按鈕)。
四、使用指令渲染
除了 {{ }} 之外,指令也可以將數據渲染在DOM節點上。
1. v-html
<div id="app">
<div v-html="str"></div>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
str: 'hello'
}
});
注:
- v-html 是以 innerHTML的方式渲染數據的。
- v-html 綁定的好處是當vue.js文件沒有被加載出來時,瀏覽器會認爲v-html指令只是一個普通的自定義屬性,不會將代碼暴露在瀏覽器中。
2. v-bind
前面的幾種渲染方式都是將數據渲染在標籤內,但是有時候我們需要動態的爲某些元素的屬性綁定一些數據。要使用 v-bind。
<div id="app">
<!-- 當flag爲true時,div 會添加一個 'active-box'的類名 -->
<div v-bind:class="{{ flag ? 'active-box' : '' }}"></div>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
flag: true
}
});
v-bind 可以簡寫:
<div :class="{{ flag ? 'active-box' : '' }}"></div>
注:
使用v-bind時,屬性內的執行代碼需要用 {{ }} 包括。
Vue中的表單輸入綁定
框架中有完整 DOM 操作系統,這個系統除了提供一系列的數據綁定方式之外,還提供數據獲取方式。
可以用 v-model 指令在表單 <input>
、<textarea>
及 <select>
元素上創建雙向數據綁定。它會根據控件類型自動選取正確的方法來更新元素
v-model 本質上不過是語法糖。它負責監聽用戶的輸入事件以更新數據,並對一些極端場景進行一些特殊處理。
一、 輸入框和輸入域的綁定
<div id="app">
<!-- 將這個輸入框的數據動態綁定在app的message上 -->
<input v-model="message">
<!-- 將message的數據渲染在頁面上 -->
<p>Message is: {{ message }}</p>
<!-- 將文本域的數據動態綁定在app的text上 -->
<textarea v-model="text"></textarea>
<!-- 渲染text -->
<p>Text is: {{ text }}</p>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
message: ''
text: ''
}
});
注:
- v-model 會忽略所有表單元素的 value、checked、selected 特性的初始值而總是將 Vue 實例的數據作爲數據來源。應該通過 JavaScript 在app的 data 選項中聲明初始值。
二、複選框的綁定
單個複選框
<div id="app">
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
checked: true
}
});
多個複選框
<div id="app">
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
// 複選框被選中,其對應的value值會被自動添加到數組中,取消選中時,自動從數組中刪除
checkedNames: []
}
});
三、單選框的綁定
<div id="app">
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<br>
<span>Picked: {{ picked }}</span>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
// picked的值是當前這組單選框中被選中的value值
picked: ''
}
});
四、下拉框的綁定
<div id="app">
<select v-model="selected">
<option disabled value="">請選擇</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
// selected中的值,是被選中的option中的數據
selected: ''
}
});
下拉框多選時需要綁定到一個數組。
<div id="app">
<select v-model="selected" multiple style="width: 50px;">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
selected: []
}
});
用 v-for 渲染動態選項,需要規定 option 的 value 值。
<div id="app">
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
selected: 'A',
options: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
]
}
});
注:
如果 v-model 表達式的初始值未能匹配任何選項,<select>
元素將被渲染爲“未選中”狀態。在 iOS 中,這會使用戶無法選擇第一個選項。因爲這樣的情況下,iOS 不會觸發 change 事件。因此,更推薦像上面這樣提供一個值爲空的禁用選項。
五、輸入框的修飾符
1 .lazy
在默認情況下,v-model 在每次 input 事件觸發後將輸入框的值與數據進行同步 (除了上述輸入法組合文字時)。你可以添加 lazy 修飾符,從而轉變爲使用 change 事件進行同步:
<input v-model.lazy="msg" >
2 .number
如果想自動將用戶的輸入值轉爲數值類型,可以給 v-model 添加 number 修飾符:
<input v-model.number="age" type="number">
3 .trim
如果要自動過濾用戶輸入的首尾空白字符,可以給 v-model 添加 trim 修飾符:
<input v-model.trim="msg">
Vue中的事件處理
Vue提供了 v-on 指令監聽 DOM 事件,並在觸發時運行一些 JavaScript 代碼。
一、事件的綁定、傳參和事件對象的獲取
1. 事件的綁定
<div id="app">
<button v-on:click="{{count++}}">+</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {
count: 0
}
});
v-on指令的簡寫:
<button @click="{{count++}}">+</button>
然而許多事件處理邏輯會更爲複雜,所以直接把 JavaScript 代碼寫在 v-on 指令中是不可行的。因此 v-on 還可以接收一個需要調用的方法名稱。
<div id="app">
<!-- 在執行點擊動作時調用一個函數 -->
<button @click="fn">click me</button>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
// 當前vue實例要用到的所有的數據
data: {},
// 當前實例要用到的所有的方法
methods: {
fn () {
// 函數體代碼
}
}
});
2. 調用事件時傳參
<div id="app">
<button @click="say('hello')">click me</button>
<button @click="say('what')">click me</button>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {},
methods: {
say (msg) {
console.log(msg);
}
}
});
3. 事件對象
<div id="app">
<button @click="say('hello', $event)">click me</button>
</div>
// vue-1.js
let app = new Vue({
el: '#app',
data: {},
methods: {
say (msg, e) {
// e 就是原生js中的事件對象
}
}
});
二、事件修飾符
在事件處理程序中調用 event.preventDefault() 或 event.stopPropagation() 是非常常見的需求。儘管我們可以在方法中輕鬆實現這點,但更好的方式是:方法只有純粹的數據邏輯,而不是去處理 DOM 事件細節。
爲了解決這個問題,Vue.js 爲 v-on 提供了事件修飾符。之前提過,修飾符是由點開頭的指令後綴來表示的。
1. 鼠標事件修飾符
- .stop
- .prevent
- .capture
- .self
- .once
- .passive
<!-- 阻止單擊事件繼續傳播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重載頁面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修飾符可以串聯 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修飾符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件監聽器時使用事件捕獲模式 -->
<!-- 即元素自身觸發的事件先在此處理,然後才交由內部元素進行處理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只當在 event.target 是當前元素自身時觸發處理函數 -->
<!-- 即事件不是從內部元素觸發的 -->
<div v-on:click.self="doThat">...</div>
<!-- 點擊事件將只會觸發一次 -->
<a v-on:click.once="doThis"></a>
<!-- 滾動事件的默認行爲 (即滾動行爲) 將會立即觸發 -->
<!-- 而不會等待 `onScroll` 完成 -->
<!-- 這其中包含 `event.preventDefault()` 的情況 -->
<div v-on:scroll.passive="onScroll">...</div>
注:
- 使用修飾符時,順序很重要;相應的代碼會以同樣的順序產生。因此,用 v-on:click.prevent.self 會阻止所有的點擊,而 v-on:click.self.prevent 只會阻止對元素自身的點擊。
- 不要把 .passive 和 .prevent 一起使用,因爲 .prevent 將會被忽略,同時瀏覽器可能會向你展示一個警告。請記住,.passive 會告訴瀏覽器你不想阻止事件的默認行爲
2. 按鍵修飾符
在監聽鍵盤事件時,我們經常需要檢查詳細的按鍵。Vue 允許爲 v-on 在監聽鍵盤事件時添加按鍵修飾符:
<!-- 只有在 `key` 是 `Enter` 時調用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
可以直接將 KeyboardEvent.key 暴露的任意有效按鍵名轉換爲 kebab-case 來作爲修飾符。
<input v-on:keyup.page-down="onPageDown">
可以綁定特定的鍵碼:
<!-- 按刪除鍵時觸發 -->
<input v-on:keyup.13="submit">
Vue 提供了絕大多數常用的按鍵碼的別名:
- .enter
- .tab
- .delete (捕獲“刪除”和“退格”鍵)
- .esc
- .space
- .up
- .down
- .left
- .right
注:
有一些按鍵 (.esc 以及所有的方向鍵) 在 IE9 中有不同的 key 值, 如果你想支持 IE9,這些內置的別名應該是首選。
3. 系統修飾鍵
可以用如下修飾符來實現僅在按下相應按鍵時才觸發鼠標或鍵盤事件的監聽器。
- .ctrl
- .alt
- .shift
- .meta
- .exact
.exact 修飾符允許你控制由精確的系統修飾符組合觸發的事件。
<!-- 即使 Alt 或 Shift 被一同按下時也會觸發 -->
<button @click.ctrl="onClick">A</button>
<!-- 有且只有 Ctrl 被按下的時候才觸發 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 沒有任何系統修飾符被按下的時候才觸發 -->
<button @click.exact="onClick">A</button>
4. 鼠標按鈕修飾符
- .left
- .right
- .middle
注: 這些修飾符會限制處理函數僅響應特定的鼠標按鈕。