vue入門教程vueJS2.X
寫在前面
看完此教程可以達到:能看懂並能修改簡單的vue項目
。
看的過程中,請把所有例子都放到html
文件中跑一遍。
Vue.js 是什么
Vue.js(讀音 /vjuː/,類似於 view) 是一套構建用戶界面的漸進式框架。與其他重量級框架不同的是,Vue 采用自底向上增量開發的設計。Vue 的核心庫只關注視圖層,它不僅易於上手,還便於與第三方庫或既有項目整合。
什么叫漸進式
沒有多做職責之外的事,它只是個輕量視圖而已,只做了自己該做的事,沒有做不該做的事,僅此而已。
你可以在原有的項目上面,把一兩個組件改用它實現,當jQuery用
也可以整個用它全家桶開發,當Angular用
還可以在頁面上當模板引擎用
特點
- 輕量級的框架
- 雙向數據綁定
- 指令
- 組件化
優點
- 簡單:官方文檔很清晰,簡單易學,國人開發,生態好,社區、文檔齊全
- 快速:異步批處理方式更新DOM (Virtual DOM)
- 組合:解耦的、可復用的組件
- 緊湊:28.96kb min+gzip 且無依賴
- 強大:性能好,表達式、指令、組件化···
缺點
- 不支持IE8
vue的使用
安裝
vue的 安裝方式 有很多,這里所有的示例都是通過
<script>
標簽引入, Vue就會被注冊為一個全局變量。
<script src="https://vuejs.org/js/vue.min.js"></script>
實例
hello vue!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>hello vue!</title>
<script src="https://vuejs.org/js/vue.min.js"></script>
</head>
<body>
<div id="app">
{{ message }}
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
</html>
查看運行結果 此運行頁面,僅供查看結果使用,操作時,把代碼復制到新建的html文件中運行,下同
我們已經生成了我們的第一個 Vue 應用!看起來這跟單單渲染一個字符串模板非常類似,但是 Vue 在背后做了大量工作。現在數據和 DOM 已經被綁定在一起,所有的元素都是響應式的。我們如何知道?打開你的瀏覽器的控制台(就在這個頁面打開,或者右鍵點擊
審查元素
),在控制台輸入app.message='xxxxx'
,你將看到上例相應地更新。
通過指令綁定數據
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>指令</title>
<script src="https://vuejs.org/js/vue.min.js"></script>
</head>
<body>
<div id="app">
<p>
鼠標懸停在圖片上可以看到提示內容
</p>
<img v-bind:title="message" src="https://img.alicdn.com/imgextra/i2/2296013456/TB2ia_RvKJ8puFjy1XbXXagqVXa_!!2296013456.png"/>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: '這是個寶箱!'
}
})
</script>
</body>
</html>
查看運行結果
你看到的
v-bind
屬性被稱為指令。指令帶有前綴v-
,以表示它們是 Vue 提供的特殊屬性。可能你已經猜到了,它們會在渲染的 DOM 上應用特殊的響應式行為。簡言之,這里該指令的作用是:“將這個元素節點的 title 屬性和 Vue 實例的 message 屬性保持一致”。
再次打開瀏覽器的 JavaScript 控制台輸入 app.message = '新消息'
,就會再一次看到這個綁定了 title 屬性的 HTML 已經進行了更新。
條件與循環
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>條件與循環</title>
<script src="https://vuejs.org/js/vue.min.js"></script>
</head>
<body>
<div id="app">
<p v-if="seen">現在你看到我了</p>
<ul>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ul>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
seen: true,
todos: [
{ text: '學習 JavaScript' },
{ text: '學習 Vue' },
{ text: '整個牛項目' }
]
}
})
</script>
</body>
</html>
繼續在控制台設置
app.seen = false
,你會發現“現在你看到我了”
消失了。在控制台里,輸入
app.todos.push({ text: '新項目' })
,你會發現列表中添加了一個新項。
雙向綁定
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>表單雙向綁定</title>
<script src="https://vuejs.org/js/vue.min.js"></script>
</head>
<body>
<div id="app">
<p>{{message}}</p>
<input type="text" name="test" id="test" value="" v-model="message" />
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message :'hello vue!'
}
})
</script>
</body>
</html>
查看運行結果
Vue 還提供了
v-model
指令,它能輕松實現表單輸入和應用狀態之間的雙向綁定。
使用JavaScript表達式
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>表達式</title>
<script src="https://vuejs.org/js/vue.min.js"></script>
</head>
<body>
<div id="app">
<div v-if="Math.random() > 0.5">
隨機數大於 0.5
</div>
<div v-else>
隨機數不大於 0.5
</div>
</div>
<script>
new Vue({
el: '#app'
})
</script>
</body>
</html>
模板語法
文本
數據綁定最常見的形式就是使用 Mustache
語法(雙大括號)的文本插值:
<span>Message: {{ msg }}</span>
Mustache
標簽將會被替代為對應數據對象上 msg
屬性的值。無論何時,綁定的數據對象上 msg
屬性發生了改變,插值處的內容都會更新。
通過使用 v-once
指令,你也能執行一次性地插值,當數據改變時,插值處的內容不會更新。但請留心這會影響到該節點上所有的數據綁定:
<span v-once>This will never change: {{ msg }}</span>
雙大括號會將數據解釋為純文本,而非 HTML 。為了輸出真正的 HTML ,你需要使用 v-html
指令:
<div v-html="rawHtml"></div>
這個 div 的內容將會被替換成為屬性值 rawHtml,直接作為 HTML —— 數據綁定會被忽略。注意,你不能使用 v-html
來復合局部模板,因為 Vue 不是基於字符串的模板引擎。組件更適合擔任 UI 重用與復合的基本單元。
你的站點上動態渲染的任意 HTML 可能會非常危險,因為它很容易導致 XSS 攻擊。請只對可信內容使用 HTML 插值,絕不要對用戶提供的內容插值。
屬性
Mustache
不能在 HTML 屬性中直接使用,應使用 v-bind指令
:
<div v-bind:id="dynamicId"></div>
這對布爾值的屬性也有效 —— 如果條件被求值為 false
的話該屬性會被移除:
<button v-bind:disabled="isButtonDisabled">Button</button>
使用 JavaScript 表達式
迄今為止,在我們的模板中,我們一直都只綁定簡單的屬性鍵值。但實際上,對於所有的數據綁定, Vue.js 都提供了完全的 JavaScript 表達式支持。
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
這些表達式會在所屬 Vue 實例的數據作用域下作為 JavaScript 被解析。有個限制就是,每個綁定都只能包含單個表達式,所以下面的例子都不會生效。
<!-- 這是語句,不是表達式 -->
{{ var a = 1 }}
<!-- 流控制也不會生效,請使用三元表達式 -->
{{ if (ok) { return message } }}
模板表達式都被放在沙盒中,只能訪問全局變量的一個白名單,如
Math
和Date
。你不應該在模板表達式中試圖訪問用戶定義的全局變量。
指令
指令(Directives)是帶有 v-
前綴的特殊屬性。指令屬性的值預期是單一 JavaScript
表達式(除了 v-for
,之后再討論)。指令的職責就是當其表達式的值改變時相應地將某些行為應用到 DOM 上。讓我們回顧一下在介紹里的例子:
<p v-if="seen">現在你看到我了</p>
這里, v-if
指令將根據表達式 seen
的值的真假來移除/插入 <p>
元素。
參數
一些指令能接受一個“參數”,在指令后以冒號指明。例如, v-bind
指令被用來響應地更新 HTML
屬性:
<a v-bind:href="url"></a>
在這里 href
是參數,告知 v-bind
指令將該元素的 href
屬性與表達式 url
的值綁定。
另一個例子是 v-on
指令,它用於監聽 DOM 事件:
<a v-on:click="doSomething">
在這里參數是監聽的事件名。我們也會更詳細地討論事件處理。
修飾符
修飾符(Modifiers)是以半角句號 .
指明的特殊后綴,用於指出一個指令應該以特殊方式綁定。例如,.prevent
修飾符告訴 v-on
指令對於觸發的事件調用 event.preventDefault()
:
<form v-on:submit.prevent="onSubmit"></form>
之后當我們更深入地了解 v-on
與 v-model
時,會看到更多修飾符的使用。
縮寫
v-
前綴在模板中是作為一個標示 Vue 特殊屬性的明顯標識。當你使用 Vue.js 為現有的標記添加動態行為時,它會很有用,但對於一些經常使用的指令來說有點繁瑣。同時,當搭建 Vue.js 管理所有模板的 SPA
時,v-
前綴也變得沒那么重要了。因此,Vue.js 為兩個最為常用的指令提供了特別的縮寫:
v-bind 縮寫
<!-- 完整語法 -->
<a v-bind:href="url"></a>
<!-- 縮寫 -->
<a :href="url"></a>
v-on 縮寫
<!-- 完整語法 -->
<a v-on:click="doSomething"></a>
<!-- 縮寫 -->
<a @click="doSomething"></a>
它們看起來可能與普通的 HTML 略有不同,但 : 與 @ 對於屬性名來說都是合法字符,在所有支持 Vue.js 的瀏覽器都能被正確地解析。而且,它們不會出現在最終渲染的標記。縮寫語法是完全可選的,但隨着你更深入地了解它們的作用,你會慶幸擁有它們。
計算屬性
模板內的表達式是非常便利的,但是它們實際上只用於簡單的運算。在模板中放入太多的邏輯會讓模板過重且難以維護。例如:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
在這種情況下,模板不再簡單和清晰。在意識到這是反向顯示 message
之前,你不得不再次確認第二遍。當你想要在模板中多次反向顯示 message
的時候,問題會變得更糟糕。
這就是對於任何復雜邏輯,你都應當使用計算屬性的原因。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>計算屬性</title>
<script src="https://vuejs.org/js/vue.min.js"></script>
</head>
<body>
<div id="example">
<p>Original message: "{{ message }}"</p>
<input type="text" name="test" id="test" value="" v-model="message"/>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
<script>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// a computed getter
reversedMessage: function() {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
}
}
})
</script>
</body>
</html>
這里我們聲明了一個計算屬性 reversedMessage
。我們提供的函數將用作屬性 vm.reversedMessage
的 getter
。
console.log(vm.reversedMessage) // -> 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // -> 'eybdooG'
你可以打開瀏覽器的控制台,自行修改例子中的 vm
。 vm.reversedMessage
的值始終取決於 vm.message
的值。
你可以像綁定普通屬性一樣在模板中綁定計算屬性。 Vue 知道 vm.reversedMessage
依賴於 vm.message
,因此當 vm.message 發生改變時,所有依賴於 vm.reversedMessage
的綁定也會更新。而且最妙的是我們已經以聲明的方式創建了這種依賴關系:計算屬性的 getter
是沒有副作用,這使得它易於測試和推理。
Class 與 Style 綁定
數據綁定一個常見需求是操作元素的 class
列表和它的內聯樣式。因為它們都是屬性 ,我們可以用v-bind
處理它們:只需要計算出表達式最終的字符串。不過,字符串拼接麻煩又易錯。因此,在 v-bind
用於 class
和 style
時, Vue.js 專門增強了它。表達式的結果類型除了字符串之外,還可以是對象或數組。
對象語法
我們可以傳給 v-bind:class
一個對象,以動態地切換 class
。
<div v-bind:class="{ active: isActive }"></div>
上面的語法表示 class active
的更新將取決於數據屬性 isActive
是否為真值 。
我們也可以在對象中傳入更多屬性用來動態切換多個 class
。此外, v-bind:class
指令可以與普通的 class 屬性共存。如下模板:
<div class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
如下 data:
data: {
isActive: true,
hasError: false
}
渲染為:
<div class="static active"></div>
當 isActive
或者 hasError
變化時,class
列表將相應地更新。例如,如果 hasError
的值為 true
, class列表將變為 "static active text-danger"
。
你也可以直接綁定數據里的一個對象:
<div v-bind:class="classObject"></div>
data: {
classObject: {
active: true,
'text-danger': false
}
}
渲染的結果和上面一樣。我們也可以在這里綁定返回對象的計算屬性。這是一個常用且強大的模式:
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal',
}
}
}
數組語法
我們可以把一個數組傳給 v-bind:class
,以應用一個 class
列表:
<div v-bind:class="[activeClass, errorClass]">
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
渲染為:
<div class="active text-danger"></div>
如果你也想根據條件切換列表中的 class
,可以用三元表達式:
<div v-bind:class="[isActive ? activeClass : '', errorClass]">
此例始終添加 errorClass
,但是只有在 isActive
是 true
時添加 activeClass
。
不過,當有多個條件 class
時這樣寫有些繁瑣。可以在數組語法中使用對象語法:
<div v-bind:class="[{ active: isActive }, errorClass]">
條件渲染
v-if
語法格式:
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
在<template>
中配合 v-if 條件渲染一整組
因為 v-if
是一個指令,需要將它添加到一個元素上。但是如果我們想切換多個元素呢?此時我們可以把一個 <template>
元素當做包裝元素,並在上面使用 v-if
。最終的渲染結果不會包含 <template>
元素。
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
v-else
你可以使用 v-else
指令來表示 v-if
的 else
塊:
<div v-if="Math.random() > 0.5">
Now you see me
</div>
<div v-else>
Now you don't
</div>
v-else
元素必須緊跟在v-if
或者v-else-if
元素的后面——否則它將不會被識別。
v-else-if
2.1.0 新增
v-else-if
,顧名思義,充當 v-if
的 else-if
塊。可以鏈式地使用多次:
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
類似於 v-else
,v-else-if
必須緊跟在 v-if
或者 v-else-if
元素之后。
v-show
另一個用於根據條件展示元素的選項是 v-show
指令。用法大致一樣:
<h1 v-show="ok">Hello!</h1>
不同的是帶有 v-show
的元素始終會被渲染並保留在 DOM 中。v-show
是簡單地切換元素的 CSS
屬性 display
。
注意,
v-show
不支持<template>
語法,也不支持v-else
。
v-if vs v-show
v-if
是“真正的”條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建。
v-if
也是惰性的:如果在初始渲染時條件為假,則什么也不做——直到條件第一次變為真時,才會開始渲染條件塊。
相比之下, v-show
就簡單得多——不管初始條件是什么,元素總是會被渲染,並且只是簡單地基於 CSS
進行切換。
一般來說, v-if
有更高的切換開銷,而 v-show
有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用 v-show
較好;如果在運行時條件不太可能改變,則使用 v-if
較好。
列表渲染
v-for
我們用 v-for
指令根據一組數組的選項列表進行渲染。 v-for
指令需要以 item in items
形式的特殊語法, items
是源數據數組並且 item
是數組元素迭代的別名。
基本用法
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{message: 'Foo' },
{message: 'Bar' }
]
}
})
結果:
Foo
Bar
在 v-for
塊中,我們擁有對父作用域屬性的完全訪問權限。 v-for
還支持一個可選的第二個參數為當前項的索引。
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
結果:
Parent - 0 - Foo
Parent - 1 - Bar
你也可以用 of
替代 in
作為分隔符,因為它是最接近 JavaScript
迭代器的語法:
<div v-for="item of items"></div>
Template v-for
如同 v-if
模板,你也可以用帶有 v-for
的 <template>
標簽來渲染多個元素塊。例如:
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider"></li>
</template>
</ul>
對象迭代 v-for
你也可以用 v-for
通過一個對象的屬性來迭代。
<ul id="repeat-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
new Vue({
el: '#repeat-object',
data: {
object: {
firstName: 'John',
lastName: 'Doe',
age: 30
}
}
})
結果:
John
Doe
30
你也可以提供第二個的參數為鍵名:
<div v-for="(value, key) in object">
{{ key }} : {{ value }}
</div>
第三個參數為索引:
<div v-for="(value, key, index) in object">
{{ index }}. {{ key }} : {{ value }}
</div>
在遍歷對象時,是按 Object.keys()
的結果遍歷,但是不能保證它的結果在不同的 JavaScript
引擎下是一致的。
整數迭代 v-for
v-for
也可以取整數。在這種情況下,它將重復多次模板。
<div>
<span v-for="n in 10">{{ n }} </span>
</div>
結果:
1 2 3 4 5 6 7 8 9 10
事件處理器
監聽事件
可以用 v-on
指令監聽 DOM
事件來觸發一些 JavaScript
代碼。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>事件處理</title>
<script src="https://vuejs.org/js/vue.min.js"></script>
</head>
<body>
<div id="example-1">
<button v-on:click="counter += 1">增加 1</button>
<p>這個按鈕被點擊了 {{ counter }} 次。</p>
</div>
<script type="text/javascript">
var example1 = new Vue({
el: '#example-1',
data: {
counter: 0
}
})
</script>
</body>
</html>
方法事件處理器
許多事件處理的邏輯都很復雜,所以直接把 JavaScript
代碼寫在 v-on
指令中是不可行的。因此 v-on
可以接收一個定義的方法來調用。
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>事件處理</title>
<script src="https://vuejs.org/js/vue.min.js"></script>
</head>
<body>
<div id="example-2">
<!-- `greet` 是在下面定義的方法名 -->
<button v-on:click="greet">Greet</button>
</div>
<script type="text/javascript">
var example2 = new Vue({
el: '#example-2',
data: {
name: 'Vue.js'
},
// 在 `methods` 對象中定義方法
methods: {
greet: function(event) {
// `this` 在方法里指當前 Vue 實例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if(event) {
alert(event.target.tagName)
}
}
}
})
// 也可以用 JavaScript 直接調用方法
example2.greet() // -> 'Hello Vue.js!'
</script>
</body>
</html>
內聯處理器方法
除了直接綁定到一個方法,也可以用內聯 JavaScript
語句:
<div id="example-3">
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
</div>
new Vue({
el: '#example-3',
methods: {
say: function (message) {
alert(message)
}
}
})
結果:
Say hi
Say what
有時也需要在內聯語句處理器中訪問原生 DOM 事件。可以用特殊變量 $event
把它傳入方法:
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
// ...
methods: {
warn: function (message, event) {
// 現在我們可以訪問原生事件對象
if (event) event.preventDefault()
alert(message)
}
}
事件修飾符
在事件處理程序中調用 event.preventDefault()
或 event.stopPropagation()
是非常常見的需求。盡管我們可以在 methods
中輕松實現這點,但更好的方式是:methods
只有純粹的數據邏輯,而不是去處理 DOM
事件細節。
為了解決這個問題, Vue.js
為 v-on
提供了 事件修飾符。通過由點(.)
表示的指令后綴來調用修飾符。
.stop
.prevent
.capture
.self
.once
<!-- 阻止單擊事件冒泡 -->
<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>
<!-- 只當事件在該元素本身(比如不是子元素)觸發時觸發回調 -->
<div v-on:click.self="doThat">...</div>
<!-- 點擊事件將只會觸發一次 -->
<a v-on:click.once="doThis"></a>
使用修飾符時,順序很重要;相應的代碼會以同樣的順序產生。因此,用
@click.prevent.self
會阻止所有的點擊,而@click.self.prevent
只會阻止元素上的點擊。
進階玩法
此篇為入門教程,想成為高級玩家,請點這里
轉載請注明出處
作者:xuesswuniu2010@126.com
時間:2017年07月19日
最后修改時間:2017年07月19日