回顧
哈嘍大家好,前后端分離系列文章又開始了,今天周一,還是感謝大家花時間來觀看我寫的博客,周末呢,沒有寫文章,但是也沒有閑着,主要是研究了下遺留問題,看過之前文章的應該知道,之前的在AOP使用Redis緩存的文章里,遺留了一個問題,周末苦思冥想還是不得其法,想了一個餿主意,但是肯定不是最終解決方案,感興趣的可以看看,地址《框架之十一 || AOP自定義篩選,Redis入門 11.1》,然后呢,剩下的時間,就是簡單搭建了下我在以后的Vue實戰中用到的一個小項目,我會手把手在一戶的文章中講到,但是還在搭建中,預計下周可以接觸到,因為Vue是重新開始的,所以在基礎這一塊兒說的比較多,主要也是希望都能好好學習下,也是希望能檢查下去,看博客園粉絲破百的時候,能不能有啥小福利啥的哈哈哈
言歸正傳,上文咱們說到了vue基礎的第二章 指令和計算屬性,因為時間的問題,上次沒有說到Class 與 Style 綁定,那今天咱們就簡單說說這個綁定樣式問題,然后重點說一下 Vue的生命周期,我感覺這個還是比較重要的,因為任何一個Web程序,生命周期都是重中之重,老生常談的一個話題,今天咱們也說說。然后如果有時間,可以簡單說下Vue的兩大核心之組件(另一個大家應該也還記得,就是數據驅動,雙向數據綁定,就是不用操作DOM的那個,嗯~),好啦,開始今天的講解吧!
零、今天完成右下角橙色的部分
一、動態綁定class和style
之前咱們都已經了解到了,Vue是通過Data來控制DOM的,這樣可以減少太多的JS操作,從而達到頁面的無縫快速渲染的作用,這是一個很好的想法,我們可以想一下,頁面內,除了各種標簽的DOM需要操作修改以外,還有哪些因素呢,不過,你應該已經想到了,就是樣式!頁面的三大元素:HTML+CSS+JS。我們也可以使用相同的辦法,通過操作Data來控制樣式!對,Vue的設計者們也考慮到了這個問題,所以就出來了動態綁定class和style。操作元素的 class 列表和內聯樣式是數據綁定的一個常見需求。因為它們都是屬性,所以我們可以用
v-bind
處理它們:只需要通過表達式計算出字符串結果即可。不過,字符串拼接麻煩且易錯。因此,在將v-bind
用於class
和style
時,Vue.js 做了專門的增強。表達式結果的類型除了字符串之外,還可以是對象或數組。
1、通過對象的方式動態修改頁面內的 class,來實現刪除效果
還記得當時我們給 a 標簽是如何添加 src 的?對,就是 v-bind ,它就是用來統一操作頁面內各種屬性的,所以我們要修改 class 和 style 也得使用到 v-bind ,這里我們統一使用他們的縮寫 ( :),
在我們的博客首頁 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。
我們可以看一看結果:
2、通過數組的方式動態修改頁面內的 class,主要的多個樣式的時候
我們可以把一個數組傳給 v-bind:class
,以應用一個 class 列表:
<h2 :class="[hrClass,testClass]"> <span>Contact</span> </h2> data: { hrClass: 'hr', testClass:'test', }
運行出來的結果就是醬紫的:
因此可以看得出來,數組中的值是我們的 Data 屬性值,通過渲染,加載出我們對應的真是 class 值,這個在動態多個綁定的時候,還是很有用的。
3、綁定內聯樣式style
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把整個生命周期划分為創建、掛載、更新、銷毀等階段,每個階段都會給一些“鈎子”讓我們來做一些我們想實現的動作(這個鈎子叫法很貼切,很形象的表現了每到一個階段會鈎住,並執行相應的操作,而不會跳躍過去)。學習實例的生命周期,能幫助我們理解vue實例的運作機制,更好地合理利用各個鈎子來完成我們的業務代碼,不同的時期處理不同的邏輯,比如 loading 的加載。
0、首先我們看一下這個經常出現的圖片,其實簡單看一下,也就大概明白了
其實,在 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結構依然存在
我們分別來看看這幾個階段:
1、beforeCreate —— 創建之前
此階段為實例初始化之后,此時的數據觀察和事件配置都沒好准備好。我們試着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
},
});
2、created —— 創建完成
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); //已被初始化 },
3、beforeMount —— 准備掛載( 掛載成功才能去渲染頁面 )
上一個階段我們知道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); //已被初始化 },
4、mounted —— 掛載完畢,頁面渲染完成
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實例,然后掛載,到最后頁面渲染完成)
5、beforeUpdate —— 更新前(修改Data,但未渲染至頁面)
當修改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 數據已經更新了,但是頁面里還沒有更新,那什么時候更新呢,請往下看。
6、updated —— 更新數據,頁面渲染
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); },
7、beforeDestroy —— 頁面銷毀前
調用實例的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); },
8、destroyed —— 銷毀完成
成功銷毀之后,會觸發 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 的兩大特性之一數據驅動,我們這里簡單說下另一個特性 —— 組件。
注冊組件就是利用Vue.component()
方法,先傳入一個自定義組件的名字,然后傳入這個組件的配置。我們之前說過,在 Vue 中,只有一個初始頁面,然后其他的都是通過路由將各個不同的組件聯系在一起,大致如下圖:
1、這里簡單說下如何定義一個組件,這里我們定義一個頁腳組件( 注意:一定要寫在 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> ` })
還記得如何定義一個模板么,用反引號 ``,包裹。
2、然后在 Vue 定義的元素內的任何一個地方,使用頁腳組件
<div id="app"> <div>.......</div> <footer-vue></footer-vue> <div class="layout-bg"></div> </div> <script> new Vue({ el: '#app' }) </script>
3、這時候就可以看到頁面效果了
今天呢,暫時就說下如何定義一個組件,明天咱們再深入了解下組件。
四、結語
今天呢,咱們就說到這里啦,通過動態 class 和 style 綁定,咱們了解到可以像通過操作Data來綁定頁面元素一樣的,操作頁面的所有樣式;通過簡單了解 Vue 的生命周期的八個階段,可以在之后的開發中,針對不同的階段采取不同的操作,最后簡單說了下如何定義並使用一個 全局組件,那如何定義一個局部組件、如何更好的實現復用組件、父子組件之間又是如何通信、又是如何統一管理組件系統的,咱們明天再見吧~~~