從壹開始前后端分離 [ Vue2.0+.NET Core2.1] 十九║Vue基礎: 樣式動態綁定+生命周期


回顧

 哈嘍大家好,前后端分離系列文章又開始了,今天周一,還是感謝大家花時間來觀看我寫的博客,周末呢,沒有寫文章,但是也沒有閑着,主要是研究了下遺留問題,看過之前文章的應該知道,之前的在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 的生命周期的八個階段,可以在之后的開發中,針對不同的階段采取不同的操作,最后簡單說了下如何定義並使用一個 全局組件,那如何定義一個局部組件、如何更好的實現復用組件、父子組件之間又是如何通信、又是如何統一管理組件系統的,咱們明天再見吧~~~

 

五、CODE

https://github.com/anjoy8/Blog.Vue/tree/master/Demo/Vue_17


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM