2021-06-29 Vue 第三方組件的二次封裝

封裝第三方組件

  1. 需要自定義組件MyInput, 透?jìng)鱡l-input的所有事件和方法

    <template>
      <div class="input-container">
        <my-input
          v-model="inputVal"
          style="width: 50%; margin-left: 200px;"
          size="mini"
          clearable
          maxlength="5"
          ref="myInput"
        >
          <template slot="prepend">Http://</template>
          <template slot="append">.com</template>
          <i slot="suffix" class="el-input__icon el-icon-date"></i>
          <i slot="prefix" class="el-input__icon el-icon-search"></i>
        </my-input>
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Vue, Ref } from "vue-property-decorator";
    import MyInput from "./MyInput.vue";
    
    @Component({
      components: {
        MyInput,
      },
    })
    export default class NavFooterComponent extends Vue {
      private inputVal = "123";
    
      @Ref('myInput')
      myInput!: any;
    
      private mounted() {
        this.myInput?.elInput.focus();
      }
    }
    </script>
    
  2. 使用第三方組件的屬性: $sttrs

    $attrs: 包含了父作用域中不作為 prop 被識(shí)別 (且獲取) 的 attribute 綁定 (class 和 style 除外)。

    當(dāng)一個(gè)組件沒(méi)有聲明任何prop 時(shí),這里會(huì)包含所有父作用域的綁定 (class 和 style 除外),并且可以通過(guò) v-bind="$attrs" 傳入內(nèi)部組件

    <!-- myInput.vue -->
    <template>
      <div>
        <el-input v-model="input" v-bind="$attrs"></el-input>
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Vue, Model, Emit, Ref } from "vue-property-decorator";
    import { Input } from "element-ui";
    
    @Component({
      name: "MyInput",
      components: {
        ElInput: Input,
      },
      inheritAttrs: false,
    })
    export default class extends Vue {
     @Model("input")
      value!: any;
      
      set input(newVal: any) {
        this.$emit("input", newVal);
      }
    
      get input() {
        return this.value;
      }
    }
    

    這還不夠,還得把inheritAttrs選項(xiàng)設(shè)置為false,為什么呢,來(lái)看一下inheritAttrs選項(xiàng)的官方定義就明白了。

    默認(rèn)情況下父作用域的不被認(rèn)作 props 的 attribute 綁定 (attribute bindings) 將會(huì)“回退”且作為普通的 HTML attribute 應(yīng)用在子組件的根元素上。當(dāng)撰寫包裹一個(gè)目標(biāo)元素或另一個(gè)組件的組件時(shí),這可能不會(huì)總是符合預(yù)期行為。通過(guò)設(shè)置 inheritAttrsfalse,這些默認(rèn)行為將會(huì)被去掉。而通過(guò) $attrs 可以讓這些 attribute 生效,且可以通過(guò) v-bind 顯性的綁定到非根元素上。注意:這個(gè)選項(xiàng)不影響 class 和 style 綁定。

    簡(jiǎn)單來(lái)說(shuō),把inheritAttrs設(shè)置為false,避免給myInput組件設(shè)置的屬性被添加到myInput組件的根元素div上。

    這樣設(shè)置后,在myInput組件上就可以直接使用el-input組件的屬性,不管后續(xù)el-input組件再增加了多少個(gè)屬性。

  1. 使用第三方法組件的自定義事件: $listeners

    $listeners:包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽(tīng)器。它可以通過(guò) v-on="$listeners" 傳入內(nèi)部組件。

    <el-input v-model="input" v-bind="$attrs" v-on="$listeners"></el-input>
    
  2. 使用第三方付組件的插槽

    <el-input v-model="input" v-bind="$attrs" v-on="$listeners" ref="elInput">
      <!-- 普通插槽 -->
      <slot v-for="(_, name) in $slots" :name="name" :slot="name" />
    
      <!--
        作用域插槽
        <template v-for="(_, name) in $scopedSlots" #[name]="scope">
         <slot :name="name" v-bind="scope" />
        </template>
      -->
    </el-input>
    
  3. 使用第三方組件的Ref

    如上代碼, 在el-inpuit上掛載屬性 ref="elInput"

    @Component({
      name: "MyInput",
      components: {
        ElInput: Input,
      },
      inheritAttrs: false,
    })
    export default class extends Vue {
      
      @Ref("elInput")
     elInput!: any;
     
     // ...
    }
    
    <template>
      <div class="input-container">
        <my-input
          v-model="inputVal"
          ref="myInput"
        >
        </my-input>
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Vue, Ref } from "vue-property-decorator";
    import MyInput from "./MyInput.vue";
    
    @Component({
      components: {
        MyInput,
      },
    })
    export default class NavFooterComponent extends Vue {
      private inputVal = "123";
    
      @Ref('myInput')
      myInput!: any;
    
      private mounted() {
        // <!-- 父組件中獲取elInput實(shí)例HTMLLInputElement -->
        this.myInput?.elInput.focus();
      }
    }
    </script>
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容