一、Vue 實例的基本結(jié)構(gòu)
script標(biāo)簽引入vue.js文件
<div id="app">
<p>{{msg}}<p>
</div>
// script標(biāo)簽內(nèi)容:
var vm = new Vue({
el: '#app',
data: {
//頁面響應(yīng)的數(shù)據(jù)都放在這里,
msg: ' ',
},
props:{
//props 可以是數(shù)組或?qū)ο?,接收任何?br>
},
methods: {
//頁面或組件定義的方法的集合
},
computed: {
//計算屬性(computed)與方法(methods) 類似,如果計算數(shù)據(jù)量比較大,建議放到這里
},
components:{
// 局部組件注冊的地方
'component-a': ComponentA,
'component-b': ComponentB
},
directives: {
// 局部指令注冊的地方
focus: {
// 指令的定義
inserted: function (el,binding) {
el.focus();
}
}
},
filters:{
// 局部過濾器注冊的地方
},
二、Vue 事件處理、綁定屬性
v-on:
1、綁定事件監(jiān)聽器。
如:click、keyup/down、mouseenter/over/move/down/out 等。
也可以監(jiān)聽自定義事件即 methods 里面的事件。
在監(jiān)聽原生 DOM 事件時,方法以事件為唯一的參數(shù)。如果使用內(nèi)聯(lián)語句,語句可以訪問一個 event)"。
常用修飾符:
.stop - 調(diào)用 event.stopPropagation()。阻止冒泡
.prevent - 調(diào)用 event.preventDefault()。阻止默認事件
.capture - 添加事件偵聽器時使用 capture 模式。
.self - 只當(dāng)事件是從偵聽器綁定的元素本身觸發(fā)時才觸發(fā)回調(diào)。
.{keyCode | keyAlias} - 只當(dāng)事件是從特定鍵觸發(fā)時才觸發(fā)回調(diào)。
.native - 監(jiān)聽組件根元素的原生事件。
.once - 只觸發(fā)一次回調(diào)。
用法:
內(nèi)聯(lián)語句
<button v-on:click="doThat('hello', $event)"></button>
縮寫
<button @click="doThis"></button>
停止冒泡
<button @click.stop="doThis"></button>
對象語法
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
v-on 還提供了按鍵修飾
鍵盤按鈕的別名
.enter
.tab
.delete (捕獲“刪除”和“退格”鍵)
.esc
.space
.up
.down
.left
.right
2、v-bind: 動態(tài)地綁定一個或多個特性,或一個組件 prop 到表達式。
綁定一個屬性
<img v-bind:src="imageSrc">
縮寫
<img :src="imageSrc">
內(nèi)聯(lián)字符串拼接
<img :src="'/path/to/images/' + fileName">
class 綁定
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">
style 綁定
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>
綁定一個有屬性的對象
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
三、Vue 指令、自定義指令、
Vue指令:
v-text:
<span v-text="msg"></span>
<span>{{msg}}</span>
v-html://輸出真正的 HTML
<div v-html="html"></div>
data{
html:'<strong>我是真正的html</strong>'
}
v-show://根據(jù)表達式之真假值,切換元素的 display CSS 屬性。
<h1 v-show="ok">Hello!</h1>
v-if、v-if-else、v-else:
//v-if 是“真正”的條件渲染,如果條件為假,dom不會渲染在頁面當(dāng)中
//v-show 會一直渲染在dom當(dāng)中
//當(dāng) v-if 與 v-for 一起使用時,v-for 具有比 v-if 更高的優(yōu)先級。
<h1 v-if="ok">Yes</h1>
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
<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-for://基于源數(shù)據(jù)多次渲染元素或模板塊。
<div v-for="item in items">
{{ item.text }}
</div>
//另外也可以為數(shù)組索引指定別名 (或者用于對象的鍵):val->對象的鍵值 key->對象的鍵 index->對象的下標(biāo)
<div v-for="(item, index) in items"></div>
<div v-for="(val, key) in object"></div>
<div v-for="(val, key, index) in object"></div>
v-model:作用于<input>、<select>、<textarea>,
當(dāng)v-model作用于多個復(fù)選框、當(dāng)選擇按鈕、選擇框時,都是把這些標(biāo)簽的value值賦值給v-model的變量
修飾符:
.lazy - 取代 input 監(jiān)聽 change 事件
.number- 輸入字符串轉(zhuǎn)為數(shù)字
.trim- 輸入首尾空格過濾
<input v-model="message" placeholder="edit me">
<textarea v-model="message" placeholder="add multiple lines"></textarea>
// 選擇框
<select v-model="selected">
<option disabled value="">請選擇</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
// 用 v-for 渲染的動態(tài)選項:
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
v-once:只渲染元素和組件一次。隨后的重新渲染,元素/組件及其所有的子節(jié)點將被視為靜態(tài)內(nèi)容并跳過。這可以用于優(yōu)化更新性能。
單個元素
<span v-once>This will never change: {{msg}}</span>
有子元素
<div v-once>
<h1>comment</h1>
<p>{{msg}}</p>
</div>
組件
<my-component v-once :comment="msg"></my-component>
v-for 指令
<ul>
<li v-for="i in list" v-once>{{i}}</li>
</ul>
Vue自定義指令:
bind:只調(diào)用一次,指令第一次綁定到元素時調(diào)用。在這里可以進行一次性的初始化設(shè)置。
inserted:被綁定元素插入父節(jié)點時調(diào)用 (僅保證父節(jié)點存在,但不一定已被插入文檔中)。
update:1、所在組件的 VNode 更新時調(diào)用,但是可能發(fā)生在其子 VNode 更新之前。
2、指令的值可能發(fā)生了改變,也可能沒有。
3、你可以通過比較更新前后的值來忽略不必要的模板更新
componentUpdated:指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用。
unbind:只調(diào)用一次,指令與元素解綁時調(diào)用。
el:指令所綁定的元素,可以用來直接操作 DOM 。
binding:一個對象,包含以下屬性:
name:指令名,不包括 v- 前綴。
value:指令的綁定值,例如:v-my-directive="1 + 1" 中,綁定值為 2。
oldValue:指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。
expression:字符串形式的指令表達式。例如 v-my-directive="1 + 1" 中,表達式為 "1 + 1"。
arg:傳給指令的參數(shù),可選。例如 v-my-directive:foo 中,參數(shù)為 "foo"。
modifiers:一個包含修飾符的對象。例如:v-my-directive.foo.bar 中,修飾符對象為 { foo: true, bar: true }。
Vue.directive('focus', {
// 當(dāng)被綁定的元素插入到 DOM 中時……
inserted: function (el,binding) {
// 聚焦元素
el.focus();
console.log(binding.value) //=>666
}
})
//如果想注冊局部指令,組件中也接受一個 directives 的選項:
directives: {
focus: {
// 指令的定義
inserted: function (el,binding) {
el.focus();
console.log(binding.value) //=>666
}
}
}
四、Vue 過濾器
Vue 過濾器的用法
過濾器可以用在兩個地方:雙花括號插值和 v-bind 表達式
與指令的用法類似,但過濾器一定要有返回值,也不支持鏈?zhǔn)秸{(diào)用
// 在雙花括號中
{{ message | capitalize }}
// 在 v-bind 中
<div v-bind:id="rawId | formatId"></div>
// 局部注冊過濾器
filters: {
// 首字母大寫
capitalize: function (value) {
// value 就是 ‘|’ 符號前面的值
if (!value) return '';
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
// 注冊全局過濾器
Vue.filter('capitalize', function (value) {
if (!value) return '';
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
// 過濾器傳值
{{ number | dual(2) }}
Vue.filter('dual', function (value,type) {
// 回調(diào)函數(shù)里面默認有 value ,在頁面上傳過來的值會依次添加在后面
console.log(type) // => 2
if (!value) return '';
if (typeof value !== "number") return alert(value + ' 不是數(shù)字');
if( parseInt(type) === 2 ){
return value = value > 10 ? value : '0' + value
}
return value
})
// 過濾器的插件用法,與 directives.js 一致
// main.js
import directives from './filters.js'
Vue.use(filters);
// filters.js
export default {
install(Vue){
Vue.filter('dual', function (value,type) {
if (!value) return '';
if (typeof value !== "number") return alert(value + ' 不是數(shù)字');
if( parseInt(type) === 2 ){
return value = value > 10 ? value : '0' + value
}
return value
})
}
}
五、Vue 數(shù)據(jù)監(jiān)聽
Vue 數(shù)據(jù)監(jiān)聽 watch
// watch 基本用法與注意事項
data: {
a: 1,
e: {
f: {
g: 5
}
},
items: [
{ message: 'Foo' },
{ message: 'Bar' }
],
}
mounted: function(){
this.a = 2;
this.e.f.g = 10;
this.set 賦值
this.items[0] = { message: 'AAA' }; // 直接賦值
},
watch: {
// 最簡單最直接的監(jiān)聽方式,能監(jiān)聽簡單的數(shù)據(jù)變化,這種方法默認就是執(zhí)行 handler: function(){}
// 注意:這種方式監(jiān)聽不到對象的變化
a: function(val, oldVal){
console.log(val); // => 變化之后的數(shù)據(jù)
console.log(oldVal); // => 變化之前的數(shù)據(jù)
},
// 深度監(jiān)聽,這里要注意一下,這樣的方式打印出來兩個值都是變化之后的值
// deep 的值默認為false,如果不寫或者deep: false 都不能監(jiān)聽到對象值的變化
e: {
handler: function (val, oldVal) {
console.log(val); // => 變化之后的數(shù)據(jù)
console.log(oldVal); // => 變化之后的數(shù)據(jù)
},
deep: true,
},
// 如果要精準(zhǔn)監(jiān)聽的對象值的變化,可以用這種方法
'e.f.g': function (val, oldVal) {
console.log(val); // => 變化之后的數(shù)據(jù)
console.log(oldVal); // => 變化之前的數(shù)據(jù)
},
// 監(jiān)聽數(shù)組
// 由于 JavaScript 的限制,Vue 不能檢測 this.items[0] = { message: 'AAA' }; 這種方式賦值的變化
// 所以你要用 $set、或者數(shù)組變異的方法賦值
items: function(val, oldVal){
console.log(val); // => 變化之后的數(shù)據(jù)
console.log(oldVal); // => 變化之后的數(shù)據(jù)
},
}
六、Vue 組件
Vue 組件基礎(chǔ)
組件是可復(fù)用的 Vue 實例,所以它們與 new Vue 接收相同的選項,例如 data、computed、watch、methods等。
Vue.component( 組件名 ,{ 選項 }) 全局注冊
// 全局注冊組件的時候必須寫在Vue實例創(chuàng)建之前
// 下面這幾種方式是等價的
import Vue from 'vue'
var MyComponent = Vue.extend({
template:"<h1>我是全局組件</h1>"
});
Vue.component("my-component",MyComponent);
// 注冊組件,傳入一個擴展過的構(gòu)造器
Vue.component('my-component', Vue.extend({ /* ... / }))
// 注冊組件,傳入一個選項對象 (自動調(diào)用 Vue.extend)
Vue.component('my-component', { / ... */ })
// 一個定義模板的方式是在一個 <script> 元素中,并為其帶上 text/x-template 的類型,然后通過一個 id 將模板引用過去。
<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
// 另一個定義模板的方式是在一個 <template> 元素中,通過一個 id 將模板引用過去;在單文件組件 .vue 當(dāng)中,id可以省略;
<template id="hello-world-template">
<p>Hello hello hello</p>
</template>
Vue.component("my-component",{
template:"#hello-world-template"
});
局部注冊組件
// 每個vue 實例都會有一個 components 的選項,而組件是可復(fù)用的 Vue 實例,所以每個組件都有components 選項
// 引入外部文件注冊成局部組件
import home from './components/home/home'
new Vue({
el:"#app",
components: {
home, // 等價于home: home,ES6對象中屬性的簡潔表示,ES6(http://es6.ruanyifeng.com/#docs/object)
}
});
// 直接在components 選項中寫,(不推薦這種用法)
new Vue({
el:"#app",
components: {
loading: {
data: function () {
return {
getting: 'welcome'
}
},
components:{
// 這里還可以嵌套局部組件...
}
}
}
});
Vue.component('my-component', {
props: {
// 基礎(chǔ)的類型檢查 (null 匹配任何類型)
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
}
}
}
})