vue.js官網教程學習筆記和學習摘要
起步
安裝
一個簡單的方法,直接把一個vue.js引入你的HTML頁面中,就像引入一個jq框架一樣,首先你要下載js文檔,然后用script標簽把它引進去,然后在</body>之前寫一個<script>標簽,將你的vue.js代碼寫進去
- step1:進入vue.js的官網:http://cn.vuejs.org/
- step2:點 "安裝v1.026"
點“開發版本”,然后就把一個“vue.js”文件下載下來了。
-
step3:你的頁面結構
HTML文件中:
HTML文件
記?。?.引入vue.js文件 2.在<script>標簽中寫vue.js代碼
運行效果:
概述
響應的數據綁定
Vue.js 的核心是一個響應的數據綁定系統,它讓數據與 DOM 保持同步非常簡單。
Vue.js 擁抱數據驅動的視圖概念。
組件系統
組件系統是 Vue.js 另一個重要概念,因為它提供了一種抽象,讓我們可以用獨立可復用的小組件來構建大型應用。
vue實例
構造器:
- 每個vue.js應用的起步都是通過構造函數Vue創建一個Vue的根實例
var vm = new Vue({
// 選項
})
- 實例化Vue時需要傳入選項對象,例如數據(data)、模板(template)、掛在元素、方法(method)、生命周期鉤子(例如:create)等選項。
eg:
var vm = new Vue({
data:{
message:'hello'
},
method:{
reverseMessage:function(){
xxx;
}
}
})
擴展vue構造器:預定義選項,創建可復用的組件構造器
var MyComponent = Vue.extend({
// 擴展選項
})// 所有的 `MyComponent` 實例都將以預定義的擴展選項被創建
var myComponentInstance = new MyComponent()
- 所有的 Vue.js 組件其實都是被擴展的 Vue 實例。
屬性與方法
每個 Vue 實例都會代理其 data 對象里所有的屬性:
var data = { a: 1 }
var vm = new Vue({
data: data//這里的data是被代理的屬性
})
vm.a === data.a // -> true
// 設置屬性也會影響到原始數據
vm.a = 2
data.a // -> 2
// ... 反之亦然
data.a = 3
vm.a // -> 3
實例屬性與方法
前綴:$
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // -> true
vm.$el === document.getElementById('example') // -> true
// $watch 是一個實例方法
vm.$watch('a', function (newVal, oldVal) {
// 這個回調將在 `vm.a` 改變后調用
}
實例生命周期
Vue 實例在創建時有一系列初始化步驟——例如,它需要建立數據觀察,編譯模板,創建必要的數據綁定。在每個過程如果有相應的生命周期鉤子,將會調用
var vm = new Vue({
data: {
a: 1
},
created: function () {//在實例創建后調用這個函數
// `this` 指向 vm 實例
console.log('a is: ' + this.a)
}
})
// -> "a is: 1"
數據綁定語法
- 插值
文本插值:(Mustache語法:雙大括號)
eg:
<span id="app">Message: {{ msg }}</span>
<script>
var vm = new Vue() {
el:'#app',//指定ID
data:{
msg:'hello'//替換ID為“app”的{{message}}
}
})
</script>
- HTML 特性
Mustache 標簽也可以用在 HTML 特性 (Attributes) 內:
<div id="item-{{ id }}"></div>
綁定表達式
雙大括號內的文本稱為綁定表達式,綁定表達式由一個簡單的JavaScript表達式和可選的一個或者多個過濾器構成。
- JavaScript表達式
eg:
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
tip:每個綁定只能包含單個表達式
<!-- 這是一個語句,不是一個表達式: -->
{{ var a = 1 }}
<!-- 流程控制也不可以,可改用三元表達式 -->
{{ if (ok) { return message } }}
- 過濾器(管道語法)
eg:
{{ message | capitalize }}//message的值通過過濾器capitalize,capitalize過濾器的作用是變換成大寫,所以message的值通過過濾器capitalize的結果是返回大寫化的值
tip:管道語法不是JavaScript語法,因此不能在表達式內使用過濾器,只能添加到表達式的后面。
過濾器可以串聯:{{ message | filterA | filterB }
指令
前綴:“v-”
指令的值:“綁定表達式”(JavaScript表達式、過濾器)
指令的職責:表達式的值改變式把某些特殊行為應用到DOM上
eg:
<p v-if="greeting">Hello!</p>
這里,v-if是一個指令,指令的值是表達式“greeting”的值,如果值為真,就插入< p>元素,如果是假,就刪除< p>元素。
- 參數
eg:
<a v-bind:href="url"></a>//v-bind 指令用于響應地更新 HTML 特性,href是參數,它告訴v-bind指令將元素的href特性跟表達式url的值綁定
<a v-on:click="doSomething">//v-on 指令,它用于監聽 DOM 事件
- 修飾符
- 以半角句號 . 開始的特殊后綴
- 用于表示指令應當以特殊方式綁定
eg:
<a v-bind:href.literal="/a/b/c"></a>//.literal 修飾符告訴指令將它的值解析為一個字面字符串而不是一個表達式
- 縮寫
v-bind的縮寫
eg:
<!-- 完整語法 -->
<a v-bind:href="url"></a>
<!-- 縮寫 -->
<a :href="url"></a>
<!-- 完整語法 -->
<button v-bind:disabled="someDynamicCondition">Button</button>
<!-- 縮寫 -->
<button :disabled="someDynamicCondition">Button</button>
v-on的縮寫
eg:
<!-- 完整語法 -->
<a v-on:click="doSomething"></a>
<!-- 縮寫 -->
<a @click="doSomething"></a>
計算屬性
eg:
var vm = new Vue({
el: '#example',
data: {
a: 1
},
computed: {
// 一個計算屬性的 getter
b: function () {
// `this` 指向 vm 實例
return this.a + 1//b的值是計算出來的,依賴于a的值
}
}
})
- $watch方法:監測數據的變化
eg:
<div id="demo">{{fullName}}</div>
<script>
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
}
})
vm.$watch('firstName', function (val) {//監測‘firstName’值的變化,如果變化,就調用后面這個函數,將firstName的新值傳給參數val
this.fullName = val + ' ' + this.lastName
})
vm.$watch('lastName', function (val) {//監測‘lastName’值的變化,如果變化,就調用后面這個函數,將lasttName的新值傳給參數val
this.fullName = this.firstName + ' ' + val
})
</script>
- 優化:因為上面的命令式回調是重復的,最好是使用計算屬性
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
- 也可以使用計算屬性設置值:計算屬性默認只是 getter,不過也可以提供一個 setter
eg:
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
調用vm.fullName = 'John Doe' 時,setter會被調用,為firstName和lastName賦值,'John Doe' 傳給參數newValue,var names = newValue.split(' ')將newValue以’ ‘為分隔符分隔為一個數組儲存在names里面,所以names[0]的值為John,names[names.length - 1]即names[1]的值為Doe,然后getter被調用,為fullName計算值。
Class 與 Style 綁定
綁定 HTML Class
- 對象語法
可以傳給 v-bind:class 一個對象,以動態地切換 class。
v-bind:class 指令可以與普通的 class 特性共存
eg:
<div class="static" v-bind:class="{ 'class-a': isA, 'class-b': isB }"></div>
data: {
isA: true,
isB: false
}
class-a是一個類名,class-b也是一個類名,通過data的isA和isB設置是否為元素綁定相應的類。渲染為:
<div class="static class-a"></div>
也可以直接綁定一個對象
<div v-bind:class="classObject"></div>
data: {
classObject: {
'class-a': true,
'class-b': false
}
}
- 數組語法
可以把一個數組傳給 v-bind:class,以應用一個 class 列表:
eg:
<div v-bind:class="[classA, classB]">
data: {
classA: 'class-a',
classB: 'class-b'
}
渲染為:
<div class="class-a class-b"></div>
也可以:
<div v-bind:class="[classA, isB ? classB : '']">
始終添加classA類,如果isB為true,就添加classB類,如果isB為false,就不添加classB。
也可以:
eg:
<div v-bind:class="[classA, { classB: isB, classC: isC }]">
始終添加classA類,根據isB的值選擇是否添加classB,根據IsC選擇是否添加classC。
綁定內聯樣式
- 對象語法
v-bind:style 的對象語法:
eg:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize: 30
}
直接綁定到一個樣式對象通常更好:
<div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
- 數組語法
v-bind:style 的數組語法可以將多個樣式對象應用到一個元素上:
<div v-bind:style="[styleObjectA, styleObjectB]">
條件渲染
- v-if
eg:
<h1 v-if="ok">Yes</h1>
如果v-if的屬性值——“ok”表達式的值為真,則顯示“yes”,否則不顯示“yes”。
eg:
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
如果v-if的屬性值——“ok”表達式的值為真,則顯示“yes”,否則不顯示v-else對應的語句“No”。
- template v-if
如果想用v-if同時顯示或者隱藏多個元素,可以用<template>將多個元素包裹起來。把一個 <template> 元素當做包裝元素,并在上面使用 v-if,最終的渲染結果不會包含它。
eg:
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
<strong>
tip:官網教程頁沒有詳細說明v-if的用法,因此我在學習時使用v-if寫的例子出現了問題:
首先,一開始我以為代碼是這樣寫的:
然而,雖然“ok”值為false,但是仍然顯示:
控制臺報錯:
這個報錯是說:v-if不可以用于根元素。
應將代碼更正為:
即可以用一個< div>將帶有v-if的元素包裹起來,這時候控制臺就不會報錯了。
同樣地,使用<template>包裹多個元素時,,也要用一個< div>將帶有v-if的<template>包裹起來。
代碼:
顯示效果:
</strong>
- v-show
用法大體和v-if一樣:
eg:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="two"><h1 v-show="ok">haha</h1></div>
<script>
var vm2 = new Vue({
el:"#two",
data: {
ok:true
}
})
</script>
</body>
</html>
顯示效果:
- v-show與v-if的區別
1.v-show 不支持 <template> 語法。
2.v-show 的元素會始終渲染并保持在 DOM 中。v-show 是簡單的切換元素的 CSS 屬性 display。
eg:
顯示效果:
檢查元素查看代碼渲染結果:
可見,v-show情況下即使為false,元素也會被渲染并保持在DOM中,只是display值為none。
v-if的情況下:
顯示效果:
檢查元素查看代碼渲染結果:
看,v-if情況下,當值為false時,元素不會被渲染出來。
tip: 在切換 v-if 塊時,Vue.js 有一個局部編譯/卸載過程,因為 v-if 之中的模板也可能包括數據綁定或子組件。v-if 是真實的條件渲染,因為它會確保條件塊在切換當中合適地銷毀與重建條件塊內的事件監聽器和子組件。
v-if 也是惰性的:如果在初始渲染時條件為假,則什么也不做——在條件第一次變為真時才開始局部編譯(編譯會被緩存起來)。
相比之下,v-show 簡單得多——元素始終被編譯并保留,只是簡單地基于 CSS 切換。
一般來說,v-if 有更高的切換消耗而 v-show 有更高的初始渲染消耗。因此,如果需要頻繁切換 v-show 較好,如果在運行時條件不大可能改變 v-if 較好。
- v-else
可以用 v-else 指令給 v-if 或 v-show 添加一個 “else 塊”:
eg:
<div v-if="Math.random() > 0.5">
Sorry
</div>
<div v-else>
Not sorry
</div>
tip:v-else 元素必須立即跟在 v-if 或 v-show 元素的后面——否則它不能被識別。
- 組件警告
將 v-show 用在組件上時,因為指令的優先級 v-else 會出現問題。因此不要這樣做:
<custom-component v-show="condition"></custom-component>
<p v-else>這可能也是一個組件</p>
用另一個 v-show 替換 v-else:
<custom-component v-show="condition"></custom-component>
<p v-show="!condition">這可能也是一個組件</p>
這樣就可以達到 v-if 的效果。
列表渲染
- v-for
可以使用 v-for 指令基于一個數組渲染一個列表。這個指令使用特殊的語法,形式為 item in items,items 是數據數組,item 是當前數組元素的別名:
eg:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
<script>
var vm3 = new Vue ({
el:"#three",
data: {
items:[
{message:'haha'},
{message: 'hehe'}
]
}
})
</script>
</body>
</html>
items是一個數組,使用v-for將該數組中的每個數組元素渲染,然后顯示每個數組元素的message。
在 v-for 塊內我們能完全訪問父組件作用域內的屬性,另有一個特殊變量 $index,它是當前數組元素的索引:
eg:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
<li v-for="item in items">
{{ parentMessage }} - {{ $index }} - {{ item.message }}
</li>
</ul>
<script>
var vm3 = new Vue ({
el:"#three",
data: {
parentMessage: 'Parent',
items:[
{message:'haha'},
{message: 'hehe'}
]
}
})
</script>
</body>
</html>
運行結果:
另外,可以為索引指定一個別名:
上面代碼中,“xuhao”是為索引值起的一個別名,注意上下一致。
tip:從 1.0.17 開始可以使用 of 分隔符,更接近 JavaScript 遍歷器語法:
<div v-for="item of items"></div>
- template v-for
類似于 template v-if,也可以將 v-for 用在 <template> 標簽上,以渲染一個包含多個元素的塊。
eg:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
<template v-for="(xuhao,item) in items">
<li>
{{ parentMessage }} - {{ xuhao }} - {{ item.message }}
</li>
<li>yiyi</li>
</template>
</ul>
<script>
var vm3 = new Vue ({
el:"#three",
data: {
parentMessage: 'Parent',
items:[
{message:'haha'},
{message: 'hehe'}
]
}
})
</script>
</body>
</html>
因為v-for是在template上的,而每個template都有< li>yiyi</li>,所以會被多次渲染出來。
- 變異方法
push():增加數組元素;
pop():刪除數組元素;
reverse():將該數組元素向前移動一位。
eg1:
看,代碼中原本是“haha”在前,“hehe”在后,使用reverse()后,“hhe”移動到了前面。
eg2:
看,pop()之后只剩一個數組元素。
eg3:
看,push()之后為數組動態地添加了一個新元素。
- 問題
因為 JavaScript 的限制,Vue.js 不能檢測到下面數組變化:
直接用索引設置元素,如 vm.items[0] = {};
修改數據的長度,如 vm.items.length = 0。
vue.js用索引設置數組元素:$set(索引值,新元素)
- 對象v-for
可以使用 v-for 遍歷對象。作用域內還可以訪問另外一個特殊變量 $key。
eg:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
<li v-for="value in object">
{{ $key }} : {{ value }}
</li>
</ul>
<script>
var vm3 = new Vue ({
el:"#three",
data: {
object: {
FirstName: 'Frank',
LastName: 'Jane',
age: 20
}
}
})
</script>
</body>
</html>
也可以給對象的鍵提供一個別名:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
<li v-for="(key,value) in object">
{{ key }} : {{ value }}
</li>
</ul>
<script>
var vm3 = new Vue ({
el:"#three",
data: {
object: {
FirstName: 'Frank',
LastName: 'Jane',
age: 20
}
}
})
</script>
</body>
</html>
方法與事件處理器
方法處理器
- v-on監聽DOM事件
eg:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="four">
<button v-on:click="greet">greet</button>//為button綁定一個單擊事件處理器,當被點擊時執行greet方法
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
name:'vue.js'
},
methods: {
greet: function (event) {
alert('hello ' + this.name + '!')
alert(event.target.tagName)
}
}
})
vm3.greet();//頁面加載后執行此函數,因為沒有調用它的元素,所以不會執行alert(event.target.tagName)這一句
</script>
</body>
</html>
運行結果:
點擊按鈕:
內聯語句處理器
eg:
<div id="four">
<button v-on:click="greet('hi')">greet</button>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
name:'vue.js'
},
methods: {
greet: function (msg) {
alert(msg)
}
}
})
</script>
點擊按鈕:
有時也需要在內聯語句處理器中訪問原生 DOM 事件??梢杂锰厥庾兞?$event 把它傳入方法:
eg:
<div id="four">
<button v-on:click="greet('hi',$event)">greet</button>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
name:'vue.js'
},
methods: {
greet: function (msg,event) {
alert(event)
}
}
})
</script>
事件修飾符
Vue.js 為 v-on 提供兩個 事件修飾符:.prevent 與 .stop
<a v-on:click.stop="doThis"></a>
<form v-on:submit.prevent="onSubmit"></form>
eg1:
<div id="four">
<button v-on:click="doThis"><a v-on:click="doThis">greet</a></button>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
name:'vue.js'
},
methods: {
doThis: function (event) {
alert('haha')
}
}
})
</script>
上例會冒泡,點擊的時候會出現兩次彈窗,因為冒泡,< a>和< button>都觸發了click。
eg2:
上例不會冒泡,點擊的時候只出現一次彈窗。
eg3:
由于submit按鈕的默認行為,點擊submit后會重載頁面,因此會發現,在此例中,點擊submit后,首先出現了彈窗,然后整個頁面被刷新。
eg4:
添加了事件修飾符,.prevent,避免了點擊提交按鈕的時候頁面被重載。
按鍵修飾符
監聽鍵盤事件時,vue.js允許為v-on添加按鍵修飾符,并為最常用的按鍵提供了別名:
- 全部的按鍵別名:
- enter
- tab
- delete
- esc
- space
- up
- down
- left
- right
eg:
按下tab鍵時,執行submit方法,出現彈窗。
表單控件綁定
基礎用法
- Text
eg:
<div id="four">
<span>Message is: {{ message }}</span>
<br>
<input type="text" v-model="message" placeholder="edit me" />
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
message:''
},
})
</script>
注意:一定要將“Message is”和input輸入框包裹在一起,上例中將它們用一個div包裹在一起,并且id要寫在包裹它們的標簽上,即div標簽上。
實現雙向數據綁定,同步顯示。
- Multiline text
eg:
<div id="four">
<span>Message is: </span>
<p>{{ message }}</p>
<br>
<textarea v-model="message" placeholder="edit me"></textarea>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
message:''
},
})
</script>
- checkbox
單個勾選框
eg:
<div id="four">
<input type="checkbox" id="check" v-model="checked">
<label for="check">{{ checked }}</label>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
message:''
},
})
</script>
會根據勾選狀態改變勾選框的label值。
多個勾選框,選中的同時顯示選中的value值:
eg:
<div id="four">
<input type="checkbox" id="jack" v-model="checkedName" value="jack">
<label for="jack">jack</label>
<input type="checkbox" id="jane" v-model="checkedName" value="jane">
<label for="jane">jane</label>
<input type="checkbox" id="jim" v-model="checkedName" value="jim">
<label for="jim">jim</label>
<br>
<span>check: {{ checkedName }} </span>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
checkedName:[]
},
})
</script>
- radio
eg:
<div id="four">
<input type="radio" id="one" value="one" v-model="message">
<label for="one">one</label>
<input type="radio" id="two" value="two" v-model="message">
<label for="two">two</label>
<br>
<span>picked: {{ message }}</span>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
message:''
},
})
</script>
- select
eg:
<div id="four">
<select v-model="select">
<option selected="selected">A</option>
<option>B</option>
<option>C</option>
</select>
<span>selected: {{ select }}</span>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
select:''
},
})
</script>
eg2:
動態選項,用v-for渲染:
eg:
<div id="four">
<select v-model="select">
<option v-for="option in options" v-bind:value="option.value">//v-bind:value為option設置value值
{{ option.text }}//option.text為option設置標簽文本
</option>
</select>
<br>
<span>selected: {{ select }}</span>//select和v-model對應,v-model指示的是option的value值
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
options:[
{ text:'one', value:'a'},
{ text:'two', value:'b'},
{ text:'three', value:'c'}
]
},
})
</script>
- 綁定value值
綁定 value 到 Vue 實例的一個動態屬性上,這時可以用 v-bind 實現,并且這個屬性的值可以不是字符串。
eg:
<div id="four">
<input type="checkbox" id="check" v-model="checked" v-bind:true-value="yes" v-bind:false-value="no">
<label for="check">{{ checked }}</label>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
checked:'',
yes:'yes',
no:'no'
},
})
</script>
這樣,當單選框被勾選時,value值為vue實例中的yes屬性值,當單選框不被勾選時,value值為vue實例中的no屬性值。
- 參數特性
lazy:
在默認情況下,v-model 在input 事件中同步輸入框值與數據,可以添加一個特性 lazy,從而改到在 change 事件中同步:
number:
如果想自動將用戶的輸入轉為 Number 類型(如果原值的轉換結果為 NaN 則返回原值),可以添加一個特性 number:
debounce:
debounce 設置一個最小的延時,在每次敲擊之后延時同步輸入框的值與數據。如果每次更新都要進行高耗操作(例如在輸入提示中 Ajax 請求),它較為有用。
注意 debounce 參數不會延遲 input 事件:它延遲“寫入”底層數據。因此在使用 debounce 時應當用 vm.$watch() 響應數據的變化。若想延遲 DOM 事件,應當使用 debounce 過濾器。