vue系列元件篇(二)

伊澤瑞爾發表於2018-09-07

概述

vue元件是vue常用的功能,vue也因為強大的元件功能得到很多開發者的青睞。一個好的元件,可以提供給開發者很多方便,特別是複用程式碼,程式碼一致性等。 本文通過實現一個列表my-list元件,來講解元件的用法和特性。 下面先看一下工程目錄:

目錄結構

整個工程可以在git上下載:點選下載,其中藍色線條標記的,分別是我們這次用到的頁面和元件。

元件引入

元件引入分全域性引入和區域性引入,顧名思義,全域性引入可以在任何一個路由頁面使用該元件,而區域性引入是在引入頁面才能使用。

import myList from '../components/my-list'
  //全域性引入
  Vue.component('my-list',myList)
  export default {
    name: "componentStudy",
    data: function () {
        return {}
    },
    //區域性引入,寫法很靈活
    components:{myList},
    methods: {},
    mounted: function () {
    },

    computed: {},
    created: function () {
    }
  }
複製程式碼

上面的程式碼的2中寫法分別是全域性引入和區域性引入,整體來說,像分頁元件,下拉框元件,表格元件等大多數頁面都用得上的可以全域性引入,像tab頁面,特殊按鈕等用的比較的少的頁面可以採用區域性引用。

元件傳值

我們的列表元件,各個頁面的資料不一樣,這些資料往往是通過引入改元件的頁面決定的,那麼意味著,這些資料應該是從父元件傳到子元件的,下面我們給我們的列表元件傳一個dataList(資料)和一個clickFunction(點選每一項的觸發函式)。vue通過prop子元件傳值,這裡傳值可以是js所有型別。

//檔案componentSutdy.vue
<my-list :data-list="dataList" :click-fun="clickFunction"></my-list>
data: function () {
        return {
          dataList:[
            {title:'攜手打造更加緊密的中非命運共同體',content:'9月3日,2018年中非合作論...'},
            {title:'“小眼鏡”牽動大情懷',content:'近日,習近平總書記就青少年視力健...'},
            {title:'倡議五週年之際',content:'2013年9月7日,國家主席習...'},
          ]
        }
    },
    methods: {
      clickFunction(item){
        console.log(item)
      }
    },
//檔案my-list.vue
<template>
    <div class="my-list">
      <ul>
        <li class="list-group-item" v-for="(item,index) in dataList" @click="clickFun(1)">
          <div class="main-title" v-text="item.title"></div>
          <div class="content" v-text="item.content"></div>
        </li>
      </ul>
    </div>
</template>
//子元件接收父元件傳過來的值
    props:{
      dataList:{
        type:[Array,Object],   // 型別校驗,多個可能的型別
        require:true,         //是否必傳
        default:function () { //預設值, 物件或陣列預設值必須從一個工廠函式獲取
          return []
        },
        // //自定義校驗
        // validator: function (value) {
        //   // 這個值必須匹配下列字串中的一個
        //   return ['success', 'warning', 'danger'].indexOf(value) !== -1
        // }
      },
      clickFun:{
        type: Function,
        require: false
      }
    },
複製程式碼

這裡寫圖片描述

可以看到,子元件使用propos接收了父元件傳過來的dataListclickFun2個變數。注意傳遞形式就是vue常見語法v-bind來傳遞。試著點選列表,可以看到父元件的方法cliFun被呼叫了,並且接收到了子元件傳過來的變數。 上面的例子,完成了父元件向子元件傳遞引數,子元件呼叫父元件方法。

子元件呼叫父元件方法

和其他框架一下,vue在子元件無法直接通過this.的方式調到父元件的方法,這裡vue提供的是$emit的方式來呼叫父元件的方法。我們修改上面的例子,讓子元件點選按鈕來刪除一個列表,這裡值得注意的是,vue元件直接傳遞引數是單向的,意思是,父元件傳遞過去的變數,只能在父元件被改變子元件是不能改變父元件傳過來的這個變數的。不過可以通過賦值、計算屬性等方式來重新定義一個變數。 修改部分的程式碼:

//檔案componentSutdy.vue
//新增了@deleteItem的繫結
<my-list :data-list="dataList" :click-fun="clickFunction" @deleteItem="removeItem"></my-list>
//方法裡面新增執行函式
removeItem(index){
        this.dataList.splice(index,1)
      }
