vue實例從建立到銷燬的過程,稱爲生命週期,共有八個階段。css
這八個階段裏分別有一個叫作鉤子函數的實例選項。供用戶在相應的階段對其進行操做。vue
beforeCreate(){ //組件實例剛剛建立,還未進行數據觀測和事件配置 }, created(){ //實例已經建立完成,而且已經進行數據觀測和事件配置 }, beforeMount(){//模板編譯以前,還沒掛載 }, mounted(){ //模板編譯以後,已經掛載,此時纔會渲染頁面,才能看到頁面上數據的展現 }, beforeUpdate(){//組件更新以前 }, updated(){//組件更新以後 }, beforeDestroy(){//組件銷燬以前 }, destroyed(){ //組件銷燬以後 }
這幾個鉤子中,最經常使用的是created()
與mounted()
。express
計算屬性也是用來存儲數據,但具備如下幾個特色:緩存
<div id="app"> {{addZero}} </div> new Vue({ el: '#app', data: { num: 8 }, computed: { //這是計算屬性的get方法,用於取值 addZero() { return this.num > 10 ? this.num : '0' + this.num; } } })
這裏的addZero
和num
同樣,都是屬性。不過addZero
是依賴於num
、進行計算後的值。一旦num
的值發生變化,addZero
的值也會隨之變化。app
<div id="app"> {{num}}----{{addZero}} <br> <button type="button" @click="change">點擊改變num</button> </div> new Vue({ el: '#app', data: { num: 8 }, methods: { change: () => { this.num++; } }, computed: { addZero:() => { return this.num > 10 ? this.num : '0' + this.num; } } })
一旦咱們點擊按鈕改變num
的值,那麼由於計算屬性實時監測依賴項,addZero
也會跟着發生變化。dom
將計算屬性的get函數定義爲一個方法也能夠實現和計算屬性相似的功能。那麼兩者之間有什麼區別?函數
官方文檔給出了下面這個例子:動畫
computed: { now: function () { return Date.now() } }
計算屬性存在緩存,這裏的now
值不會發生變化。this
計算屬性由兩部分組成:get和set,分別用來獲取計算屬性和設置計算屬性。默認只有get,若是須要set,要本身添加。code
<div id="app"> {{num}}----{{addZero}} <br> <button type="button" @click="change(5)">點擊改變num</button> </div> new Vue({ el: '#app', data: { num: 8 }, methods: { change(newNumber) { this.addZero = newNumber; } }, computed: { addZero: { get() { return this.num > 10 ? this.num : '0' + this.num; }, set(newNum) { this.num = newNum } } } })
咱們再change
方法中改變addZero
屬性的值的時候會自動調用它的set方法。
vue中給實例和屬性提供了若干屬性和方法。
獲取屬性的語法:實例名.屬性名
如下是經常使用的屬性:
手動掛載vue實例
var vm=new Vue({ data:{ msg:'Hello vue.js' } }).$mount('#app');
銷燬實例
vm.$destroy(); //銷燬實例所佔的內存空間
在DOM更新完成後再執行回調函數,通常在修改數據以後使用該方法,以便獲取更新後的DOM
var vm=new Vue({ data:{ msg:'Hello vue.js' } }).$mount('#app'); //修改數據 vm.msg='foo'; console.log(vm.$refs.title.textContent); //Hello vue.js vm.$nextTick(function(){ console.log(vm.$refs.title.textContent); //foo });
DOM還沒更新完,Vue實現響應式並非數據發生改變以後DOM當即變化,須要按必定的策略進行DOM更新,須要時間!使用$nextTick
方法等DOM更新完再獲取數據。
經過vue實例的$set方法爲對象添加屬性,能夠實時監視。
<div id="app"> {{user.name}}<br> {{user.age}} <br> <button type="button" @click="addAge">添加屬性</button> </div> var vm = new Vue({ data: { msg: 'Hello vue.js', user: { name: 'hedawei', gender: 'man' } }, methods: { addAge() { /* this.user.age = 22; */ this.$set(this.user, 'age', 22); } } }).$mount('#app');
方法中使用原始的添加屬性方法的話不會在模板中顯示。使用$set
方法會實時監控數據,而後添加。
監控vue實例的變化
vm.$watch('msg', (newValue, oldValue) => { console.log('msg被修改啦,原值:' + oldValue + ',新值:' + newValue); });
若是須要監控深度數據變化(例如監控一個對象中的某個屬性),則須要在選項中添加{deep:true}
自定義指令分爲自定義全局指令和自定義局部指令。
使用全局方法Vue.directive(指令ID,定義對象)
。注:使用指令時必須在指名名稱前加前綴v-,即v-指令名稱
。
簡單示例:
Vue.directive('hello',{ bind(){ //經常使用!! alert('指令第一次綁定到元素上時調用,只調用一次,可執行初始化操做'); }, inserted(){ alert('被綁定元素插入到DOM中時調用'); }, update(){ alert('被綁定元素所在模板更新時調用'); }, componentUpdated(){ alert('被綁定元素所在模板完成一次更新週期時調用'); }, unbind(){ alert('指令與元素解綁時調用,只調用一次'); } });
這裏定義了一個名爲hello
的指令,指令定義函數提供了幾個鉤子函數,分別在不一樣的時期生效。咱們像下面這樣使用這個指令:
<p v-hello>hello vue.js</p>
大多數狀況下,咱們只須要使用bind
與update
鉤子函數。vue裏提供了函數的簡寫形式:
Vue.directive('hello', function () { alert("hello vue.js"); })
鉤子函數有兩個經常使用的參數el
和binding
。el
是綁定的DOM對象,binding
是一個對象,包含若干屬性。
拿到DOM對象,咱們就能夠對DOM進行一些操做。
<p v-hello="msg">hello vue.js</p> Vue.directive('hello', function (el,binding) { el.style.color = "red"; //屬性name是指令的名字(不帶v-) console.log(binding.name); //hello //屬性value是傳遞給指令的值 console.log(binding.value); //alice //屬性expression是指令值的字符串形式(我的感受就是相似變量名) console.log(binding.expression); //msg //屬性arg是傳遞給指令的參數(和傳值寫在一塊兒容易令初學者困惑,下面分開寫 //合在一塊兒寫的寫法是<p v-hello:123="msg">hello vue.js</p>) //<p v-hello:123>hello vue.js</p> console.log(binding.arg); //123 //屬性modifiers是一個包含修飾符的對象。 //與傳參傳值合在一塊兒的寫法是 <p v-hello:123.bar="msg">hedawei</p> //<p v-hello.bar>hello vue.js</p> console.log(binding.modifiers); //{bar:true} }) var vm = new Vue({ el: '#app', data: { msg: 'alice' } })
局部自定義指令寫在實例的directives
選項中。
var vm = new Vue({ el: '#app', data: { msg: 'alice' }, methods: { }, directives: { word: function(el, binding) { console.log(binding.name); } } })
其餘用法與全局自定義指令一致。
Vue 在插入、更新或者移除 DOM 時,提供多種不一樣方式的應用過渡效果。本質上仍是使用CSS3動畫:transition、animation屬性。
使用transition組件,將要執行動畫的元素包含在該組件內:
<transition name="fade"> 運動的元素 </transition>
咱們須要爲其定義一個name
屬性,以便後面爲其添加css樣式。
動畫有6個CSS類名,下面結合例子說明:
<style> button { display: block; margin: 20px auto; } p { width: 100px; height: 100px; background-color: red; margin: 0 auto; } .fade-enter-active, .fade-leave-active { //定義整個過渡期間的效果 transition: all 2s ease; } .fade-enter-to { //定義過渡進入的最終效果 opacity: 1; width: 100px; height: 100px; } .fade-leave-to { //定義過渡離開的最終效果 opacity: 0; width: 50px; height: 50px; } .fade-enter { //定義過渡進入的開始效果 opacity: 0; width: 50px; height: 50px; } </style> <div id="app"> <button type="button" @click="flag = !flag">點 擊</button> <transition name="fade"> <p v-show="flag"> </p> </transition> </div> <script> new Vue({ el: '#app', data: { flag: false } }); </script>
vue中給過渡的不一樣時期提供了不一樣的鉤子函數。
<transition name="fade" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter" @before-leave="beforeLeave" @leave="leave" @after-leave="afterLeave"> <p v-show="flag"> </p> </transition> new Vue({ ... methods: { beforeEnter(el) { alert('動畫進入以前'); }, enter(el) { alert('動畫進入'); }, afterEnter(el) { alert('動畫進入以後'); }, beforeLeave(el) { alert('動畫離開以前'); }, leave(el) { alert('動畫離開'); }, afterLeave(el) { alert('動畫離開以後'); } } });
在這不一樣的時期,咱們能夠取到過渡元素的DOM對象,從而對其進行操做。
上面的<transition></transition>
標籤只適用於單元素過渡。若要對多元素進行過渡,則須要使用<transition-group></transition-group>
標籤,而且綁定key
屬性,設置不一樣的值。
<button type="button" @click="flag = !flag">點 擊</button> <transition-group name="fade"> <p v-show="flag" :key="1"> </p> <p v-show="flag" :key="2"> </p> </transition-group>
咱們可使用vue的自定義過渡類名結合第三方動畫庫實現自定義動畫效果。這六個自定義類名和vue內置的類名相似:
p { width: 300px; height: 300px; background-color: red; margin: 0 auto; } <div id="app"> <button type="button" @click="flag = !flag">點 擊</button> <transition enter-active-class="animated tada" leave-active-class="animated bounceOutRight"> <p v-show="flag"> </p> </transition> </div> <script> new Vue({ el: '#app', data: { flag: false } }); </script>
未完待續。。。