Vue封裝三方庫的運用: $attrs + $listeners

分類是學習的本質,時間分類是時間管理,知識分類是知識管理,資源分類是項目管理~~ html

是什麼

在封裝一個插件時,你們每每會先從使用插件者能傳遞的數據,開始設計插件的入口,封裝vue組件同理。vue中封裝一個組件,組件上dom綁定傳遞的各類東西,除class style外,在vue裏本質上只有如下三種vue

  • Prop:子組件內聲明瞭接受props,父傳的屬性就是Prop
  • $attrs:除Prop外,全部傳遞的屬性 (v-bind監聽)
  • $listeners:除上面二者,剩下的就是事件啦~ (v-on監聽)

如何用

下面簡單demo封裝一個三方組件,咱們但願首先是繼承這個三方組件的全部事件,而後再經過控制數據流入口,能夠自定義各類功能。下面看看如何使用$attrs ,$listeners完整繼承bash

  • 能夠先用inheritAttrs: false關閉自動繼承1,從而能夠得到父級傳下來的全部數據分配權。能夠簡單理解爲父級傳下來的數據爲以下結構
    {
    	$props:{},
    	$attrs:{},
    	$listeners:{}
    }複製代碼
  • props咱們聲明時會對其中屬性進行分配,那麼就剩下分配$listeners和$attrs
  • 投磚引玉:下面demo,我直接把全部屬性、事件沉澱到三方庫組件上,這樣就變相繼承了全部三方的配置
    // 使用組件代碼
    <AntButton type="danger" @click="test"  size="large" msg="Welcome to Your Vue.js App"/>複製代碼
    //封裝AntButton,a-button爲ant-design-vue三方庫中組件
    <template lang="html">
        <div class="button-wrap">
            <a-button v-bind="$attrs" v-on="$listeners">{{msg}}</a-button>
        </div>
    </template>
    
    <script>
    export default {
      inheritAttrs: false,
      props: {
        msg: {
          type: String,
          default: '輸入內容'
        }
      },
      created () {
        console.log(this.$attrs, 'button-$attrs')
        console.log(this.$listeners, 'button-$listeners')
      }
    }
    </script>複製代碼

處理 v-model

v-model本質是傳遞一個prop + 監聽表單事件2。咱們能夠用以下方式進行向下沉澱數據dom

<template lang="html">
    <div class="input-wrap">
         <a-input  v-bind="$attrs" v-on="inputListeners"  placeholder="Basic usage"/>
    </div>
</template>

<script>
export default {
  inheritAttrs: false,
  props: ['value'],
  computed: {
    inputListeners: function () {
      var vm = this
      return Object.assign({},
        // 咱們從父級添加全部的監聽器
        this.$listeners,
        // 而後咱們添加自定義監聽器,
        // 或覆寫一些監聽器的行爲
        {
          // 這裏確保組件配合 `v-model` 的工做
          input: function (event) {
            // 默認會把整個event冒泡上去,也是v-model實現成功
            vm.$emit('input', event.target.value)
          }
        }
      )
    }
  }
}
</script>
	複製代碼

固然若是去掉自定義的表單事件監聽,也是能夠實現的,父級將會獲得整個InputEventide

//註釋這段 
{
          // 這裏確保組件配合 `v-model` 的工做
          input: function (event) {
            // 默認會把整個event冒泡上去,也是v-model實現成功
            vm.$emit('input', event.target.value)
          }
  }複製代碼


關於 $attrs + $listeners的運用場景,這裏只能簡單拋轉引玉一下。不過明晰一個v-model,v-on , v-bind其實本質是在作什麼,是件頗有必要的事。在數據驅動視圖的邏輯裏,咱們應該始終盯住咱們的數據流,一切皆對象,哪一個對象哪一個key變了,在IT的世界裏,清晰本質,將會更有創造力。(以上只談運用精通,不談理論精通~)學習

  1. inheritAttrs ↩︎
  2. 自定義組件v-model ↩︎
相關文章
相關標籤/搜索