一:表單
v-model
會根據(jù)控件類型自動選取正確的方法來更新元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<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>
</body>
</html>
運行結(jié)果:
復選框
復選框如果是一個為邏輯值奕翔,如果是多個則綁定到同一個數(shù)組:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<p>單個復選框:</p>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
<p>多個復選框:</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>
</body>
</html>
運行結(jié)果:
單選按鈕
以下實例中演示了單選按鈕的雙向數(shù)據(jù)綁定:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<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>
</body>
</html>
運行結(jié)果:
select 列表
以下實例中演示了下拉列表的雙向數(shù)據(jù)綁定
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<select v-model="selected" name="fruit">
<option value="">選擇一個網(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>
</body>
</html>
運行結(jié)果:
修飾符
.lazy
在默認情況下, v-model 在 input 事件中同步輸入框的值與數(shù)據(jù)弱左,但你可以添加一個修飾符 lazy 侧纯,從而轉(zhuǎn)變?yōu)樵?change 事件中同步:
<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >
.number
如果想自動將用戶的輸入值轉(zhuǎn)為 Number 類型(如果原值的轉(zhuǎn)換結(jié)果為 NaN 則返回原值)骚揍,可以添加一個修飾符 number 給 v-model 來處理輸入值:
<input v-model.number="age" type="number">
這通常很有用媳拴,因為在 type="number" 時 HTML 中輸入的值也總是會返回字符串類型依鸥。
.trim
如果要自動過濾用戶輸入的首尾空格亥至,可以添加 trim 修飾符到 v-model 上過濾輸入:
<input v-model.trim="msg">
二:組件
組件(Component)是 Vue.js
最強大的功能之一。
組件可以擴展 HTML 元素贱迟,封裝可重用的代碼姐扮。
組件系統(tǒng)讓我們可以用獨立可復用的小組件來構(gòu)建大型應(yīng)用,幾乎任意類型的應(yīng)用的界面都可以抽象為一個組件樹:
注冊一個全局組件語法格式如下:
Vue.component(tagName, options)
tagName 為組件名衣吠,options 為配置選項茶敏。注冊后,我們可以使用以下方式來調(diào)用組件:
<tagName></tagName>
全局組件
: 所有實例都能用全局組件缚俏。
注冊一個簡單的全局組件runoob
惊搏,并使用它:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<runoob></runoob>
</div>
<script>
// 注冊
Vue.component('runoob', {
template: '<h1>自定義組件!</h1>'
})
// 創(chuàng)建根實例
new Vue({
el: '#app'
})
</script>
</body>
</html>
結(jié)果:
自定義組件!
局部組件
: 實例選項中注冊局部組件贮乳,這樣組件只能在這個實例中使用:。
注冊一個簡單的局部組件runoob
恬惯,并使用它:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<runoob></runoob>
</div>
<script>
var Child = {
template: '<h1>自定義組件!</h1>'
}
// 創(chuàng)建根實例
new Vue({
el: '#app',
components: {
// <runoob> 將只在父模板可用
'runoob': Child
}
})
</script>
</body>
</html>
結(jié)果:
自定義組件!
Prop
: prop 是子組件用來接受父組件傳遞過來的數(shù)據(jù)的一個自定義屬性向拆。
父組件的數(shù)據(jù)需要通過 props 把數(shù)據(jù)傳給子組件,子組件需要顯式地用 props 選項聲明 "prop":
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<child message="hello!"></child>
</div>
<script>
// 注冊
Vue.component('child', {
// 聲明 props
props: ['message'],
// 同樣也可以在 vm 實例中像 “this.message” 這樣使用
template: '<span>{{ message }}</span>'
})
// 創(chuàng)建根實例
new Vue({
el: '#app'
})
</script>
</body>
</html>
結(jié)果:
hello!
動態(tài) Prop
: 類似于用 v-bind 綁定 HTML 特性到一個表達式酪耳,也可以用 v-bind 動態(tài)綁定 props 的值到父組件的數(shù)據(jù)中亲铡。每當父組件的數(shù)據(jù)變化時,該變化也會傳導給子組件:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<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 實例中像 “this.message” 這樣使用
template: '<span>{{ message }}</span>'
})
// 創(chuàng)建根實例
new Vue({
el: '#app',
data: {
parentMsg: '父組件內(nèi)容'
}
})
</script>
</body>
</html>
結(jié)果:輸入框改變葡兑,下面的內(nèi)容也變
動態(tài) Prop
: 類似于用 v-bind 綁定 HTML 特性到一個表達式奖蔓,也可以用 v-bind 動態(tài)綁定 props 的值到父組件的數(shù)據(jù)中。每當父組件的數(shù)據(jù)變化時讹堤,該變化也會傳導給子組件:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<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>
</body>
</html>
結(jié)果
1. Runoob
2. Google
3. Taobao
Prop 驗證
: 組件可以為 props 指定驗證要求吆鹤。
為了定制 prop 的驗證方式,你可以為 props 中的值提供一個帶有驗證需求的對象洲守,而不是一個字符串數(shù)組疑务。例如:
Vue.component('my-component', {
props: {
// 基礎(chǔ)的類型檢查 (`null` 和 `undefined` 會通過任何類型驗證)
propA: Number,
// 多個可能的類型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 帶有默認值的數(shù)字
propD: {
type: Number,
default: 100
},
// 帶有默認值的對象
propE: {
type: Object,
// 對象或數(shù)組默認值必須從一個工廠函數(shù)獲取
default: function () {
return { message: 'hello' }
}
},
// 自定義驗證函數(shù)
propF: {
validator: function (value) {
// 這個值必須匹配下列字符串中的一個
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
當 prop 驗證失敗的時候,(開發(fā)環(huán)境構(gòu)建版本的) Vue 將會產(chǎn)生一個控制臺的警告梗醇。
type 可以是下面原生構(gòu)造器:
- String
- Number
- Boolean
- Array
- Object
- Date
- Function
- Symbol
type 也可以是一個自定義構(gòu)造器知允,使用 instanceof 檢測比庄。
三:自定義事件
父組件是使用props
傳遞數(shù)據(jù)給子組件忽肛,但如果子組件要把數(shù)據(jù)傳遞回去,就需要使用自定義事件秉版!
我們可以使用 v-on
綁定自定義事件, 每個 Vue 實例都實現(xiàn)了事件接口(Events interface)
手负,即:
- 使用
$on(eventName)
監(jiān)聽事件- 使用
$emit(eventName)
觸發(fā)事件
另外涤垫,父組件可以在使用子組件的地方直接用v-on
來監(jiān)聽子組件觸發(fā)的事件。
以下實例中子組件已經(jīng)和它外部完全解耦了竟终。它所做的只是觸發(fā)一個父組件關(guān)心的內(nèi)部事件蝠猬。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<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>
</body>
</html>
結(jié)果:
如果你想在某個組件的根元素上監(jiān)聽一個原生事件⊥炒罚可以使用 .native 修飾 v-on 榆芦。例如:
<my-component v-on:click.native="doTheThing"></my-component>
data
必須是一個函數(shù)
上面例子中,可以看到 ·button-counter
組件中的data
不是一個對象喘鸟,而是一個函數(shù):
data: function () {
return {
count: 0
}
}
這樣的好處就是每個實例可以維護一份被返回對象的獨立的拷貝匆绣,如果 data 是一個對象則會影響到其他實例,如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<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 選項是一個函數(shù)迷守,組件不相互影響
return {
count: 0
}
},
*/
data: function () {
// data 選項是一個對象犬绒,會影響到其他實例
return buttonCounter2Data
},
template: '<button v-on:click="count++">點擊了 {{ count }} 次旺入。</button>'
})
new Vue({ el: '#components-demo3' })
</script>
</body>
</html>
結(jié)果:點擊8次的效果
自定義組件的 v-model
組件上的 v-model
默認會利用名為 value
的prop
和名為 input 的事件兑凿。
<input v-model="parentData">
等價于:
<input
:value="parentData"
@input="parentData = $event.target.value"
>
以下實例自定義組件 runoob-input凯力,父組件的 num 的初始值是 100,更改子組件的值能實時更新父組件的 num:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實例 - 菜鳥教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<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>
</body>
</html>
結(jié)果:
由于 v-model 默認傳的是 value礼华,不是 checked咐鹤,所以對于復選框或者單選框的組件時,我們需要使用 model 選項圣絮,model 選項可以指定當前的事件類型和傳入的 props祈惶。
由于 v-model 默認傳的是 value,不是 checked扮匠,所以對于復選框或者單選框的組件時捧请,我們需要使用 model 選項,model 選項可以指定當前的事件類型和傳入的 props棒搜。
結(jié)果:
data
也可以是對象:
Vue.component('button-counter2', {
/*
data: function () {
// data 選項是一個函數(shù)疹蛉,組件不相互影響
return {
count: 0
}
},
*/
data: function () {
// data 選項是一個對象,會影響到其他實例
return buttonCounter2Data
},
template: '<button v-on:click="count++">點擊了 {{ count }} 次力麸。</button>'
})
注釋起來的 data
代碼和未注釋起來的 data
都是函數(shù)可款,只是注釋起來的函數(shù)返回值是每執(zhí)行一次函數(shù)就產(chǎn)生一個獨立的對象,而未注釋的data
函數(shù)返回值卻是引用了一個已有對象的名稱(即對象的引用)克蚂,不管函數(shù)執(zhí)行多少次返回值都是這個外部定義的對象的引用而已闺鲸,也就是說不管有多少個組件,所有的組件維護的數(shù)據(jù)都是同一個對象的數(shù)據(jù)而已埃叭,所以一個組件的數(shù)據(jù)發(fā)生變化同樣會影響到其他所有的組件的數(shù)據(jù)摸恍。。赤屋。