vue入門教程 (vueJS2.X)


vue入門教程vueJS2.X

寫在前面

看完此教程可以達到:能看懂並能修改簡單的vue項目

看的過程中,請把所有例子都放到html文件中跑一遍。

Vue.js 是什么

Vue.js(讀音 /vjuː/,類似於 view) 是一套構建用戶界面的漸進式框架。與其他重量級框架不同的是,Vue 采用自底向上增量開發的設計。Vue 的核心庫只關注視圖層,它不僅易於上手,還便於與第三方庫或既有項目整合。

什么叫漸進式

沒有多做職責之外的事,它只是個輕量視圖而已,只做了自己該做的事,沒有做不該做的事,僅此而已。

你可以在原有的項目上面,把一兩個組件改用它實現,當jQuery用

也可以整個用它全家桶開發,當Angular用

還可以在頁面上當模板引擎用

特點

  1. 輕量級的框架
  2. 雙向數據綁定
  3. 指令
  4. 組件化

優點

  1. 簡單:官方文檔很清晰,簡單易學,國人開發,生態好,社區、文檔齊全
  2. 快速:異步批處理方式更新DOM (Virtual DOM)
  3. 組合:解耦的、可復用的組件
  4. 緊湊:28.96kb min+gzip 且無依賴
  5. 強大:性能好,表達式、指令、組件化···

缺點

  1. 不支持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 } }}

模板表達式都被放在沙盒中,只能訪問全局變量的一個白名單,如 MathDate 。你不應該在模板表達式中試圖訪問用戶定義的全局變量。

指令

指令(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-onv-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.reversedMessagegetter

console.log(vm.reversedMessage) // -> 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // -> 'eybdooG'

你可以打開瀏覽器的控制台,自行修改例子中的 vmvm.reversedMessage 的值始終取決於 vm.message 的值。

你可以像綁定普通屬性一樣在模板中綁定計算屬性。 Vue 知道 vm.reversedMessage 依賴於 vm.message ,因此當 vm.message 發生改變時,所有依賴於 vm.reversedMessage 的綁定也會更新。而且最妙的是我們已經以聲明的方式創建了這種依賴關系:計算屬性的 getter 是沒有副作用,這使得它易於測試和推理。

Class 與 Style 綁定

數據綁定一個常見需求是操作元素的 class 列表和它的內聯樣式。因為它們都是屬性 ,我們可以用v-bind 處理它們:只需要計算出表達式最終的字符串。不過,字符串拼接麻煩又易錯。因此,在 v-bind 用於 classstyle 時, 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 ,但是只有在 isActivetrue 時添加 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-ifelse 塊:

<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-ifelse-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-elsev-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.jsv-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日


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM