09、掌握Vue的另一個(gè)核心:組件

實(shí)現(xiàn)組件



我們用傳統(tǒng)的實(shí)現(xiàn)方式實(shí)現(xiàn)一個(gè)組件,html 代碼如下:

 <div class="unit">
    <div class="content">
        <h1>這里是文章的標(biāo)題</h1>
        <div class="info">
            <span>2017年4月10日</span>
            <span class="original">原創(chuàng)</span>
        </div>
    </div>
    <img src="../img/cover.jpg" alt="">
 </div>

效果圖如下:


效果圖.png

在 vue 組件中,這些代碼將作為我們組件的模板 template。
接下來我們看看 vue 是如何實(shí)現(xiàn)一個(gè)組件的。
首先,我們還是先創(chuàng)建一個(gè) vue 實(shí)例。

 <div id="app"></div>
 <script>
    let vm = new Vue({
       el:"#app",
    });
 </script>

成功創(chuàng)建了一個(gè) vue 實(shí)例 vm,掛載元素是 id 為 app 的 div 節(jié)點(diǎn)。
接下來,我們?cè)趧?chuàng)建實(shí)例 vm 之前,利用 vue 提供的 API 來注冊(cè)一個(gè)組件。稍微修改一下上面的代碼:

 <div id="app"></div>
 <script>
    Vue.component('my-article',{
       template:`<div>
                <div>
                <h1>這里是文章的標(biāo)題</h1>
                <div>
                <span>2017年4月10日</span>
                <span>原創(chuàng)</span>
                </div>
                </div>
                <img src="../img/cover.jpg" alt="">
                </div>`
    });

    let vm = new Vue({
       el:"#app",
    });
 </script>

我們使用了 vue 提供的全局 API Vue.component(),注冊(cè)了一個(gè)名為:“my-article”的組件,而組件的 template 正好是我們上面的 html 代碼,這樣,我們就可以用 <my-article></my-article> 的方式來使用我們的組件。

注意:一定要確保實(shí)例 vm 在創(chuàng)建之前,<my-article> 組件已經(jīng)被成功注冊(cè),這也是為什么我們要把代碼寫在實(shí)例化之前。

既然注冊(cè)了組件 <my-article>,我們就來使用這個(gè)自定義的組件:

 <div id="app">
    <my-article></my-article>
 </div>

效果如下:


效果圖.png

我們看到最終渲染的不是標(biāo)簽 <my-article></my-article>,而是我們組件的模板 template 的值。我們成功注冊(cè)了一個(gè)自定義的組件并使用了它。
但這并不夠,我們有的文章目錄中不僅僅只有一篇文章,而且每篇文章的標(biāo)題和日期都不一樣,我們?nèi)绾蝿?dòng)態(tài)地展示它們的數(shù)據(jù)呢?
這里就涉及到了組件的傳參 props,不但函數(shù)可以接受參數(shù),vue 的組件也可以。接下來,我們看看怎么實(shí)現(xiàn)傳參。
我們知道,組件中的這4部分是需要?jiǎng)討B(tài)獲取數(shù)據(jù)的:標(biāo)題,時(shí)間,是否原創(chuàng),頭像。


效果圖.png

那么,我們就通過傳參的方式把這些數(shù)據(jù)傳到組件,實(shí)現(xiàn)數(shù)據(jù)動(dòng)態(tài)展示。
首先,我們把數(shù)據(jù)存儲(chǔ)在實(shí)例vm的data中:
 let vm = new Vue({
   el:"#app",
   data:{
       article:{
           title:"文章標(biāo)題-1",
           date:" 2017年03月06日",
           is_original:true,
           cover_url:"../img/cover.jpg"
       }
   }
 });

我們給 data 增加了一個(gè)文章 article 的信息,包括:標(biāo)題 title,時(shí)間 date,是否原創(chuàng) is_original,頭像 cover_url。
文章的信息有了,我們?cè)趺磦鞯浇M件中去呢?

<div id="app">    
  <my-article :detail="article"></my-article>
</div>

就像一個(gè)函數(shù)傳參一樣,你可以把 detail 理解成一個(gè)形參,article 相當(dāng)于實(shí)參。

Vue.component('my-article',{
   props:['detail'],
   template:`<div>
            <div>
            <h1>{{detail.title}}</h1>
            <div>
            <span>{{detail.date}}</span>
            <span v-show="detail.is_original">原創(chuàng)</span>
            </div>
            </div>
            <img :src="detail.cover_url" alt="">
            </div>`
});

除了 template 以外,我們?cè)黾恿?props,通過它來接受我們的參數(shù) detail,傳進(jìn)來之后,你可以在組件的模板 template 中使用它所接受的所有數(shù)據(jù)了。比如,我們傳進(jìn)來的數(shù)據(jù)包含著文章的信息:title,date,is_original,cover_url。
效果如下:


效果圖.png

數(shù)據(jù)是動(dòng)態(tài)讀取了,那么我們的目錄并不僅僅只有一篇文章,當(dāng)我們數(shù)據(jù)多了之后,該用什么方式展示出來呢?

let vm = new Vue({
   el:"#app",
   data:{
       articles:[
           {
               title:"文章標(biāo)題-1",
               date:"2017年03月06日",
               is_original:true,
               cover_url:"../img/cover.jpg"
           },
           {
               title:"文章標(biāo)題-2",
               date:" 2017年03月09日",
               is_original:true,
               cover_url:"../img/cover.jpg"
           },
           {
               title:"文章標(biāo)題-3",
               date:"2017年03月17日",
               is_original:true,
               cover_url:"../img/cover.jpg"
           },
           {
               title:"文章標(biāo)題-4",
               date:"2017年03月20日",
               is_original:true,
               cover_url:"../img/cover.jpg"
           },
       ]
   }
 });

articles是一個(gè)數(shù)組,我們用 v-for 指令對(duì)它進(jìn)行遍歷即可。
我們對(duì)html代碼稍微改動(dòng)一下:

 <div id="app">
    <my-article 
            v-for="item in articles" 
            :detail="item">
    </my-article>
 </div>

我們?cè)诮M件上加上了 v-for 指令,并遍歷了 articles。
渲染結(jié)果:


效果圖.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。