回顧
哈嘍大家好出牧,前后端分離系列文章又開始了穴肘,今天周一,還是感謝大家花時(shí)間來觀看我寫的博客舔痕,周末呢旺遮,沒有寫文章盈咳,但是也沒有閑著耿眉,主要是研究了下遺留問題鱼响,看過之前文章的應(yīng)該知道鸣剪,之前的在AOP使用Redis緩存的文章里丈积,遺留了一個(gè)問題,周末苦思冥想還是不得其法江滨,想了一個(gè)餿主意铛纬,但是肯定不是最終解決方案唬滑,感興趣的可以看看,地址《框架之十一 || AOP自定義篩選晶密,Redis入門 11.1》,然后呢稻艰,剩下的時(shí)間,就是簡單搭建了下我在以后的Vue實(shí)戰(zhàn)中用到的一個(gè)小項(xiàng)目尊勿,我會手把手在一戶的文章中講到,但是還在搭建中元扔,預(yù)計(jì)下周可以接觸到,因?yàn)閂ue是重新開始的摇展,所以在基礎(chǔ)這一塊兒說的比較多,主要也是希望都能好好學(xué)習(xí)下咏连,也是希望能檢查下去盯孙,看博客園粉絲破百的時(shí)候祟滴,能不能有啥小福利啥的哈哈哈
言歸正傳,上文咱們說到了vue基礎(chǔ)的第二章 指令和計(jì)算屬性垄懂,因?yàn)闀r(shí)間的問題痛垛,上次沒有說到Class 與 Style 綁定,那今天咱們就簡單說說這個(gè)綁定樣式問題匙头,然后重點(diǎn)說一下 Vue的生命周期,我感覺這個(gè)還是比較重要的蹂析,因?yàn)槿魏我粋€(gè)Web程序,生命周期都是重中之重碟婆,老生常談的一個(gè)話題,今天咱們也說說竖共。然后如果有時(shí)間,可以簡單說下Vue的兩大核心之組件(另一個(gè)大家應(yīng)該也還記得公给,就是數(shù)據(jù)驅(qū)動,雙向數(shù)據(jù)綁定妓布,就是不用操作DOM的那個(gè)宋梧,嗯~),好啦捂龄,開始今天的講解吧!
零倦沧、今天完成右下角橙色的部分
一、動態(tài)綁定class和style
之前咱們都已經(jīng)了解到了展融,Vue是通過Data來控制DOM的,這樣可以減少太多的JS操作告希,從而達(dá)到頁面的無縫快速渲染的作用扑浸,這是一個(gè)很好的想法燕偶,我們可以想一下,頁面內(nèi)指么,除了各種標(biāo)簽的DOM需要操作修改以外榴鼎,還有哪些因素呢,不過巫财,你應(yīng)該已經(jīng)想到了,就是樣式翁涤!頁面的三大元素:HTML+CSS+JS。我們也可以使用相同的辦法葵礼,通過操作Data來控制樣式!對鸳粉,Vue的設(shè)計(jì)者們也考慮到了這個(gè)問題,所以就出來了動態(tài)綁定class和style园担。操作元素的 class 列表和內(nèi)聯(lián)樣式是數(shù)據(jù)綁定的一個(gè)常見需求。因?yàn)樗鼈兌际菍傩酝涮晕覀兛梢杂?
v-bind
處理它們:只需要通過表達(dá)式計(jì)算出字符串結(jié)果即可。不過咏闪,字符串拼接麻煩且易錯(cuò)。因此鸽嫂,在將v-bind
用于class
和style
時(shí),Vue.js 做了專門的增強(qiáng)据某。表達(dá)式結(jié)果的類型除了字符串之外,還可以是對象或數(shù)組癣籽。
1、通過對象的方式動態(tài)修改頁面內(nèi)的 class筷狼,來實(shí)現(xiàn)刪除效果
還記得當(dāng)時(shí)我們給 a 標(biāo)簽是如何添加 src 的?對桑逝,就是 v-bind ,它就是用來統(tǒng)一操作頁面內(nèi)各種屬性的楞遏,所以我們要修改 class 和 style 也得使用到 v-bind 首昔,這里我們統(tǒng)一使用他們的縮寫 ( :),
在我們的博客首頁 DEMO 中勒奇,我們都是通過這樣的方法定義一個(gè) class
<li v-for='item in listSearch' class="post-list-item">
現(xiàn)在我們需要實(shí)現(xiàn)一個(gè)刪除效果,那就需要給文章列表 list 赊颠,動態(tài)的增加一個(gè) deleted 的 class ,
<!--注意竣蹦,不能在已經(jīng)存在的靜態(tài)類post-list-item上操作-->
<li v-for='item in listSearch' class="post-list-item" :class="{ deleted: item.deleted}">
var vm = new Vue({
el: '#app',//容器
data: {
author: "老張的哲學(xué)",
task: {
name: '',//內(nèi)容為空
id: 100,
date: " Just Now ",
finished: false,
deleted: false },
list: [ //假數(shù)據(jù)
{ name: " Vue前篇:ES6初體驗(yàn) & 模塊化編程", id: 9585766, date: "2018年9月5日", finished: false, **deleted: true** },//我們在這里定義一個(gè)刪除的true
{ name: "Vue前篇:JS對象&字面量&this", id: 9580807, date: "2018年9月4日", finished: false, deleted: false },
{ name: " VUE 計(jì)劃書 & 我的前后端開發(fā)簡史", id: 9577805, date: "2018年9月3日", finished: false, deleted: false },
{ name: " DTOs 對象映射使用,項(xiàng)目部署Windows+Linux完整版", id: 3800, date: "2018年9月1日", finished: false, deleted: false },
{ name: " 三種跨域方式比較痘括,DTOs(數(shù)據(jù)傳輸對象)初探", id: 4200, date: "2018年8月31日", finished: false, deleted: false },
{ name: "VUE 計(jì)劃書 & 我的前后端開發(fā)簡史", id: 3200, date: "2018年9月2日", finished: false, deleted: false },
{ name: "VUE 實(shí)戰(zhàn)預(yù)告", id: 3200, date: "2018年9月12日", finished: false, deleted: false }
],
},
}
}); <!-- 樣式 -->
<style> .deleted {
color: red;
text-decoration: line-through;
} </style>
從代碼中我們可看到 :class="{ deleted: item.deleted}"滔吠,這是一個(gè)通過對象定義樣式纲菌,第一個(gè) deleted 疮绷,就是我們的樣式 class 翰舌,第二個(gè)就是對應(yīng)我們的 數(shù)據(jù)屬性冬骚。deleted 這個(gè) class 存在與否將取決于數(shù)據(jù)屬性 list 中的 item.deleted 是否為 true,如果為 false唉韭,那么這個(gè) class 就不會顯示犯犁,這就達(dá)到了一個(gè)動態(tài)的效果属愤,當(dāng)然酸役,你也可以在對象中傳入更多屬性來動態(tài)切換多個(gè) class。
我們可以看一看結(jié)果:
2涣澡、通過數(shù)組的方式動態(tài)修改頁面內(nèi)的 class,主要的多個(gè)樣式的時(shí)候
我們可以把一個(gè)數(shù)組傳給 v-bind:class
入桂,以應(yīng)用一個(gè) class 列表:
<h2 :class="[hrClass,testClass]">
<span>Contact</span>
</h2> data: {
hrClass: 'hr',
testClass:'test',
}
運(yùn)行出來的結(jié)果就是醬紫的:
因此可以看得出來,數(shù)組中的值是我們的 Data 屬性值抗愁,通過渲染呵晚,加載出我們對應(yīng)的真是 class 值,這個(gè)在動態(tài)多個(gè)綁定的時(shí)候饵隙,還是很有用的。
3沮脖、綁定內(nèi)聯(lián)樣式style
v-bind:style
的對象語法十分直觀——看著非常像 CSS,但其實(shí)是一個(gè) JavaScript 對象勺届。CSS 屬性名可以用駝峰式 (camelCase) 或短橫線分隔 (kebab-case,記得用單引號括起來) 來命名:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> data: {
activeColor: 'red',
fontSize: 30 }
但是這種寫法并不是很好免姿,因?yàn)闀x很多數(shù)據(jù)屬性,所以我們一般是這么使用的养泡,綁定一個(gè)樣式對象:
<div v-bind:style="styleObject"></div> data: {
styleObject: {
color: 'red',
fontSize: '13px' }
}
這樣看起來,像不像我們把 <style> 中的樣式定義澜掩,轉(zhuǎn)到了 Data 里,但是好處就是可以控制變化肩榕,這個(gè)具體的使用還是看具體的安排,目前我主要是使用的原來的寫法株汉,靜態(tài)的寫到 <style> 里,但是需要樣式變化的地方乔妈,寫到 Data 里,還是很爽快的~
二路召、探究 Vue 實(shí)例的生命周期
在編程的世界其實(shí)和現(xiàn)實(shí)世界是一樣的,一切皆是對象股淡,都是有生命的,只不過沒有感情而已唯灵,就比大到一個(gè)機(jī)器人贾铝,它有生命周期(設(shè)計(jì),生產(chǎn)垢揩,銷毀,死亡)水孩,也有自己的神經(jīng)網(wǎng)絡(luò),但是如果要是有自己的感情支配的話俘种,嘖嘖,那就是妥妥的一個(gè)人呀 [哭笑]宙刘,小到一個(gè)項(xiàng)目的啟動,一個(gè)頁面的加載悬包,都是由生命周期,Vue把整個(gè)生命周期劃分為創(chuàng)建布近、掛載、更新撑瞧、銷毀等階段,每個(gè)階段都會給一些“鉤子”讓我們來做一些我們想實(shí)現(xiàn)的動作(這個(gè)鉤子叫法很貼切预伺,很形象的表現(xiàn)了每到一個(gè)階段會鉤住订咸,并執(zhí)行相應(yīng)的操作酬诀,而不會跳躍過去)。學(xué)習(xí)實(shí)例的生命周期瞒御,能幫助我們理解vue實(shí)例的運(yùn)作機(jī)制,更好地合理利用各個(gè)鉤子來完成我們的業(yè)務(wù)代碼葵腹,不同的時(shí)期處理不同的邏輯屿岂,比如 loading 的加載践宴。
0爷怀、首先我們看一下這個(gè)經(jīng)常出現(xiàn)的圖片阻肩,其實(shí)簡單看一下,也就大概明白了
其實(shí)烤惊,在 vue 的整個(gè)生命周期內(nèi),總共分為8個(gè)階段創(chuàng)建前/后柒室,載入前/后,更新前/后雄右,銷毀前/后。
創(chuàng)建前/后: 在beforeCreated階段擂仍,vue實(shí)例的掛載元素
el還沒有。
載入前/后:在beforeMount階段盲赊,vue實(shí)例的$el和data都初始化了,但還是掛載之前為虛擬的dom節(jié)點(diǎn)角钩,data.message還未替換。在mounted階段递礼,vue實(shí)例掛載完成,data.message成功渲染脊髓。
更新前/后:當(dāng)data變化時(shí)辫愉,會觸發(fā)beforeUpdate和updated方法将硝。
銷毀前/后:在執(zhí)行destroy方法后,對data的改變不會再觸發(fā)周期函數(shù)依疼,說明此時(shí)vue實(shí)例已經(jīng)解除了事件監(jiān)聽以及和dom的綁定,但是dom結(jié)構(gòu)依然存在
我們分別來看看這幾個(gè)階段:
1律罢、beforeCreate —— 創(chuàng)建之前
此階段為實(shí)例初始化之后,此時(shí)的數(shù)據(jù)觀察和事件配置都沒好準(zhǔn)備好。我們試著console一下實(shí)例的數(shù)據(jù)data和掛載元素el沧踏,代碼如下:
let app = new Vue({
el:"#app",
data:{
author: "老張的哲學(xué)",
},
beforeCreate: function () {
console.group('beforeCreate 創(chuàng)建前狀態(tài)===============》');
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 —— 創(chuàng)建完成
beforeCreate之后緊接著的鉤子就是創(chuàng)建完畢created翘狱,我們同樣打印一下數(shù)據(jù)data
和掛載元素el
,看會得到什么潦匈?
created: function () {
console.group('created 創(chuàng)建完畢狀態(tài)===============》');
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 —— 準(zhǔn)備掛載( 掛載成功才能去渲染頁面 )
上一個(gè)階段我們知道DOM還沒生成历等,屬性el
還為 undefined,那么寒屯,此階段為即將掛載,頁面渲染成功寡夹,el 已經(jīng)賦值
beforeMount: function () {
console.group('beforeMount 掛載前狀態(tài)===============》');
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也就是掛載完畢階段,到了這個(gè)階段智绸,數(shù)據(jù)就會被成功渲染出來
mounted: function () {
console.group('mounted 掛載結(jié)束狀態(tài)===============》');
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); //已被初始化
},
這個(gè)時(shí)候,你把鼠標(biāo)放到右側(cè)的 <div> 上瞧栗,左側(cè)頁面就是被選中狀態(tài),說明這個(gè)就是我們渲染出來的頁面迹恐,這就是已經(jīng)掛載成功了。
這個(gè)時(shí)候殴边,頁面渲染的四個(gè)階段已經(jīng)完成了,我們看看流程:(剛開始的時(shí)候beforeCreate階段锤岸,數(shù)據(jù)和頁面都沒有渲染,但是頁面的靜態(tài)數(shù)據(jù)已經(jīng)被加載出來能耻,然后一步一步亡驰,先vue實(shí)例晓猛,然后掛載,到最后頁面渲染完成)
5戒职、beforeUpdate —— 更新前(修改Data,但未渲染至頁面)
當(dāng)修改vue實(shí)例的data時(shí)洪燥,vue就會自動幫我們更新渲染視圖,在這個(gè)過程中捧韵,vue提供了beforeUpdate的鉤子給我們市咆,在檢測到我們要修改數(shù)據(jù)的時(shí)候再来,更新渲染視圖之前就會觸發(fā)鉤子beforeUpdate。
beforeUpdate: function () {
console.group('beforeUpdate 更新前狀態(tài)===============》');
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;//打斷點(diǎn)
}
注意:這里要說下桨吊,打斷點(diǎn)就是為了能準(zhǔn)確看到這個(gè)鉤子起的作用,不受其他鉤子的影響针炉。
由圖看來,我們的 Data 數(shù)據(jù)已經(jīng)更新了篡帕,但是頁面里還沒有更新,那什么時(shí)候更新呢镰烧,請往下看。
6拌滋、updated —— 更新數(shù)據(jù),頁面渲染
updated: function () {
console.group('updated 更新完成狀態(tài)===============》');
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 —— 頁面銷毀前
調(diào)用實(shí)例的destroy( )
方法可以銷毀當(dāng)前的組件,在銷毀前昌犹,會觸發(fā)beforeDestroy鉤子。
beforeDestroy: function () {
console.group('beforeDestroy 銷毀前狀態(tài)===============》');
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 —— 銷毀完成
成功銷毀之后沧竟,會觸發(fā) destroyed 鉤子,此時(shí)該實(shí)例與其他實(shí)例的關(guān)聯(lián)已經(jīng)被清除缚忧,它與視圖之間也被解綁,控制 Data 已經(jīng)不能控制頁面闪水,也無法雙向綁定。
destroyed: function () {
console.group('destroyed 銷毀完成狀態(tài)===============》');
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)
},
這個(gè)時(shí)候我們可以看到球榆,vue 實(shí)例被銷毀后,再修改 Data 頁面也已經(jīng)不能修改頁面 DOM 了持钉。
這個(gè)時(shí)候頁面的生命周期已經(jīng)完成,一共八個(gè)時(shí)期每强,大家可以多嘗試看看,了解過程舀射。
三、Vue 核心之 組件初探
在之前的文章中脆烟,我們已經(jīng)簡單地介紹了 vue 的兩大特性之一數(shù)據(jù)驅(qū)動山林,我們這里簡單說下另一個(gè)特性 —— 組件邢羔。
注冊組件就是利用Vue.component()
方法,先傳入一個(gè)自定義組件的名字拜鹤,然后傳入這個(gè)組件的配置框冀。我們之前說過敏簿,在 Vue 中,只有一個(gè)初始頁面惯裕,然后其他的都是通過路由將各個(gè)不同的組件聯(lián)系在一起温数,大致如下圖:
1蜻势、這里簡單說下如何定義一個(gè)組件,這里我們定義一個(gè)頁腳組件(** 注意**:一定要寫在 Vue 實(shí)例之前 )
// 定義一個(gè)名為 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> `
})
還記得如何定義一個(gè)模板么握玛,用反引號 ``甫菠,包裹。
2冕屯、然后在 Vue 定義的元素內(nèi)的任何一個(gè)地方,使用頁腳組件
<div id="app">
<div>.......</div>
<footer-vue></footer-vue>
<div class="layout-bg"></div>
</div>
<script>
new Vue({
el: '#app' }) </script>
3愕撰、這時(shí)候就可以看到頁面效果了
今天呢醋寝,暫時(shí)就說下如何定義一個(gè)組件,明天咱們再深入了解下組件音羞。
四囱桨、結(jié)語
今天呢嗅绰,咱們就說到這里啦,通過動態(tài) class 和 style 綁定窘面,咱們了解到可以像通過操作Data來綁定頁面元素一樣的翠语,操作頁面的所有樣式财边;通過簡單了解 Vue 的生命周期的八個(gè)階段肌括,可以在之后的開發(fā)中酣难,針對不同的階段采取不同的操作,最后簡單說了下如何定義并使用一個(gè) 全局組件憨募,那如何定義一個(gè)局部組件紧索、如何更好的實(shí)現(xiàn)復(fù)用組件菜谣、父子組件之間又是如何通信、又是如何統(tǒng)一管理組件系統(tǒng)的尾膊,咱們明天再見吧~~~
五媳危、CODE
https://github.com/anjoy8/Blog.Vue
QQ群:
867095512 (blod.core)