哈嘍你們好,先後端分離系列文章又開始了,今天週一,仍是感謝你們花時間來觀看我寫的博客,週末呢,沒有寫文章,可是也沒有閒着,主要是研究了下遺留問題,看過以前文章的應該知道,以前的在AOP使用Redis緩存的文章裏,遺留了一個問題,週末苦思冥想仍是不得其法,想了一個餿主意,可是確定不是最終解決方案,感興趣的能夠看看,地址《框架之十一 || AOP自定義篩選,Redis入門 11.1》,而後呢,剩下的時間,就是簡單搭建了下我在之後的Vue實戰中用到的一個小項目,我會手把手在一戶的文章中講到,可是還在搭建中,預計下週能夠接觸到,由於Vue是從新開始的,因此在基礎這一起說的比較多,主要也是但願都能好好學習下,也是但願能檢查下去,看博客園粉絲破百的時候,能不能有啥小福利啥的哈哈哈html
言歸正傳,上文我們說到了vue基礎的第二章 指令和計算屬性,由於時間的問題,上次沒有說到Class 與 Style 綁定,那今天我們就簡單說說這個綁定樣式問題,而後重點說一下 Vue的生命週期,我感受這個仍是比較重要的,由於任何一個Web程序,生命週期都是重中之重,老生常談的一個話題,今天我們也說說。而後若是有時間,能夠簡單說下Vue的兩大核心之組件(另外一個你們應該也還記得,就是數據驅動,雙向數據綁定,就是不用操做DOM的那個,嗯~),好啦,開始今天的講解吧!vue
以前我們都已經瞭解到了,Vue是經過Data來控制DOM的,這樣能夠減小太多的JS操做,從而達到頁面的無縫快速渲染的做用,這是一個很好的想法,咱們能夠想一下,頁面內,除了各類標籤的DOM須要操做修改之外,還有哪些因素呢,不過,你應該已經想到了,就是樣式!頁面的三大元素:HTML+CSS+JS。咱們也可使用相同的辦法,經過操做Data來控制樣式!對,Vue的設計者們也考慮到了這個問題,因此就出來了動態綁定class和style。操做元素的 class 列表和內聯樣式是數據綁定的一個常見需求。由於它們都是屬性,因此咱們能夠用
v-bind
處理它們:只須要經過表達式計算出字符串結果便可。不過,字符串拼接麻煩且易錯。所以,在將v-bind
用於class
和style
時,Vue.js 作了專門的加強。表達式結果的類型除了字符串以外,還能夠是對象或數組。git
還記得當時咱們給 a 標籤是如何添加 src 的?對,就是 v-bind ,它就是用來統一操做頁面內各類屬性的,因此咱們要修改 class 和 style 也得使用到 v-bind ,這裏咱們統一使用他們的縮寫 ( :),github
在咱們的博客首頁 DEMO 中,咱們都是經過這樣的方法定義一個 class編程
<li v-for='item in listSearch' class="post-list-item">
如今咱們須要實現一個刪除效果,那就須要給文章列表 list ,動態的增長一個 deleted 的 class ,後端
<!--注意,不能在已經存在的靜態類post-list-item上操做--> <li v-for='item in listSearch' class="post-list-item" :class="{ deleted: item.deleted}"> // 注意:若是用三目運算,不要加括 :class="o.cardShow === true ?'class1':'class2'"
var vm = new Vue({ el: '#app',//容器 data: { author: "老張的哲學", task: { name: '',//內容爲空 id: 100, date: " Just Now ", finished: false, deleted: false }, list: [ //假數據 { name: " Vue前篇:ES6初體驗 & 模塊化編程", id: 9585766, date: "2018年9月5日", finished: false, deleted: true },//咱們在這裏定義一個刪除的true { name: "Vue前篇:JS對象&字面量&this", id: 9580807, date: "2018年9月4日", finished: false, deleted: false }, { name: " VUE 計劃書 & 個人先後端開發簡史", id: 9577805, date: "2018年9月3日", finished: false, deleted: false }, { name: " DTOs 對象映射使用,項目部署Windows+Linux完整版", id: 3800, date: "2018年9月1日", finished: false, deleted: false }, { name: " 三種跨域方式比較,DTOs(數據傳輸對象)初探", id: 4200, date: "2018年8月31日", finished: false, deleted: false }, { name: "VUE 計劃書 & 個人先後端開發簡史", id: 3200, date: "2018年9月2日", finished: false, deleted: false }, { name: "VUE 實戰預告", id: 3200, date: "2018年9月12日", finished: false, deleted: false } ], }, } }); <!-- 樣式 --> <style> .deleted { color: red; text-decoration: line-through; } </style>
從代碼中咱們可看到 :class="{ deleted: item.deleted}",這是一個經過對象定義樣式,第一個 deleted ,就是咱們的樣式 class ,第二個就是對應咱們的 數據屬性。deleted 這個 class 存在與否將取決於數據屬性 list 中的 item.deleted 是否爲 true,若是爲 false,那麼這個 class 就不會顯示,這就達到了一個動態的效果,固然,你也能夠在對象中傳入更多屬性來動態切換多個 class。跨域
咱們能夠看一看結果:數組
咱們能夠把一個數組傳給 v-bind:class
,以應用一個 class 列表:緩存
<h2 :class="[hrClass,testClass]"> <span>Contact</span> </h2> data: { hrClass: 'hr', testClass:'test', }
運行出來的結果就是醬紫的:網絡
所以能夠看得出來,數組中的值是咱們的 Data 屬性值,經過渲染,加載出咱們對應的真是 class 值,這個在動態多個綁定的時候,仍是頗有用的。
v-bind:style
的對象語法十分直觀——看着很是像 CSS,但實際上是一個 JavaScript 對象。CSS 屬性名能夠用駝峯式 (camelCase) 或短橫線分隔 (kebab-case,記得用單引號括起來) 來命名:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> data: { activeColor: 'red', fontSize: 30 }
可是這種寫法並非很好,由於會定義不少數據屬性,因此咱們通常是這麼使用的,綁定一個樣式對象:
<div v-bind:style="styleObject"></div> data: { styleObject: { color: 'red', fontSize: '13px' } }
這樣看起來,像不像咱們把 <style> 中的樣式定義,轉到了 Data 裏,可是好處就是能夠控制變化,這個具體的使用仍是看具體的安排,目前我主要是使用的原來的寫法,靜態的寫到 <style> 裏,可是須要樣式變化的地方,寫到 Data 裏,仍是很爽快的~
在編程的世界其實和現實世界是同樣的,一切皆是對象,都是有生命的,只不過沒有感情而已,就比大到一個機器人,它有生命週期(設計,生產,銷燬,死亡),也有本身的神經網絡,可是若是要是有本身的感情支配的話,嘖嘖,那就是妥妥的一我的呀 [哭笑],小到一個項目的啓動,一個頁面的加載,都是由生命週期,Vue把整個生命週期劃分爲建立、掛載、更新、銷燬等階段,每一個階段都會給一些「鉤子」讓咱們來作一些咱們想實現的動做(這個鉤子叫法很貼切,很形象的表現了每到一個階段會鉤住,並執行相應的操做,而不會跳躍過去)。學習實例的生命週期,能幫助咱們理解vue實例的運做機制,更好地合理利用各個鉤子來完成咱們的業務代碼,不一樣的時期處理不一樣的邏輯,好比 loading 的加載。
其實,在 vue 的整個生命週期內,總共分爲8個階段建立前/後,載入前/後,更新前/後,銷燬前/後。
建立前/後: 在beforeCreated階段,vue實例的掛載元素$el和數據對象data都爲undefined,還未初始化。在created階段,vue實例的數據對象data有了,$el尚未。
載入前/後:在beforeMount階段,vue實例的$el和data都初始化了,但仍是掛載以前爲虛擬的dom節點,data.message還未替換。在mounted階段,vue實例掛載完成,data.message成功渲染。
更新前/後:當data變化時,會觸發beforeUpdate和updated方法。
銷燬前/後:在執行destroy方法後,對data的改變不會再觸發周期函數,說明此時vue實例已經解除了事件監聽以及和dom的綁定,可是dom結構依然存在
咱們分別來看看這幾個階段:
此階段爲實例初始化以後,此時的數據觀察和事件配置都沒好準備好。咱們試着console一下實例的數據data和掛載元素el,代碼以下:
let app = new Vue({ el:"#app", data:{ author: "老張的哲學", }, beforeCreate: function () { console.group('beforeCreate 建立前狀態===============》'); console.log("%c%s", "color:red", "el : " + this.$el); //undefined console.log("%c%s", "color:red", "data : " + this.$data); //undefined console.log("%c%s", "color:red", "author: " + this.author);//undefined
},
});
beforeCreate以後緊接着的鉤子就是建立完畢created,咱們一樣打印一下數據data
和掛載元素el
,看會獲得什麼?
created: function () { console.group('created 建立完畢狀態===============》'); console.log("%c%s", "color:red", "el : " + this.$el); //undefined console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化 console.log("%c%s", "color:red", "author: " + this.author); //已被初始化 },
上一個階段咱們知道DOM還沒生成,屬性el
還爲 undefined,那麼,此階段爲即將掛載,頁面渲染成功,el 已經賦值
beforeMount: function () { console.group('beforeMount 掛載前狀態===============》'); console.log("%c%s", "color:red", "el : " + (this.$el)); //已被初始化 console.log(this.$el); console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化 console.log("%c%s", "color:red", "author: " + this.author); //已被初始化 },
mounted也就是掛載完畢階段,到了這個階段,數據就會被成功渲染出來
mounted: function () { console.group('mounted 掛載結束狀態===============》'); console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化 console.log(this.$el); console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化 console.log("%c%s", "color:red", "author: " + this.author); //已被初始化 },
這個時候,你把鼠標放到右側的 <div> 上,左側頁面就是被選中狀態,說明這個就是咱們渲染出來的頁面,這就是已經掛載成功了。
這個時候,頁面渲染的四個階段已經完成了,咱們看看流程:(剛開始的時候beforeCreate階段,數據和頁面都沒有渲染,可是頁面的靜態數據已經被加載出來,而後一步一步,先vue實例,而後掛載,到最後頁面渲染完成)
當修改vue實例的data時,vue就會自動幫咱們更新渲染視圖,在這個過程當中,vue提供了beforeUpdate的鉤子給咱們,在檢測到咱們要修改數據的時候,更新渲染視圖以前就會觸發鉤子beforeUpdate。
beforeUpdate: function () { console.group('beforeUpdate 更新前狀態===============》'); console.log("%c%s", "color:red", "el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red", "data : " + this.$data); console.log("%c%s", "color:red", "author: " + this.author); debugger;//打斷點 },
注意:這裏要說下,打斷點就是爲了能準確看到這個鉤子起的做用,不受其餘鉤子的影響。
由圖看來,咱們的 Data 數據已經更新了,可是頁面裏尚未更新,那何時更新呢,請往下看。
updated: function () { console.group('updated 更新完成狀態===============》'); console.log("%c%s", "color:red", "el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red", "data : " + this.$data); console.log("%c%s", "color:red", "author: " + this.author); },
調用實例的destroy( )
方法能夠銷燬當前的組件,在銷燬前,會觸發beforeDestroy鉤子。
beforeDestroy: function () { console.group('beforeDestroy 銷燬前狀態===============》'); console.log("%c%s", "color:red", "el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red", "data : " + this.$data); console.log("%c%s", "color:red", "author: " + this.author); },
成功銷燬以後,會觸發 destroyed 鉤子,此時該實例與其餘實例的關聯已經被清除,它與視圖之間也被解綁,控制 Data 已經不能控制頁面,也沒法雙向綁定。
destroyed: function () { console.group('destroyed 銷燬完成狀態===============》'); console.log("%c%s", "color:red", "el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red", "data : " + this.$data); console.log("%c%s", "color:red", "author: " + this.author) },
這個時候咱們能夠看到,vue 實例被銷燬後,再修改 Data 頁面也已經不能修改頁面 DOM 了。
這個時候頁面的生命週期已經完成,一共八個時期,你們能夠多嘗試看看,瞭解過程。
在以前的文章中,咱們已經簡單地介紹了 vue 的兩大特性之一數據驅動,咱們這裏簡單說下另外一個特性 —— 組件。
註冊組件就是利用Vue.component()
方法,先傳入一個自定義組件的名字,而後傳入這個組件的配置。咱們以前說過,在 Vue 中,只有一個初始頁面,而後其餘的都是經過路由將各個不一樣的組件聯繫在一塊兒,大體以下圖:
// 定義一個名爲 footer-vue 的新組件 Vue.component('footer-vue', { template: ` <div id="footer-vue"> <p>2018 <a href="#">LZ's Blog</a> - Hosted by <a href="#" style="font-weight: bold">Coding Pages</a></p> <p> <a href="#">京ICP備00000000號</a> </p> </div> ` })
還記得如何定義一個模板麼,用反引號 ``,包裹。
<div id="app"> <div>.......</div> <footer-vue></footer-vue> <div class="layout-bg"></div> </div> <script> new Vue({ el: '#app' }) </script>
今天呢,暫時就說下如何定義一個組件,明天我們再深刻了解下組件。
今天呢,我們就說到這裏啦,經過動態 class 和 style 綁定,我們瞭解到能夠像經過操做Data來綁定頁面元素同樣的,操做頁面的全部樣式;經過簡單瞭解 Vue 的生命週期的八個階段,能夠在以後的開發中,針對不一樣的階段採起不一樣的操做,最後簡單說了下如何定義並使用一個 全局組件,那如何定義一個局部組件、如何更好的實現複用組件、父子組件之間又是如何通訊、又是如何統一管理組件系統的,我們明天再見吧~~~