//檔案my-list.vue
//新增了$emit('deleteItem',index)"執行函式
<li class="list-group-item" v-for="(item,index) in dataList" @click="clickFun(1)">
          <div class="main-title" v-text="item.title"></div>
          <div class="content" v-text="item.content"></div>
          <i class="el-icon-delete" @click="$emit('deleteItem',index)"></i>
        </li>
      
複製程式碼

這裡寫圖片描述

設定點選刪除按鈕,順利刪除了一行,可以看到,我們在父元件通過deleteItem傳遞了removeItem函式給子元件,子元件通過$emit('deleteItem',index)順利調到了父元件的函式,並且傳遞了一個引數,父元件通過這個引數刪除了使用者點選的資料,這個過程完成了欄位就呼叫父元件的方法,也說明了,子元件不要直接改變父元件傳遞過來的引數,因為這裡是單向繫結的。 值得注意的是,欄位就呼叫父元件的函式,有2種方式,穩重第一種是通過prop傳遞,第二種是通過@繫結來傳遞的,實際使用過程中,建議使用第二種方式。

父元件呼叫子元件方法

很多時候,我們需要欄位就來執行某種操作,來達到頁面效果,比如說,我們需要在使用者點選之後,改變列表顏色,來切換主題。

//檔案componentSutdy.vue,關鍵程式碼
<my-list :data-list="dataList" ref="myList" :click-fun="clickFunction" @deleteItem="removeItem"</my-list>
<el-button @click="changeTheme" style="margin-top: 20px;">切換主題</el-button>
changeTheme(){
        this.$refs.myList.changeColor()
      },
//檔案my-list.vue,關鍵程式碼
<li class="list-group-item" :class="{'has-bg':isChange}" v-for="(item,index) in dataList" @click="clickFun(1)">
          <div class="main-title" v-text="item.title"></div>
          <div class="content" v-text="item.content"></div>
          <i class="el-icon-delete" @click="$emit('deleteItem',index)"></i>
        </li>
changeColor(){
 this.isChange = true
}

複製程式碼

這裡寫圖片描述

點選按鈕,順利改變了列表的背景顏色。這裡,在引用元件的時候,我們通過ref給元件新增了一個命名:myList,父元件點選切換主題,執行this.$refs.myList.changeColor(),子元件changeColor方法被呼叫,最終實現了轉換主題,這裡元件能單獨命名,意味著同一個頁面可以引用同一個元件多次,通過不同的命名,來單獨操作,互不影響。

元件插槽

元件插槽是為了元件能有更靈活的使用,能讓主頁面在適當的字元插入自定義的html片段,先看一張圖

這裡寫圖片描述
我們想給每一行新增一個序號並且加粗,如果是元件裡面固定的html結構,和明顯難以實現,這裡我們需要用到slot插槽功能。

//檔案componentSutdy.vue,關鍵程式碼
<my-list :data-list="dataList" ref="myList" :click-fun="clickFunction" @deleteItem="removeItem">
          <template slot="title" slot-scope="{item,index}">
            <div>
              <span v-text="`${index + 1}.`" style="font-weight: bold"></span>
              <span v-text="item.title"></span>
            </div>
          </template>
        </my-list>
//檔案my-list.vue,關鍵程式碼
<li class="list-group-item" :class="{'has-bg':isChange}" v-for="(item,index) in dataList" @click="clickFun(1)">
          <slot name="title" :item="item" :index="index">
            <div class="main-title" v-text="item.title"></div>
          </slot>
          <div class="content" v-text="item.content"></div>
          <i class="el-icon-delete" @click="$emit('deleteItem',index)"></i>
        </li>
複製程式碼

可以看到,我們在子頁面,新增了name="title"slot插槽,並且通過繫結資料的方式傳遞了2個引數,item,index,父元件,<template slot="title" slot-scope="{item,index}">通過sole與欄位就name匹配,來將html程式碼插入到對應的位置。這樣主頁面就輕鬆定製了新聞列表標題欄的html結構,當主頁面不引入插槽是,將使用預設的html解析。這裡接收引數的方式是採用es205的解構語法。

總結:關於vue元件就將到這裡,相信上面的類容能涵蓋到大多數用法,還有部分動態元件和非同步元件不作講解,實際使用中,用到很少,整個程式碼的原始碼可以在git:github.com/jackzhujie/… 最後想檢視更多文章,可以關注我的個人公眾號:

公眾號

相關文章