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的引用,知識點也比較簡單,我講解的也比較全面,下一篇博客我會帶大家詳細介紹組件的使用。


免責聲明!

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



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