教程
本教程主要介紹了 Vue2.x 版本的使用
第一個(gè)實(shí)例:
<body>
<div id="app">
<p>{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
</script>
</body>
安裝
- 使用 CDN 方法
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://cdn.staticfile.org/vue/2.7.0/vue.min.js"></script>
起步
每個(gè) Vue 應(yīng)用都需要通過實(shí)例化 Vue 來實(shí)現(xiàn)。
語法格式如下:
var vm = new Vue({
// 選項(xiàng)
})
接下來讓我們通過實(shí)例來看下 Vue 構(gòu)造器中需要哪些內(nèi)容:
<div id="vue_det">
<h1>site : {{site}}</h1>
<h1>url : {{url}}</h1>
<h1>{{details()}}</h1>
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#vue_det',
data: {
site: "菜鳥教程",
url: "www.runoob.com",
alexa: "10000"
},
methods: {
details: function() {
return this.site + " - 學(xué)的不僅是技術(shù),更是夢想!";
}
}
})
</script>
在 Vue 構(gòu)造器中有一個(gè)el
參數(shù),它是 DOM 元素中的id
。在上面實(shí)例中 id 為 vue_det
,在 div 元素中:<div id = "vue_det"></div>
。
這意味著我們接下來的改動(dòng)全部在以上指定的 div 內(nèi),div 外部不受影響。
接下來我們看看如何定義數(shù)據(jù)對象。
data 用于定義屬性,實(shí)例中有三個(gè)屬性分別為:site、url、alexa。
methods 用于定義的函數(shù),可以通過 return 來返回函數(shù)值。
{{ }} 用于輸出對象屬性和函數(shù)返回值。
當(dāng)一個(gè) Vue 實(shí)例被創(chuàng)建時(shí),它向 Vue 的響應(yīng)式系統(tǒng)中加入了其 data 對象中能找到的所有的屬性。當(dāng)這些屬性的值發(fā)生改變時(shí),html 視圖將也會(huì)產(chǎn)生相應(yīng)的變化。
<div id="vue_det">
<h1>site : {{site}}</h1>
<h1>url : {{url}}</h1>
<h1>Alexa : {{alexa}}</h1>
</div>
<script type="text/javascript">
// 我們的數(shù)據(jù)對象
var data = { site: "菜鳥教程", url: "www.runoob.com", alexa: 10000}
var vm = new Vue({
el: '#vue_det',
data: data
})
// 它們引用相同的對象!
document.write(vm.site === data.site) // true
document.write("<br>")
// 設(shè)置屬性也會(huì)影響到原始數(shù)據(jù)
vm.site = "Runoob"
document.write(data.site + "<br>") // Runoob
// ……反之亦然
data.alexa = 1234
document.write(vm.alexa) // 1234
</script>
模板語法
插值
- 文本
數(shù)據(jù)綁定最常見的形式就是使用{{...}}
(雙大括號(hào))的文本插值:
<div id="app">
<p>{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
</script>
- HTML
使用v-html
指令用于輸出html
代碼:
<div id="app">
<div v-html="message"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
message: '<h1>菜鳥教程</h1>'
}
})
</script>
- 屬性
HTML
屬性中的值應(yīng)使用v-bind
指令。
以下實(shí)例判斷use
的值,如果為true
使用class1
類的樣式,否則不使用該類:
<style>
.class1{
background: #444;
color: #eee;
}
</style>
<body>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<div id="app">
<label for="r1">修改顏色</label><input type="checkbox" v-model="use" id="r1">
<br><br>
<div v-bind:class="{'class1': use}">
v-bind:class 指令
</div>
</div>
<script>
new Vue({
el: '#app',
data:{
use: false
}
});
</script>
</body>
- 表達(dá)式
<div id="app">
{{5+5}}<br>
{{ ok ? 'YES' : 'NO' }}<br>
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id">菜鳥教程</div>
</div>
<script>
new Vue({
el: '#app',
data: {
ok: true,
message: 'RUNOOB',
id : 1
}
})
</script>
指令
指令是帶有 v- 前綴的特殊屬性。
指令用于在表達(dá)式的值改變時(shí),將某些行為應(yīng)用到 DOM 上。
如下例子:
<div id="app">
<p v-if="seen">現(xiàn)在你看到我了</p>
<template v-if="ok">
<h1>菜鳥教程</h1>
<p>學(xué)的不僅是技術(shù),更是夢想!</p>
<p>哈哈哈,打字辛苦啊?。?!</p>
</template>
</div>
<script>
new Vue({
el: '#app',
data: {
seen: true,
ok: true
}
})
</script>
這里, v-if 指令將根據(jù)表達(dá)式 seen 的值(true 或 false )來決定是否插入 p 元素。
- 參數(shù)
參數(shù)在指令后以冒號(hào)指明。例如,v-bind
指令被用來響應(yīng)地更新HTML
屬性:
<div id="app">
<pre><a v-bind:href="url">菜鳥教程</a></pre>
</div>
<script>
new Vue({
el: '#app',
data: {
url: 'http://www.runoob.com'
}
})
</script>
在這里href
是參數(shù),告知v-bind
指令將該元素的href
屬性與表達(dá)式url
的值綁定。
另一個(gè)例子是v-on
指令,它用于監(jiān)聽 DOM 事件:<a v-on:click="doSomething">
在這里參數(shù)是監(jiān)聽的事件名。
- 修飾符
修飾符是以半角句號(hào).
指明的特殊后綴,用于指出一個(gè)指令應(yīng)該以特殊方式綁定。例如,.prevent
修飾符告訴v-on
指令對于觸發(fā)的事件調(diào)用event.preventDefault()
:<form v-on:submit.prevent="onSubmit"></form>
用戶輸入
- 在
input
輸入框中我們可以使用v-model
指令來實(shí)現(xiàn)雙向數(shù)據(jù)綁定:
<div id="app">
<p>{{ message }}</p>
<input v-model="message">
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Runoob!'
}
})
</script>
v-model
指令用來在input
、select
、textarea
、checkbox
、radio
等表單控件元素上創(chuàng)建雙向數(shù)據(jù)綁定,根據(jù)表單上的值,自動(dòng)更新綁定的元素的值。
按鈕的事件我們可以使用v-on
監(jiān)聽事件,并對用戶的輸入進(jìn)行響應(yīng)。
以下實(shí)例在用戶點(diǎn)擊按鈕后對字符串進(jìn)行反轉(zhuǎn)操作:
<div id="app">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">反轉(zhuǎn)字符串</button>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Runoob!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
</script>
過濾器
Vue.js 允許你自定義過濾器,被用作一些常見的文本格式化。
由"管道符"指示, 格式如下:
<!-- 在兩個(gè)大括號(hào)中 -->
{{ message | capitalize }}
<!-- 在 v-bind 指令中 -->
<div v-bind:id="rawId | formatId"></div>
以下實(shí)例對輸入的字符串第一個(gè)字母轉(zhuǎn)為大寫:
<div id="app">
{{ message | capitalize }}
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'runoob'
},
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
})
</script>
縮寫
Vue.js 為兩個(gè)最為常用的指令提供了特別的縮寫:
<!-- 完整語法 -->
<a v-bind:href="url"></a>
<!-- 縮寫 -->
<a :href="url"></a>
<!-- 完整語法 -->
<a v-on:click="doSomething"></a>
<!-- 縮寫 -->
<a @click="doSomething"></a>
條件語句
<div id="app">
<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>
</div>
<script>
new Vue({
el: '#app',
data: {
type: 'C'
}
})
</script>
循環(huán)語句
v-for 指令需要以 site in sites 形式的特殊語法, sites 是源數(shù)據(jù)數(shù)組并且 site 是數(shù)組元素迭代的別名。
v-for 可以綁定數(shù)據(jù)到數(shù)組來渲染一個(gè)列表:
<div id="app">
<ol>
<li v-for="site in sites">
{{ site.name }}
</li>
</ol>
</div>
<script>
new Vue({
el: '#app',
data: {
sites: [
{ name: 'Runoob' },
{ name: 'Google' },
{ name: 'Taobao' }
]
}
})
</script>
v-for 迭代對象
v-for 可以通過一個(gè)對象的屬性來迭代數(shù)據(jù):
<div id="app">
<ul>
<li v-for="(value, key, index) in object">
{{ index }}. {{ key }} : {{ value }}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
object: {
name: '菜鳥教程',
url: 'http://www.runoob.com',
slogan: '學(xué)的不僅是技術(shù),更是夢想!'
}
}
})
</script>
計(jì)算屬性
計(jì)算屬性關(guān)鍵詞: computed。
計(jì)算屬性在處理一些復(fù)雜邏輯時(shí)是很有用的。
可以看下以下反轉(zhuǎn)字符串的例子:
<div id="app">
<p>原始字符串: {{ message }}</p>
<p>計(jì)算后反轉(zhuǎn)字符串: {{ reversedMessage }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Runoob!'
},
computed: {
// 計(jì)算屬性的 getter
reversedMessage: function () {
// `this` 指向 vm 實(shí)例
return this.message.split('').reverse().join('')
}
}
})
</script>
實(shí)例中聲明了一個(gè)計(jì)算屬性reversedMessage
。
提供的函數(shù)將用作屬性vm.reversedMessage
的getter
。
vm.reversedMessage
依賴于vm.message
,在vm.message
發(fā)生改變時(shí),vm.reversedMessage
也會(huì)更新。
computed vs methods
我們可以使用methods
來替代computed
,效果上兩個(gè)都是一樣的,但是computed
是基于它的依賴緩存,只有相關(guān)依賴發(fā)生改變時(shí)才會(huì)重新取值。而使用methods
,在重新渲染的時(shí)候,函數(shù)總會(huì)重新調(diào)用執(zhí)行。
<div id="app">
<p>原始字符串: {{ message }}</p>
<p>計(jì)算后反轉(zhuǎn)字符串: {{ reversedMessage }}</p>
<p>使用方法后反轉(zhuǎn)字符串: {{ reversedMessage2() }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Runoob!'
},
computed: {
// 計(jì)算屬性的 getter
reversedMessage: function () {
// `this` 指向 vm 實(shí)例
return this.message.split('').reverse().join('')
}
},
methods: {
reversedMessage2: function () {
return this.message.split('').reverse().join('')
}
}
})
</script>
可以說使用computed
性能會(huì)更好,但是如果你不希望緩存,你可以使用methods
屬性。
監(jiān)聽屬性
本章節(jié),我們將為大家介紹Vue.js
監(jiān)聽屬性watch
,我們可以通過watch
來響應(yīng)數(shù)據(jù)的變化。
以下實(shí)例通過使用watch
實(shí)現(xiàn)計(jì)數(shù)器:
<div id = "app">
<p style = "font-size:25px;">計(jì)數(shù)器: {{ counter }}</p>
<button @click = "counter++" style = "font-size:25px;">點(diǎn)我</button>
</div>
<script type = "text/javascript">
var vm = new Vue({
el: '#app',
data: {
counter: 1
}
});
vm.$watch('counter', function(nval, oval) {
alert('計(jì)數(shù)器值的變化 :' + oval + ' 變?yōu)?' + nval + '!');
});
</script>
以下實(shí)例進(jìn)行千米與米之間的換算:
<div id = "computed_props">
千米 : <input type = "text" v-model = "kilometers">
米 : <input type = "text" v-model = "meters">
</div>
<p id="info"></p>
<script type = "text/javascript">
var vm = new Vue({
el: '#computed_props',
data: {
kilometers : 0,
meters:0
},
methods: {
},
computed :{
},
watch : {
kilometers:function(val) {
this.kilometers = val;
this.meters = this.kilometers * 1000
},
meters : function (val) {
this.kilometers = val/ 1000;
this.meters = val;
}
}
});
// $watch 是一個(gè)實(shí)例方法
vm.$watch('kilometers', function (newValue, oldValue) {
// 這個(gè)回調(diào)將在 vm.kilometers 改變后調(diào)用
document.getElementById ("info").innerHTML = "修改前值為: " + oldValue + ",修改后值為: " + newValue;
})
</script>
以上代碼中我們創(chuàng)建了兩個(gè)輸入框,data
屬性中,kilometers
和meters
初始值都為0
。watch
對象創(chuàng)建了data
對象的兩個(gè)監(jiān)控方法:kilometers
和meters
。
當(dāng)我們在輸入框輸入數(shù)據(jù)時(shí),watch
會(huì)實(shí)時(shí)監(jiān)聽數(shù)據(jù)變化并改變自身的值。
把$watch
實(shí)例方法刪掉后,千米和米的數(shù)據(jù)依然會(huì)改變,只是少了最下面的那行字
樣式綁定
class
與style
是HTML
元素的屬性,用于設(shè)置元素的樣式,我們可以用v-bind
來設(shè)置樣式屬性。
class
屬性綁定
我們可以為v-bind:class
設(shè)置一個(gè)對象,從而動(dòng)態(tài)的切換class
:
實(shí)例中將isActive
設(shè)置為true
顯示了一個(gè)綠色的div
塊,如果設(shè)置為false
則不顯示:
實(shí)例1:
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<div id="app">
<div v-bind:class="{ 'active': isActive }"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
isActive: true
}
})
</script>
以上實(shí)例div class
為:
<div class="active"></div>
我們也可以在對象中傳入更多屬性用來動(dòng)態(tài)切換多個(gè)class
。
實(shí)例2:
text-danger
類背景顏色覆蓋了active
類的背景色:
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
.text-danger {
background: red;
}
</style>
</head>
<body>
<div id="app">
<div class="static"
v-bind:class="{ 'active': isActive, 'text-danger': hasError }">
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
isActive: true,
hasError: true
}
})
</script>
以上實(shí)例div class
為:
<div class="static active text-danger"></div>
我們也可以直接綁定數(shù)據(jù)里的一個(gè)對象:
實(shí)例3:
text-danger 類背景顏色覆蓋了 active 類的背景色:
<div id="app">
<div v-bind:class="classObject"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
classObject: {
active: true,
'text-danger': true
}
}
})
</script>
實(shí)例 3 與 實(shí)例 2 的渲染結(jié)果是一樣的。
此外,我們也可以在這里綁定返回對象的計(jì)算屬性。這是一個(gè)常用且強(qiáng)大的模式:
實(shí)例4:
new Vue({
el: '#app',
data: {
isActive: true,
error: {
value: true,
type: 'fatal'
}
},
computed: {
classObject: function () {
return {
base: true,
active: this.isActive && !this.error.value,
'text-danger': this.error.value && this.error.type === 'fatal',
}
}
}
})
我們可以把一個(gè)數(shù)組傳給 v-bind:class ,實(shí)例如下:
實(shí)例 5<div v-bind:class="[activeClass, errorClass]"></div>
以上實(shí)例 div class 為:
<div class="active text-danger"></div>
Vue.js style(內(nèi)聯(lián)樣式)
我們可以在v-bind:style
直接設(shè)置樣式:
<div id="app">
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鳥教程</div>
</div>
<script>
new Vue({
el: '#app',
data: {
activeColor: 'green',
fontSize: 30
}
})
</script>
以上實(shí)例 div style 為:
<div style="color: green; font-size: 30px;">菜鳥教程</div>
也可以直接綁定到一個(gè)樣式對象,讓模板更清晰:
<div id="app">
<div v-bind:style="styleObject">菜鳥教程</div>
</div>
<script>
new Vue({
el: '#app',
data: {
styleObject: {
color: 'green',
fontSize: '30px'
}
}
})
</script>
v-bind:style
可以使用數(shù)組將多個(gè)樣式對象應(yīng)用到一個(gè)元素上:
<body>
<div id="app">
<div v-bind:style="[baseStyles, overridingStyles]">菜鳥教程</div>
</div>
<script>
new Vue({
el: '#app',
data: {
baseStyles: {
color: 'green',
fontSize: '30px'
},
overridingStyles: {
'font-weight': 'bold'
}
}
})
</script>
</body>
事件處理器
事件監(jiān)聽可以使用v-on
指令:
<div id="app">
<button v-on:click="counter += 1">增加 1</button>
<p>這個(gè)按鈕被點(diǎn)擊了 {{ counter }} 次。</p>
</div>
<script>
new Vue({
el: '#app',
data: {
counter: 0
}
})
</script>
通常情況下,我們需要使用一個(gè)方法來調(diào)用JavaScript
方法。
v-on
可以接收一個(gè)定義的方法來調(diào)用。
<div id="app">
<!-- `greet` 是在下面定義的方法名 -->
<button v-on:click="greet">Greet</button>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
name: 'Vue.js'
},
// 在 `methods` 對象中定義方法
methods: {
greet: function (event) {
// `this` 在方法里指當(dāng)前 Vue 實(shí)例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
}
}
})
// 也可以用 JavaScript 直接調(diào)用方法
app.greet() // -> 'Hello Vue.js!'
</script>
用 JavaScript 直接調(diào)用方法
用 v-on 調(diào)用方法,點(diǎn)擊顯示if(event){alert (event.target.tagName)}
除了直接綁定到一個(gè)方法,也可以用內(nèi)聯(lián)JavaScript
語句:
<div id="app">
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
</div>
<script>
new Vue({
el: '#app',
methods: {
say: function (message) {
alert(message)
}
}
})
</script>
事件修飾符
Vue.js 為 v-on 提供了事件修飾符來處理 DOM 事件細(xì)節(jié),如:event.preventDefault() 或 event.stopPropagation()。
Vue.js 通過由點(diǎn).
表示的指令后綴來調(diào)用修飾符。
按鍵修飾符
Vue 允許為 v-on 在監(jiān)聽鍵盤事件時(shí)添加按鍵修飾符:
<!-- 只有在 keyCode 是 13 時(shí)調(diào)用 vm.submit() -->
<input v-on:keyup.13="submit">
表單
你可以用 v-model 指令在表單控件元素上創(chuàng)建雙向數(shù)據(jù)綁定。
v-model 會(huì)根據(jù)控件類型自動(dòng)選取正確的方法來更新元素。
實(shí)例中演示了 input 和 textarea 元素中使用 v-model 實(shí)現(xiàn)雙向數(shù)據(jù)綁定:
<div id="app">
<p>input 元素:</p>
<input v-model="message" placeholder="編輯我……">
<p>消息是: {{ message }}</p>
<p>textarea 元素:</p>
<p style="white-space: pre">{{ message2 }}</p>
<textarea v-model="message2" placeholder="多行文本輸入……"></textarea>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Runoob',
message2: '菜鳥教程\r\nhttp://www.runoob.com'
}
})
</script>
復(fù)選框
復(fù)選框如果是一個(gè)為邏輯值,如果是多個(gè)則綁定到同一個(gè)數(shù)組:
以下實(shí)例中演示了復(fù)選框的雙向數(shù)據(jù)綁定:
<div id="app">
<p>單個(gè)復(fù)選框:</p>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
<p>多個(gè)復(fù)選框:</p>
<input type="checkbox" id="runoob" value="Runoob" v-model="checkedNames">
<label for="runoob">Runoob</label>
<input type="checkbox" id="google" value="Google" v-model="checkedNames">
<label for="google">Google</label>
<input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">
<label for="taobao">taobao</label>
<br>
<span>選擇的值為: {{ checkedNames }}</span>
</div>
<script>
new Vue({
el: '#app',
data: {
checked : false,
checkedNames: []
}
})
</script>
單選按鈕
以下實(shí)例中演示了單選按鈕的雙向數(shù)據(jù)綁定:
<div id="app">
<input type="radio" id="runoob" value="Runoob" v-model="picked">
<label for="runoob">Runoob</label>
<br>
<input type="radio" id="google" value="Google" v-model="picked">
<label for="google">Google</label>
<br>
<span>選中值為: {{ picked }}</span>
</div>
<script>
new Vue({
el: '#app',
data: {
picked : 'Runoob'
}
})
</script>
select 列表
以下實(shí)例中演示了下拉列表的雙向數(shù)據(jù)綁定:
<div id="app">
<select v-model="selected" name="fruit">
<option value="">選擇一個(gè)網(wǎng)站</option>
<option value="www.runoob.com">Runoob</option>
<option value="www.google.com">Google</option>
</select>
<div id="output">
選擇的網(wǎng)站是: {{selected}}
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
selected: ''
}
})
</script>
組件
組件(Component)是 Vue.js 最強(qiáng)大的功能之一。
組件可以擴(kuò)展 HTML 元素,封裝可重用的代碼。
組件系統(tǒng)讓我們可以用獨(dú)立可復(fù)用的小組件來構(gòu)建大型應(yīng)用,幾乎任意類型的應(yīng)用的界面都可以抽象為一個(gè)組件樹:
注冊一個(gè)全局組件語法格式如下:
Vue.component(tagName, options)
tagName 為組件名,options 為配置選項(xiàng)。注冊后,我們可以使用以下方式來調(diào)用組件:
<tagName></tagName>
全局組件
所有實(shí)例都能用全局組件。
注冊一個(gè)簡單的全局組件 runoob,并使用它:
<div id="app">
<runoob></runoob>
</div>
<script>
// 注冊
Vue.component('runoob', {
template: '<h1>自定義組件!</h1>'
})
// 創(chuàng)建根實(shí)例
new Vue({
el: '#app'
})
</script>
局部組件
我們也可以在實(shí)例選項(xiàng)中注冊局部組件,這樣組件只能在這個(gè)實(shí)例中使用:
注冊一個(gè)簡單的局部組件 runoob,并使用它:
<div id="app">
<runoob></runoob>
</div>
<script>
var Child = {
template: '<h1>自定義組件!</h1>'
}
// 創(chuàng)建根實(shí)例
new Vue({
el: '#app',
components: {
// <runoob> 將只在父模板可用
'runoob': Child
}
})
</script>
Prop
prop 是子組件用來接受父組件傳遞過來的數(shù)據(jù)的一個(gè)自定義屬性。
父組件的數(shù)據(jù)需要通過 props 把數(shù)據(jù)傳給子組件,子組件需要顯式地用 props 選項(xiàng)聲明 “prop”:
<div id="app">
<child message="hello!"></child>
</div>
<script>
// 注冊
Vue.component('child', {
// 聲明 props
props: ['message'],
// 同樣也可以在 vm 實(shí)例中像 "this.message" 這樣使用
template: '<span>{{ message }}</span>'
})
// 創(chuàng)建根實(shí)例
new Vue({
el: '#app'
})
</script>
動(dòng)態(tài) Prop
類似于用 v-bind 綁定 HTML 特性到一個(gè)表達(dá)式,也可以用 v-bind 動(dòng)態(tài)綁定 props 的值到父組件的數(shù)據(jù)中。每當(dāng)父組件的數(shù)據(jù)變化時(shí),該變化也會(huì)傳導(dǎo)給子組件:
<div id="app">
<div>
<input v-model="parentMsg">
<br>
<child v-bind:message="parentMsg"></child>
</div>
</div>
<script>
// 注冊
Vue.component('child', {
// 聲明 props
props: ['message'],
// 同樣也可以在 vm 實(shí)例中像 "this.message" 這樣使用
template: '<span>{{ message }}</span>'
})
// 創(chuàng)建根實(shí)例
new Vue({
el: '#app',
data: {
parentMsg: '父組件內(nèi)容'
}
})
</script>
以下實(shí)例中使用 v-bind 指令將 todo 傳到每一個(gè)重復(fù)的組件中:
<div id="app">
<ol>
<todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
</ol>
</div>
<script>
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
new Vue({
el: '#app',
data: {
sites: [
{ text: 'Runoob' },
{ text: 'Google' },
{ text: 'Taobao' }
]
}
})
</script>
注意: prop 是單向綁定的:當(dāng)父組件的屬性變化時(shí),將傳導(dǎo)給子組件,但是不會(huì)反過來。
Prop 驗(yàn)證
組件可以為 props 指定驗(yàn)證要求。
為了定制 prop 的驗(yàn)證方式,你可以為 props 中的值提供一個(gè)帶有驗(yàn)證需求的對象,而不是一個(gè)字符串?dāng)?shù)組。
組件 - 自定義事件
父組件是使用 props 傳遞數(shù)據(jù)給子組件,但如果子組件要把數(shù)據(jù)傳遞回去,就需要使用自定義事件!
我們可以使用 v-on 綁定自定義事件, 每個(gè) Vue 實(shí)例都實(shí)現(xiàn)了事件接口(Events interface),即:
- 使用 $on(eventName) 監(jiān)聽事件
- 使用 $emit(eventName) 觸發(fā)事件
另外,父組件可以在使用子組件的地方直接用 v-on 來監(jiān)聽子組件觸發(fā)的事件。
以下實(shí)例中子組件已經(jīng)和它外部完全解耦了。它所做的只是觸發(fā)一個(gè)父組件關(guān)心的內(nèi)部事件。
<div id="app">
<div id="counter-event-example">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
</div>
<script>
Vue.component('button-counter', {
template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
data: function () {
return {
counter: 0
}
},
methods: {
incrementHandler: function () {
this.counter += 1
this.$emit('increment')
}
},
})
new Vue({
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})
</script>
data 必須是一個(gè)函數(shù)
上面例子中,可以看到 button-counter 組件中的 data 不是一個(gè)對象,而是一個(gè)函數(shù):
data: function () {
return {
count: 0
}
}
這樣的好處就是每個(gè)實(shí)例可以維護(hù)一份被返回對象的獨(dú)立的拷貝,如果 data 是一個(gè)對象則會(huì)影響到其他實(shí)例:
<div id="components-demo3" class="demo">
<button-counter2></button-counter2>
<button-counter2></button-counter2>
<button-counter2></button-counter2>
</div>
<script>
var buttonCounter2Data = {
count: 0
}
Vue.component('button-counter2', {
data: function () {
// data 選項(xiàng)是一個(gè)對象,會(huì)影響到其他實(shí)例
return buttonCounter2Data
},
template: '<button v-on:click="count++">點(diǎn)擊了 {{ count }} 次。</button>'
})
new Vue({ el: '#components-demo3' })
</script>
自定義組件的 v-model
組件上的 v-model 默認(rèn)會(huì)利用名為 value 的 prop 和名為 input 的事件。
<input v-model="parentData">
等價(jià)于:
<input
:value="parentData"
@input="parentData = $event.target.value"
>
以下實(shí)例自定義組件 runoob-input,父組件的 num 的初始值是 100,更改子組件的值能實(shí)時(shí)更新父組件的 num:
<div id="app">
<runoob-input v-model="num"></runoob-input>
<p>輸入的數(shù)字為:{{num}}</p>
</div>
<script>
Vue.component('runoob-input', {
template: `
<p> <!-- 包含了名為 input 的事件 -->
<input
ref="input"
:value="value"
@input="$emit('input', $event.target.value)"
>
</p>
`,
props: ['value'], // 名為 value 的 prop
})
new Vue({
el: '#app',
data: {
num: 100,
}
})
</script>
由于 v-model 默認(rèn)傳的是 value,不是 checked,所以對于復(fù)選框或者單選框的組件時(shí),我們需要使用 model 選項(xiàng),model 選項(xiàng)可以指定當(dāng)前的事件類型和傳入的 props。
<div id="app">
<base-checkbox v-model="lovingVue"></base-checkbox>
<div v-show="lovingVue">
如果選擇框打勾我就會(huì)顯示。
</div>
</div>
<script>
// 注冊
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change' // onchange 事件
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
})
// 創(chuàng)建根實(shí)例
new Vue({
el: '#app',
data: {
lovingVue: true
}
})
</script>
自定義指令
除了默認(rèn)設(shè)置的核心指令( v-model 和 v-show ), Vue 也允許注冊自定義指令。
下面我們注冊一個(gè)全局指令 v-focus, 該指令的功能是在頁面加載時(shí),元素獲得焦點(diǎn):
<div id="app">
<p>頁面載入時(shí),input 元素自動(dòng)獲取焦點(diǎn):</p>
<input v-focus>
</div>
<script>
// 注冊一個(gè)全局自定義指令 v-focus
Vue.directive('focus', {
// 當(dāng)綁定元素插入到 DOM 中。
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
// 創(chuàng)建根實(shí)例
new Vue({
el: '#app'
})
</script>
我們也可以在實(shí)例使用 directives 選項(xiàng)來注冊局部指令,這樣指令只能在這個(gè)實(shí)例中使用:
<div id="app">
<p>頁面載入時(shí),input 元素自動(dòng)獲取焦點(diǎn):</p>
<input v-focus>
</div>
<script>
// 創(chuàng)建根實(shí)例
new Vue({
el: '#app',
directives: {
// 注冊一個(gè)局部的自定義指令 v-focus
focus: {
// 指令的定義
inserted: function (el) {
// 聚焦元素
el.focus()
}
}
}
})
</script>
鉤子
鉤子函數(shù)
指令定義函數(shù)提供了幾個(gè)鉤子函數(shù)(可選):
-
bind: 只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用,用這個(gè)鉤子函數(shù)可以定義一個(gè)在綁定時(shí)執(zhí)行一次的初始化動(dòng)作。
-
inserted: 被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用(父節(jié)點(diǎn)存在即可調(diào)用,不必存在于 document 中)。
-
update: 被綁定元素所在的模板更新時(shí)調(diào)用,而不論綁定值是否變化。通過比較更新前后的綁定值,可以忽略不必要的模板更新(詳細(xì)的鉤子函數(shù)參數(shù)見下)。
-
componentUpdated: 被綁定元素所在模板完成一次更新周期時(shí)調(diào)用。
-
unbind: 只調(diào)用一次, 指令與元素解綁時(shí)調(diào)用。
鉤子函數(shù)的參數(shù)
- el: 指令所綁定的元素,可以用來直接操作 DOM 。
- binding: 一個(gè)對象,包含以下屬性:
- name: 指令名,不包括 v- 前綴。
- value: 指令的綁定值, 例如: v-my-directive=“1 + 1”, value 的值是 2。
- oldValue: 指令綁定的前一個(gè)值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。
- expression: 綁定值的表達(dá)式或變量名。 例如 v-my-directive=“1 + 1” , expression 的值是 “1 + 1”。
- arg: 傳給指令的參數(shù)。例如 v-my-directive:foo, arg 的值是 “foo”。
- modifiers: 一個(gè)包含修飾符的對象。 例如: v-my-directive.foo.bar, 修飾符對象 modifiers 的值是 { foo: true, bar: true }。
- vnode: Vue 編譯生成的虛擬節(jié)點(diǎn)。
- oldVnode: 上一個(gè)虛擬節(jié)點(diǎn),僅在 update 和 componentUpdated 鉤子中可用。
以下實(shí)例演示了這些參數(shù)的使用:
<div id="app" v-runoob:hello.a.b="message">
</div>
<script>
Vue.directive('runoob', {
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#app',
data: {
message: '菜鳥教程!'
}
})
</script>
有時(shí)候我們不需要其他鉤子函數(shù),我們可以簡寫函數(shù),如下格式:
Vue.directive('runoob', function (el, binding) {
// 設(shè)置指令的背景顏色
el.style.backgroundColor = binding.value.color
})
指令函數(shù)可接受所有合法的 JavaScript 表達(dá)式,以下實(shí)例傳入了 JavaScript 對象:
<div id="app">
<div v-runoob="{ color: 'green', text: '菜鳥教程!' }"></div>
</div>
<script>
Vue.directive('runoob', function (el, binding) {
// 簡寫方式設(shè)置文本及背景顏色
el.innerHTML = binding.value.text
el.style.backgroundColor = binding.value.color
})
new Vue({
el: '#app'
})
</script>
路由( vue-router )
Vue.js 路由允許我們通過不同的 URL 訪問不同的內(nèi)容。
通過 Vue.js 可以實(shí)現(xiàn)多視圖的單頁Web應(yīng)用(single page web application,SPA)。
安裝
1、直接下載 / CDNhttps://unpkg.com/vue-router/dist/vue-router.js
2、NPM
推薦使用淘寶鏡像:cnpm install vue-router
簡單實(shí)例
Vue.js + vue-router 可以很簡單的實(shí)現(xiàn)單頁應(yīng)用。
<router-link>
是一個(gè)組件,該組件用于設(shè)置一個(gè)導(dǎo)航鏈接,切換不同 HTML 內(nèi)容。 to 屬性為目標(biāo)地址, 即要顯示的內(nèi)容。
以下實(shí)例中我們將 vue-router 加進(jìn)來,然后配置組件和路由映射,再告訴 vue-router 在哪里渲染它們。代碼如下所示:
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- 使用 router-link 組件來導(dǎo)航. -->
<!-- 通過傳入 `to` 屬性指定鏈接. -->
<!-- <router-link> 默認(rèn)會(huì)被渲染成一個(gè) `<a>` 標(biāo)簽 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的組件將渲染在這里 -->
<router-view></router-view>
</div>
<script>
// 0. 如果使用模塊化機(jī)制編程,導(dǎo)入Vue和VueRouter,要調(diào)用 Vue.use(VueRouter)
// 1. 定義(路由)組件。
// 可以從其他文件 import 進(jìn)來
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 2. 定義路由
// 每個(gè)路由應(yīng)該映射一個(gè)組件。 其中"component" 可以是
// 通過 Vue.extend() 創(chuàng)建的組件構(gòu)造器,
// 或者,只是一個(gè)組件配置對象。
// 我們晚點(diǎn)再討論嵌套路由。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 3. 創(chuàng)建 router 實(shí)例,然后傳 `routes` 配置
// 你還可以傳別的配置參數(shù), 不過先這么簡單著吧。
const router = new VueRouter({
routes // (縮寫)相當(dāng)于 routes: routes
})
// 4. 創(chuàng)建和掛載根實(shí)例。
// 記得要通過 router 配置參數(shù)注入路由,
// 從而讓整個(gè)應(yīng)用都有路由功能
const app = new Vue({
router
}).$mount('#app')
// 現(xiàn)在,應(yīng)用已經(jīng)啟動(dòng)了!
</script>
<router-link>
相關(guān)屬性
to
表示目標(biāo)路由的鏈接。 當(dāng)被點(diǎn)擊后,內(nèi)部會(huì)立刻把 to 的值傳到 router.push(),所以這個(gè)值可以是一個(gè)字符串或者是描述目標(biāo)位置的對象。
過渡 & 動(dòng)畫
過渡
Vue 在插入、更新或者移除 DOM 時(shí),提供多種不同方式的應(yīng)用過渡效果。
Vue 提供了內(nèi)置的過渡封裝組件,該組件用于包裹要實(shí)現(xiàn)過渡效果的組件。
語法格式
<transition name = "nameoftransition">
<div></div>
</transition>
我們可以通過以下實(shí)例來理解 Vue 的過渡是如何實(shí)現(xiàn)的:
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<style>
/* 可以設(shè)置不同的進(jìn)入和離開動(dòng)畫 */
/* 設(shè)置持續(xù)時(shí)間和動(dòng)畫函數(shù) */
.fade-enter-active, .fade-leave-active {
transition: opacity 2s
}
.fade-enter, .fade-leave-to /* .fade-leave-active, 2.1.8 版本以下 */ {
opacity: 0
}
</style>
</head>
<body>
<div id = "databinding">
<button v-on:click = "show = !show">點(diǎn)我</button>
<transition name = "fade">
<p v-show = "show" v-bind:style = "styleobj">動(dòng)畫實(shí)例</p>
</transition>
</div>
<script type = "text/javascript">
var vm = new Vue({
el: '#databinding',
data: {
show:true,
styleobj :{
fontSize:'30px',
color:'red'
}
},
methods : {
}
});
</script>
</body>
Ajax(axios)
Vue.js 2.0 版本推薦使用 axios 來完成 ajax 請求。
Axios 是一個(gè)基于 Promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。
安裝方法:
使用 cdn:<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
使用 npm:npm install axios
GET 方法
我們可以簡單的讀取 JSON 數(shù)據(jù):
<div id="app">
{{ info }}
</div>
<script type = "text/javascript">
new Vue({
el: '#app',
data () {
return {
info: null
}
},
mounted () {
axios
.get('https://www.runoob.com/try/ajax/json_demo.json')
.then(response => (this.info = response))
.catch(function (error) { // 請求失敗處理
console.log(error);
});
}
})
</script>
使用 response.data 讀取 JSON 數(shù)據(jù):
<div id="app">
<h1>網(wǎng)站列表</h1>
<div
v-for="site in info"
>
{{ site.name }}
</div>
</div>
<script type = "text/javascript">
new Vue({
el: '#app',
data () {
return {
info: null
}
},
mounted () {
axios
.get('https://www.runoob.com/try/ajax/json_demo.json')
.then(response => (this.info = response.data.sites))
.catch(function (error) { // 請求失敗處理
console.log(error);
});
}
})
</script>
GET 方法傳遞參數(shù)格式如下:
// 直接在 URL 上添加參數(shù) ID=12345
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 也可以通過 params 設(shè)置參數(shù):
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
POST 方法
<div id="app">
{{ info }}
</div>
<script type = "text/javascript">
new Vue({
el: '#app',
data () {
return {
info: null
}
},
mounted () {
axios
.post('/try/ajax/demo_axios_post.php')
.then(response => (this.info = response))
.catch(function (error) { // 請求失敗處理
console.log(error);
});
}
})
</script>
POST 方法傳遞參數(shù)格式如下:
axios.post('/user', {
firstName: 'Fred', // 參數(shù) firstName
lastName: 'Flintstone' // 參數(shù) lastName
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
執(zhí)行多個(gè)并發(fā)請求
function getUserAccount() {
return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
// 兩個(gè)請求現(xiàn)在都執(zhí)行完成
}));
axios API
可以通過向 axios 傳遞相關(guān)配置來創(chuàng)建請求。
axios(config)
// 發(fā)送 POST 請求
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});
// GET 請求遠(yuǎn)程圖片
axios({
method:'get',
url:'https://static.runoob.com/images/runoob-logo.png',
responseType:'stream'
})
.then(function(response) {
response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
});
axios(url[, config])
// 發(fā)送 GET 請求(默認(rèn)的方法)
axios('/user/12345');
響應(yīng)接口
Vue 可以添加數(shù)據(jù)動(dòng)態(tài)響應(yīng)接口。
例如以下實(shí)例,我們通過使用$watch
屬性來實(shí)現(xiàn)數(shù)據(jù)的監(jiān)聽,$watch
必須添加在 Vue 實(shí)例之外才能實(shí)現(xiàn)正確的響應(yīng)。
實(shí)例中通過點(diǎn)擊按鈕計(jì)數(shù)器會(huì)加 1。setTimeout 設(shè)置 10 秒后計(jì)算器的值加上 20 。
<div id = "app">
<p style = "font-size:25px;">計(jì)數(shù)器: {{ counter }}</p>
<button @click = "counter++" style = "font-size:25px;">點(diǎn)我</button>
</div>
<script type = "text/javascript">
var vm = new Vue({
el: '#app',
data: {
counter: 1
}
});
vm.$watch('counter', function(nval, oval) {
alert('計(jì)數(shù)器值的變化 :' + oval + ' 變?yōu)?' + nval + '!');
});
setTimeout(
function(){
vm.counter += 20;
},10000
);
</script>
10秒后,計(jì)數(shù)器的值+20
點(diǎn)擊一下,計(jì)數(shù)器的值+1
如果將
vm.$watch('counter', function(nval, oval) {
alert('計(jì)數(shù)器值的變化 :' + oval + ' 變?yōu)?' + nval + '!');
});
去掉,數(shù)值依然會(huì)變化,但每次變化時(shí),不會(huì)彈出alert。
實(shí)例
本章節(jié)為大家介紹幾個(gè) Vue.js 實(shí)例,通過實(shí)例練習(xí)來鞏固學(xué)到的知識(shí)點(diǎn)。文章來源:http://www.zghlxwxcb.cn/news/detail-434083.html
導(dǎo)航菜單
<div id="main">
<!-- 激活的菜單樣式為 active 類 -->
<!-- 為了阻止鏈接在點(diǎn)擊時(shí)跳轉(zhuǎn),我們使用了 "prevent" 修飾符 (preventDefault 的簡稱)。 -->
<nav v-bind:class="active" v-on:click.prevent>
<!-- 當(dāng)菜單上的鏈接被點(diǎn)擊時(shí),我們調(diào)用了 makeActive 方法, 該方法在 Vue 實(shí)例中創(chuàng)建。 -->
<a href="#" class="home" v-on:click="makeActive('home')">Home</a>
<a href="#" class="projects" v-on:click="makeActive('projects')">Projects</a>
<a href="#" class="services" v-on:click="makeActive('services')">Services</a>
<a href="#" class="contact" v-on:click="makeActive('contact')">Contact</a>
</nav>
<!-- 以下 "active" 變量會(huì)根據(jù)當(dāng)前選中的值來自動(dòng)變換 -->
<p>您選擇了 <b>{{active}} 菜單</b></p>
</div>
<script>
// 創(chuàng)建一個(gè)新的 Vue 實(shí)例
var demo = new Vue({
// DOM 元素,掛載視圖模型
el: '#main',
// 定義屬性,并設(shè)置初始值
data: {
active: 'home'
},
// 點(diǎn)擊菜單使用的函數(shù)
methods: {
makeActive: function(item){
// 模型改變,視圖會(huì)自動(dòng)更新
this.active = item;
}
}
});
</script>
文章來源地址http://www.zghlxwxcb.cn/news/detail-434083.html
編輯文本
訂單列表
搜索頁面
切換不同布局
到了這里,關(guān)于Vue.js 教程---菜鳥教程的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!