一入录、自定義組件
1、創(chuàng)建組件vue
<!--公用button-->
<template>
<div class="btn">
<button type="button">{{btnText}}</button>
</div>
</template>
<script>
export default {
</script>
<style lang="less" scoped>
</style>
2晒夹、父級(jí)引入組件并定義運(yùn)用
html:
<btn :btn-text="btnText" @touchstart.native="toPay()"></btn>
js:
import btn from '../common/btn.vue';
export default {
components: {
btn
},
}
3裆馒、一個(gè)組件的v-for
在自定義組件里,你可以像任何普通元素一樣用 v-for 丐怯。
<my-component v-for="item in items" :key="item.id"></my-component>
2.2.0+ 的版本里喷好,當(dāng)在組件中使用 v-for 時(shí),key 現(xiàn)在是必須的读跷。
4梗搅、組件的prop
在 Vue 中,父子組件的關(guān)系可以總結(jié)為 prop 向下傳遞效览,事件向上傳遞无切。父組件通過(guò) prop 給子組件下發(fā)數(shù)據(jù),子組件通過(guò)事件給父組件發(fā)送消息
5钦铺、HTML 特性是不區(qū)分大小寫(xiě)的订雾。所以,當(dāng)使用的不是字符串模板時(shí)矛洞,camelCase (駝峰式命名) 的 prop 需要轉(zhuǎn)換為相對(duì)應(yīng)的 kebab-case (短橫線分隔式命名):
Vue.component('child', {
// 在 JavaScript 中使用 camelCase
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>' //沒(méi)有寫(xiě)在html的為字符串模板
})
<!-- 在 HTML 中使用 kebab-case -->
<child my-message="hello!"></child> //寫(xiě)在html的為非字符串模板需要:相對(duì)應(yīng)的 kebab-case (短橫線分隔式命名)
如果你使用字符串模板洼哎,則沒(méi)有這些限制烫映。
二、組件父?jìng)髯訑?shù)據(jù)
1噩峦、父級(jí)綁定要傳輸?shù)臄?shù)據(jù)
<btn :btn-text="btnText" @touchstart.native="toPay()"></btn>
2锭沟、子組件接收并引用(props驗(yàn)證type寫(xiě)法)
3、如果你想把一個(gè)對(duì)象的所有屬性作為 prop 進(jìn)行傳遞识补,可以使用不帶任何參數(shù)的 v-bind (即用 v-bind 而不是 v-bind:prop-name)族淮。例如,已知一個(gè) todo 對(duì)象:
todo: {
text: 'Learn Vue',
isComplete: false
}
<todo-item v-bind="todo"></todo-item>
將等價(jià)于:
<todo-item
v-bind:text="todo.text"
v-bind:is-complete="todo.isComplete"
></todo-item>
4凭涂、 單向數(shù)據(jù)流
三祝辣、組件子傳父數(shù)據(jù)( 自定義事件)
1、
// 子組件通過(guò)$emit發(fā)射數(shù)據(jù)
methods: {
popHide() {
this.$emit('popHide', false);
},
},
// 父級(jí)通過(guò)v-on:popHide接收數(shù)據(jù)
<gained v-show="isPopShow" :currentData = "currentData" v-on:popHide="popHide" v-if="gained"></gained>
2切油、使用自定義事件的表單輸入組件
3蝙斜、非父子組件的通信
var bus = new Vue()
// 觸發(fā)組件 A 中的事件
bus.$emit('id-selected', 1)
// 在組件 B 創(chuàng)建的鉤子中監(jiān)聽(tīng)事件
bus.$on('id-selected', function (id) {
// ...
})
四、父組件通過(guò)prop傳遞數(shù)據(jù)給子組件澎胡,子組件觸發(fā)事件給父組件孕荠。但父組件想在子組件上監(jiān)聽(tīng)自己的click的話,需要加上native修飾符攻谁,故寫(xiě)法就像下面這樣稚伍。( 給組件綁定原生事件)
<btn :btn-text="btnText" v-on:click.native="setPhone"></btn>
如果將click的native去掉戚宦,思路如下:
子組件監(jiān)聽(tīng)父組件給的click事件,
子組件內(nèi)部處理click事件然后向外發(fā)送click事件:$emit("click".fn)
改造后的代碼如下(親測(cè)可用):
<template>
<button class="disable-hover button ion-button" @click="_click"
:class="[modeClass,typeClass,shapeClass,sizeClass,colorClass,roleClass,strongClass]">
<span class="button-inner">
<slot></slot>
</span>
<div class="button-effect"></div>
</button>
</template>
<script type="text/babel">
export default{
....
....
methods: {
_click: function () {
this.$emit('click', function () {
alert('inner')
})
}
}
}
</script>
父組件中這樣使用:
<ion-button @click="primary()" color="primary">primary</ion-button>
五困檩,filters用法
<p>本期學(xué)習(xí)計(jì)劃開(kāi)啟日期為{{time | dateTransform}}</p>
filters: {
dateTransform(time) {
let reg =/(\d{4})\-(\d{2})\-(\d{2})/;
return time.replace(reg, "$1年$2月$3日");
}
},
六,獲取dom方法
//html
<div ref='outBox' class="out-box">
//js中獲取
let box = this.$refs.box;
let outBox = this.$refs.outBox;
七那槽、設(shè)置全局變量
main.js中寫(xiě)入
Vue.prototype.globalBadges = []; // 徽章全局變量用于儲(chǔ)存臨時(shí)徽章彈出
需要用到的地方:
this.globalBadges
如果需要的數(shù)據(jù)量很大得用vuex來(lái)處理數(shù)據(jù)了骚灸;
八糟趾、keep-alive的運(yùn)用;
1.基本用法
vue2.0提供了一個(gè)keep-alive組件
用來(lái)緩存組件,避免多次加載相應(yīng)的組件,減少性能消耗
<keep-alive>
<component>
<!-- 組件將被緩存 -->
</component>
</keep-alive>
有時(shí)候 可能需要緩存整個(gè)站點(diǎn)的所有頁(yè)面,而頁(yè)面一般一進(jìn)去都要觸發(fā)請(qǐng)求的
在使用keep-alive的情況下
<keep-alive><router-view></router-view></keep-alive>
將首次觸發(fā)請(qǐng)求寫(xiě)在created鉤子函數(shù)中,就能實(shí)現(xiàn)緩存,
比如列表頁(yè),去了詳情頁(yè) 回來(lái),還是在原來(lái)的頁(yè)面
2.緩存部分頁(yè)面或者組件
(1)使用router. meta屬性
// 這是目前用的比較多的方式
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
router設(shè)置
routes: [
{ path: '/', redirect: '/index', component: Index, meta: { keepAlive: true }},
{
path: '/common',
component: TestParent,
children: [
{ path: '/test2', component: Test2, meta: { keepAlive: true } }
]
}
// 表示index和test2都使用keep-alive
(2).使用新增屬性inlcude/exclude
2.1.0后提供了include/exclude兩個(gè)屬性 可以針對(duì)性緩存相應(yīng)的組件
<!-- comma-delimited string -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<!-- regex (use v-bind) -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
//其中a,b是組件的name
注意:這種方法都是預(yù)先知道組件的名稱的
(2)動(dòng)態(tài)判斷
<keep-alive :include="includedComponents">
<router-view></router-view>
</keep-alive>
includedComponents動(dòng)態(tài)設(shè)置即可
九甚牲、關(guān)于v-bind丈钙、v-on、v-model
v-bind
縮寫(xiě):
:
預(yù)期:
any (with argument) | Object (without argument)
參數(shù):
attrOrProp (optional)
-
修飾符:
-
.prop
- 被用于綁定 DOM 屬性劫笙。 -
.camel
- (2.1.0+) 將 kebab-case 特性名轉(zhuǎn)換為 camelCase. -
.sync
(2.3.0+) 語(yǔ)法糖,會(huì)擴(kuò)展成一個(gè)更新父組件綁定值的 v-on 偵聽(tīng)器填大。
-
用法:
動(dòng)態(tài)地綁定一個(gè)或多個(gè)特性允华,或一個(gè)組件 prop 到表達(dá)式。
在綁定class
或style
特性時(shí)磷蜀,支持其它類型的值榨汤,如數(shù)組或?qū)ο笫蘸尽轨蛤?梢酝ㄟ^(guò)下面的教程鏈接查看詳情。
在綁定 prop 時(shí)圃验,prop 必須在子組件中聲明“囊ぃ可以用修飾符指定不同的綁定類型供常。
沒(méi)有參數(shù)時(shí)栈暇,可以綁定到一個(gè)包含鍵值對(duì)的對(duì)象。注意此時(shí)class
和style
綁定不支持?jǐn)?shù)組和對(duì)象煎源。
v-on
縮寫(xiě):
@
預(yù)期:
Function | Inline Statement | Object
參數(shù):
event
-
修飾符:
-
.stop
- 調(diào)用 event.stopPropagation()香缺。 -
.prevent
- 調(diào)用 event.preventDefault()图张。 -
.capture
- 添加事件偵聽(tīng)器時(shí)使用 capture 模式馏慨。 -
.self
- 只當(dāng)事件是從偵聽(tīng)器綁定的元素本身觸發(fā)時(shí)才觸發(fā)回調(diào)写隶。 -
.{keyCode | keyAlias}
- 只當(dāng)事件是從特定鍵觸發(fā)時(shí)才觸發(fā)回調(diào)讲仰。 -
.native
- 監(jiān)聽(tīng)組件根元素的原生事件鄙陡。 -
.once
- 只觸發(fā)一次回調(diào)。 -
.left
- (2.2.0) 只當(dāng)點(diǎn)擊鼠標(biāo)左鍵時(shí)觸發(fā)耙册。 -
.right
- (2.2.0) 只當(dāng)點(diǎn)擊鼠標(biāo)右鍵時(shí)觸發(fā)毫捣。 -
.middle
- (2.2.0) 只當(dāng)點(diǎn)擊鼠標(biāo)中鍵時(shí)觸發(fā)蔓同。 -
.passive
- (2.3.0) 以 { passive: true } 模式添加偵聽(tīng)器
-
用法:
綁定事件監(jiān)聽(tīng)器。事件類型由參數(shù)指定弃揽。表達(dá)式可以是一個(gè)方法的名字或一個(gè)內(nèi)聯(lián)語(yǔ)句矿微,如果沒(méi)有修飾符也可以省略尚揣。
從2.4.0
開(kāi)始,v-on
同樣支持不帶參數(shù)綁定一個(gè)事件/監(jiān)聽(tīng)器鍵值對(duì)的對(duì)象蒿辙。注意當(dāng)使用對(duì)象語(yǔ)法時(shí)思灌,是不支持任何修飾器的恭取。
用在普通元素上時(shí)蜈垮,只能監(jiān)聽(tīng) 原生 DOM 事件裕照。用在自定義元素組件上時(shí)调塌,也可以監(jiān)聽(tīng)子組件觸發(fā)的自定義事件羔砾。
在監(jiān)聽(tīng)原生 DOM 事件時(shí),方法以事件為唯一的參數(shù)政溃。如果使用內(nèi)聯(lián)語(yǔ)句董虱,語(yǔ)句可以訪問(wèn)一個(gè)$event
屬性:v-on:click="handle('ok', $event)"
申鱼。
v-model
也可以綁定數(shù)據(jù)润讥,但是他是用在表單控件上的,用于實(shí)現(xiàn)雙向數(shù)據(jù)綁定,所以如果你用在除了表單控件以外的標(biāo)簽是沒(méi)有任何效果的竿痰。
v-model 會(huì)忽略所有表單元素的 value影涉、checked、selected 特性的初始值而總是將 Vue 實(shí)例的數(shù)據(jù)作為數(shù)據(jù)來(lái)源蟹倾。你應(yīng)該通過(guò) JavaScript 在組件的 data 選項(xiàng)中聲明初始值鲜棠。
.lazy
在默認(rèn)情況下,v-model
在每次 input
事件觸發(fā)后將輸入框的值與數(shù)據(jù)進(jìn)行同步 (除了上述輸入法組合文字時(shí))柑爸。你可以添加 lazy
修飾符表鳍,從而轉(zhuǎn)變?yōu)槭褂?change
事件進(jìn)行同步:
<!-- 在“change”時(shí)而非“input”時(shí)更新 -->
<input v-model.lazy="msg" >
.number
如果想自動(dòng)將用戶的輸入值轉(zhuǎn)為數(shù)值類型,可以給 v-model
添加 number
修飾符:
<input v-model.number="age" type="number">
這通常很有用瓮恭,因?yàn)榧词乖?type="number"
時(shí)偎血,HTML 輸入元素的值也總會(huì)返回字符串盯漂。
.trim
如果要自動(dòng)過(guò)濾用戶輸入的首尾空白字符就缆,可以給 v-model
添加 trim
修飾符:
<input v-model.trim="msg">
十、計(jì)算屬性和監(jiān)聽(tīng)器
<template>
<div>
<input type="text" name="" v-model="myVal"><br/>
{{ myValueWithoutNum }}<br/>
{{ getMyValueWithoutNum() }}<br/>
<input type="text" name="" v-model="myVal1"><br/>
</div>
</template>
<script>
export default {
data () {
return {
myVal: '',
myVal1:''
}
},
computed: { //計(jì)算屬性
myValueWithoutNum () {
return this.myVal.replace(/\d/g, '')
}
},
methods: {// 方法
getMyValueWithoutNum () {
return this.myVal.replace(/\d/g, '')
}
},
watch: { //監(jiān)聽(tīng)器
myVal1 (val, oldval) {
console.log(val, oldval)
}
}
}
</script>
相關(guān)文檔請(qǐng)看:https://cn.vuejs.org/v2/guide/computed.html
十一、數(shù)組更新檢測(cè)——變異方法
變異方法
Vue 包含一組觀察數(shù)組的變異方法切揭,所以它們也將會(huì)觸發(fā)視圖更新廓旬。這些方法如下:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
你打開(kāi)控制臺(tái)孕豹,然后用前面例子的 items
數(shù)組調(diào)用變異方法:example1.items.push({ message: 'Baz' })
。
替換數(shù)組
變異方法 (mutation method)春霍,顧名思義叶眉,會(huì)改變被這些方法調(diào)用的原始數(shù)組衅疙。相比之下,也有非變異 (non-mutating method) 方法妖爷,例如:filter()
, concat()
和 slice()
絮识。這些不會(huì)改變?cè)紨?shù)組,但總是返回一個(gè)新數(shù)組熄攘。當(dāng)使用非變異方法時(shí)彼念,可以用新數(shù)組替換舊數(shù)組:
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
你可能認(rèn)為這將導(dǎo)致 Vue 丟棄現(xiàn)有 DOM 并重新渲染整個(gè)列表逐沙。幸運(yùn)的是,事實(shí)并非如此棚赔。Vue 為了使得 DOM 元素得到最大范圍的重用而實(shí)現(xiàn)了一些智能的靠益、啟發(fā)式的方法残揉,所以用一個(gè)含有相同元素的數(shù)組去替換原來(lái)的數(shù)組是非常高效的操作抱环。
注意事項(xiàng)
由于 JavaScript 的限制,Vue 不能檢測(cè)以下變動(dòng)的數(shù)組:
- 當(dāng)你利用索引直接設(shè)置一個(gè)項(xiàng)時(shí)濒憋,例如:
vm.items[indexOfItem] = newValue
- 當(dāng)你修改數(shù)組的長(zhǎng)度時(shí),例如:
vm.items.length = newLength
為了解決第一類問(wèn)題条辟,以下兩種方式都可以實(shí)現(xiàn)和 vm.items[indexOfItem] = newValue
相同的效果宏胯,同時(shí)也將觸發(fā)狀態(tài)更新:
// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)
為了解決第二類問(wèn)題肩袍,你可以使用 splice
:
example1.items.splice(newLength)
舉例:
<template>
<div>
<ul id="example-1">
<li v-for="item in items">
{{ item }}
</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
items: [
'11111',
'22222',
'33333'
]
}
},
mounted(){
//this.items[0] = 'aaaaa'; 這種賦值方法視圖不更新數(shù)據(jù)
this.items.splice(0, 1, 'aaaaa') // 視圖更新數(shù)據(jù)
},
}
</script>
十二、 使用插槽分發(fā)內(nèi)容
十三魂爪、this.$nextTick
官方文檔解釋如下:
在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)滓侍。在修改數(shù)據(jù)之后立即使用這個(gè)方法撩笆,獲取更新后的 DOM。
我理解的官方文檔的這句話的側(cè)重點(diǎn)在最后那半句獲取更新后的DOM氮兵,獲取更新后的DOM言外之意就是什么操作需要用到了更新后的DOM而不能使用之前的DOM或者使用更新前的DOM或出問(wèn)題歹鱼,所以就衍生出了這個(gè)獲取更新后的DOM的Vue方法醉冤。所以放在Vue.nextTick()回調(diào)函數(shù)中的執(zhí)行的應(yīng)該是會(huì)對(duì)DOM進(jìn)行操作的 js代碼蚁阳,比如Swiper擴(kuò)展包的
var swiper = new Swiper('.swiper-container', {
pagination: '.swiper-pagination',
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
paginationClickable: true,
spaceBetween: 30,
centeredSlides: true,
autoplay: 2500,
autoplayDisableOnInteraction: false
});
什么時(shí)候需要用的Vue.nextTick()
1螺捐、你在Vue生命周期的created()鉤子函數(shù)進(jìn)行的DOM操作一定要放在Vue.nextTick()的回調(diào)函數(shù)中。原因是什么呢赔癌,原因是在created()鉤子函數(shù)執(zhí)行的時(shí)候DOM 其實(shí)并未進(jìn)行任何渲染澜沟,而此時(shí)進(jìn)行DOM操作無(wú)異于徒勞茫虽,所以此處一定要將DOM操作的js代碼放進(jìn)Vue.nextTick()的回調(diào)函數(shù)中。與之對(duì)應(yīng)的就是mounted鉤子函數(shù)正什,因?yàn)樵撱^子函數(shù)執(zhí)行時(shí)所有的DOM掛載和渲染都已完成婴氮,此時(shí)在該鉤子函數(shù)中進(jìn)行任何DOM操作都不會(huì)有問(wèn)題 。
2荣暮、在數(shù)據(jù)變化后要執(zhí)行的某個(gè)操作旨怠,而這個(gè)操作需要使用隨數(shù)據(jù)改變而改變的DOM結(jié)構(gòu)的時(shí)候鉴腻,這個(gè)操作都應(yīng)該放進(jìn)Vue.nextTick()的回調(diào)函數(shù)中爽哎。
原因是,Vue是異步執(zhí)行dom更新的厨内,一旦觀察到數(shù)據(jù)變化雏胃,Vue就會(huì)開(kāi)啟一個(gè)隊(duì)列志鞍,然后把在同一個(gè)事件循環(huán) (event loop) 當(dāng)中觀察到數(shù)據(jù)變化的 watcher 推送進(jìn)這個(gè)隊(duì)列固棚。如果這個(gè)watcher被觸發(fā)多次,只會(huì)被推送到隊(duì)列一次厂汗。這種緩沖行為可以有效的去掉重復(fù)數(shù)據(jù)造成的不必要的計(jì)算和DOm操作娶桦。而在下一個(gè)事件循環(huán)時(shí)汁汗,Vue會(huì)清空隊(duì)列碰酝,并進(jìn)行必要的DOM更新戴差。
當(dāng)你設(shè)置 vm.someData = 'new value',DOM 并不會(huì)馬上更新墨吓,而是在異步隊(duì)列被清除纹磺,也就是下一個(gè)事件循環(huán)開(kāi)始時(shí)執(zhí)行更新時(shí)才會(huì)進(jìn)行必要的DOM更新橄杨。如果此時(shí)你想要根據(jù)更新的 DOM 狀態(tài)去做某些事情式矫,就會(huì)出現(xiàn)問(wèn)題。聪廉。為了在數(shù)據(jù)變化之后等待 Vue 完成更新 DOM 板熊,可以在數(shù)據(jù)變化之后立即使用 Vue.nextTick(callback) 察绷。這樣回調(diào)函數(shù)在 DOM 更新完成后就會(huì)調(diào)用克婶。
十四、生命周期函數(shù)的運(yùn)用
beforecreate : 舉個(gè)栗子:可以在這加個(gè)loading事件
created :在這結(jié)束loading,還做一些初始化筋岛,實(shí)現(xiàn)函數(shù)自執(zhí)行
mounted : 在這發(fā)起后端請(qǐng)求睁宰,拿回?cái)?shù)據(jù)柒傻,配合路由鉤子做一些事情
beforeDestory: 你確認(rèn)刪除XX嗎? destoryed :當(dāng)前組件已被刪除青柄,清空相關(guān)內(nèi)容
十五致开、 非父子組件的通信
有時(shí)候,非父子關(guān)系的兩個(gè)組件之間也需要通信虹蒋。在簡(jiǎn)單的場(chǎng)景下魄衅,可以使用一個(gè)空的 Vue 實(shí)例作為事件總線:
var bus = new Vue()
// 觸發(fā)組件 A 中的事件
bus.$emit('id-selected', 1)
// 在組件 B 創(chuàng)建的鉤子中監(jiān)聽(tīng)事件
bus.$on('id-selected', function (id) {
// ...
})
在復(fù)雜的情況下徐绑,我們應(yīng)該考慮使用專門(mén)的狀態(tài)管理模式莫辨。
一篇有關(guān)Vue2.0子同級(jí)組件之間數(shù)據(jù)交互文章:http://blog.csdn.net/wang_meiwei/article/details/75948844