vue學習筆記(七)元件
前言
在前面vue的一些部落格中,我們幾乎將vue的基礎差不多學習完了,而從本篇部落格開始將會進入到vue的另一個階段性學習,本篇部落格的內容在以後的vue專案中佔很大的比重,所以小夥伴們需要認真學習,本篇部落格的內容也比較簡單,看過我部落格的人都知道我所寫的每一篇部落格都是非常的詳細的,所以大家不要擔心學不會。我會盡量將所學的知識講解的通俗易懂,讓大家學習起來更加快樂,那麼一起來看看吧!
本章目標
- 學會使用全域性元件和區域性元件
- 學會ref引用
初識元件
解釋:元件系統是 Vue 的另一個重要概念,因為它是一種抽象,允許我們使用小型、獨立和通常可複用的元件構建大型應用。仔細想想,幾乎任意型別的應用介面都可以抽象為一個元件樹
元件通常可以用來製作單頁應用程式(SPA)
元件的話我們主要分為兩類,一種是區域性元件,一種是全域性元件,接下來我會介紹這兩種元件
全域性元件
全域性元件毫無疑問,肯定是很多地方都可以訪問的了,
語法:
Vue.component('元件名',{
template:'模板'
})
這是最簡單定義全域性元件的語法,接下來帶大家簡單入門一下全域性元件
(1)全域性元件註冊方式一
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>全域性元件註冊方式一</title> </head> <body> <div id="app"> <t1></t1> </div> <div id="demo"> <t1></t1> </div> <script type="text/template" id="template1"> <div>這是一個元件</div> </script> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> Vue.component('t1',{ template:'#template1' }) let vm=new Vue({ el:'#app' }) let d=new Vue({ el:'#demo' }) </script> </body> </html>
首先我們使用script標籤來定義模板然後將模板在元件中註冊,在這裡我們定義了兩個vue例項,發現在demo和app中都可以使用,證明全域性元件註冊成功了,這是定義元件的第一種方法,接下來我們學習第二種
(2)全域性元件註冊方式二
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <temp></temp> </div> <template id="template1"> <div>這是一個元件</div> </template> <div id="demo"> <temp></temp> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> Vue.component('temp',{ template:'#template1' }) let vm=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ } }) let app=new Vue({ el:'#demo' }) </script> </body> </html>
第二種方法我們直接使用vue提供的template標籤定義模板然後再元件中註冊就可以了,
(3)全域性元件註冊方式三
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <my-compent></my-compent> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> Vue.component('myCompent',{ template:'<div>這是第三種定義元件的方法</div>' }) let vm=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ } }) </script> </body> </html>
這是第三種定義全域性元件的方法,三種方法中都可以使用,主要看個人習慣,反正我是比較喜歡第三種,全域性元件註冊講到這裡就結束了,接下來主要講解區域性元件祖冊。
區域性元件
區域性元件的話當然是定義在vue例項裡面定義的了,區域性元件只在當前vue例項中有效
(1)區域性元件註冊
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>區域性元件註冊</title> </head> <body> <div id="app"> <hello></hello> <!--<hi></hi>--> </div> <div id="demo"> <hi></hi> <!--<hello></hello>--> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm1=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ }, components:{ 'hello':{ template:'<div>我叫hello,你叫什麼</div>' } } }) let vm2=new Vue({ el:'#demo', components:{ 'hi':{ template:'<div>我叫hi,你叫什麼</div>' } } }) </script> </body> </html>
結果的話我就不貼出來了,大家可以嘗試一下,如果我們在app中使用hi元件或者在demo中使用hello元件的話,vue將會給出警告的,因為我們註冊的是區域性元件,所以無法使用。
ref引用
在介紹ref引用之前,我想帶大家實現一個小demo,需求是這樣的,頁面上共有四個按鈕分別為紅,黃,綠,藍,當我們點選某個按鈕的時候就顯示對應的顏色,如下圖所示
當我們點選紅色的時候,顯示紅色,依次類推,那就由我帶大家實現這個小demo吧!當然還是應用元件的知識,畢竟趁熱打鐵
(1)新增元件佈局
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref引用</title> <style type="text/css"> .box{ width: 200px; height: 200px; border: 2px solid black; margin-top: 10px; } </style> </head> <body> <div id="app"> <color-template></color-template> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ }, components:{ colorTemplate:{ data(){ return{ colorArray:['red','yellow','green','blue'] } }, template:`<div class="btn_group"> <button v-for="color in colorArray" :style="{background:color}">{{color}}</button> <div class="box"></div> </div>`, } } }) </script> </body> </html>
效果
在這裡我們定義了局部元件,然後在區域性元件中返回了顏色對應的陣列,渲染的時候將顏色渲染到對應的按鈕上,並且為每個按鈕繫結對應的背景顏色。
(2)繫結事件
接下來我們為每一個按鈕新增事件,然後點選的時候獲取對應的顏色,我們在事件中傳入對應的顏色值名稱就可以
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref引用</title> <style type="text/css"> .box{ width: 200px; height: 200px; border: 2px solid black; margin-top: 10px; } </style> </head> <body> <div id="app"> <color-template></color-template> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ }, components:{ colorTemplate:{ data(){ return{ colorArray:['red','yellow','green','blue'] } }, template:`<div class="btn_group"> <button v-for="color in colorArray" :style="{background:color}" @click="handleClick(color)">{{color}}</button> <div class="box"></div> </div>`, methods:{ handleClick(color){ console.log(color); } } } } }) </script> </body> </html>
結果
當我們依次點選對應的按鈕的時候,對應顏色的值已經取到了,當然我們現在已經實現這個功能了,但是為了鞏固一下以前的知識,我也會教大家使用另一種方法來獲取就是下文提到的dataset的使用。
(3)dataset的使用
在html5中新增了data-xx的屬性,我們知道data-xx可以用來存資料所以我們也可以將對應的顏色儲存在data-xx中,然後通過dataset獲取
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref引用</title> <style type="text/css"> .box{ width: 200px; height: 200px; border: 2px solid black; margin-top: 10px; } </style> </head> <body> <div id="app"> <color-template></color-template> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ }, components:{ colorTemplate:{ data(){ return{ colorArray:['red','yellow','green','blue'] } }, template:`<div class="btn_group"> <button v-for="color in colorArray" :style="{background:color}" @click="handleClick" :data-color="color">{{color}}</button> <div class="box"></div> </div>`, methods:{ handleClick(e){ const color=e.target.dataset.color; console.log(color); } } } } }) </script> </body> </html>
使用這種方法也可以實現依次點選,獲取對應顏色的值,結果的話和上面的結果一樣,在這裡我就不截圖了
(4)實現效果
獲取到對應的顏色之後我們就要實現如上的效果,現在就必須用到ref的引用了
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref引用</title> <style type="text/css"> .box{ width: 200px; height: 200px; border: 2px solid black; margin-top: 10px; } </style> </head> <body> <div id="app"> <color-template></color-template> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ }, computed:{ }, components:{ colorTemplate:{ data(){ return{ colorArray:['red','yellow','green','blue'] } }, template:`<div class="btn_group"> <button v-for="color in colorArray" :style="{background:color}" @click="handleClick(color)" :data-color="color">{{color}}</button> <div class="box" ref="squareBox"></div> </div>`, methods:{ handleClick(color){ const box=this.$refs.squareBox; box.style.backgroundColor=color; } } } } }) </script> </body> </html>
效果
效果的話我們已經實現了,但是我們還是不知道什麼是ref,彆著急,且聽我一一道來
我們知道javascript操作dom是非常消耗效能的,因此在vue中提供了ref來獲取相應的dom元素獲取方法是this.$refs獲取的是所有含有ref引用的dom元素,主要分為四種,如下例項。
(1)單獨繫結
單獨繫結的話,主要就是獲取相應的dom元素,就像原生的javascript獲取元素一樣或者是jQuery中的$獲取元素一樣,看下例項就知道了,
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref單獨繫結</title> </head> <body> <div id="app"> <div ref="square_box" class="box"></div> <button @click="handleClick">獲取元素</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ handleClick(){ var dom=document.getElementsByClassName('box')[0]; console.log(this.$refs.square_box); console.log(dom); } }, computed:{ } }) </script> </body> </html>
在這個例項中,我們使用了兩種方法來獲取dom元素,一種是使用ref來獲取,另一種使用原生的javascript來獲取,可以看到兩種方法都獲取到了dom元素
結果:
(2)繫結重複的元素
在javascript中,我們獲取相同的節點是通過document.getElementsByClassName('節點名稱')或者document.getElementByName('節點名稱'),但是jQuery中使用$來獲取的,返回的是一個數組,但是ref繫結多個相同的元素之後,後面繫結的會覆蓋前面繫結的,這就是ref繫結元素神奇的一方面。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref繫結重複的元素</title> </head> <body> <div id="app"> <div class="box" ref="v_box"></div> <div class="box" ref="v_box"></div> <button @click="hanldeClick">獲取元素</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ hanldeClick(){ var doms=document.getElementsByClassName('box'); console.log(doms); console.log(this.$refs.v_box); } }, computed:{ } }) </script> </body> </html>
在這個示例中,我們同樣使用上面的兩種方法來獲取元素,這樣一對比結果就出來了,使用ref獲取的元素只用一個,就是最後面寫的會覆蓋前面寫的,總之無論有多個重複的元素使用ref總是會返回最後一個結果。
結果:
(3)v-for中ref實現的效果
如果在實際專案中真的有這個需求,需要繫結多個相同的元素呢?很簡單使用v-for就可以了。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>v-for中ref實現的效果</title> </head> <body> <div id="app"> <template v-for="index of 10"> <div class="box" ref="f_box"></div> </template> <button @click="handleClick">獲取元素</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ handleClick(){ console.log(this.$refs.f_box); let doms=document.getElementsByClassName('box'); console.log(doms); } }, computed:{ } }) </script> </body> </html>
同樣還是使用兩種方法來獲取節點,現在的話,我們發現使用ref在v-for迴圈中獲取的dom元素是一個數組(集合),原生的javascript還是沒有變和之前的一樣
(4)繫結元件
ref強大之處不僅僅表現在前三個方面,它還可以繫結元件呢?繫結元件返回的是元件例項(元件的應用是元件的例項物件),這個也可以說是還有一點用處,這也是ref最後需要介紹的一項。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>ref繫結元件</title> </head> <body> <div id="app"> <hello ref="hello"></hello> <button @click="handleClick">獲取元素</button> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', data:{ }, methods:{ handleClick(){ console.log(this.$refs.hello); } }, computed:{ }, components:{ 'hello':{ 'template':'<div>你好</div>', } } }) </script> </body> </html>
結果:
可以看到ref繫結元件返回元件例項,ref的使用到這裡我就已經講解完了,總體來說ref還是比較簡單的
總結
本篇部落格我們主要學習了兩個知識點,一個是認識元件(全域性元件註冊和區域性元件註冊),第二個是$ref的引用,知識點也比較簡單,我講解的也比較全面,下一篇部落格我會帶大家詳細介紹元件的使