日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

Vue3 封装第三方组件(一)做一个合格的传声筒

發(fā)布時(shí)間:2023/12/24 综合教程 31 生活家
生活随笔 收集整理的這篇文章主要介紹了 Vue3 封装第三方组件(一)做一个合格的传声筒 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

各種UI庫(kù)的功能都是非常強(qiáng)大的,尤其對(duì)于我這種不會(huì) css 的人來說,就更是幫了大忙了。

只是嘛,如果再封裝一下的話,那么用起來就會(huì)更方便了。

那么如何封裝呢?

封裝三要素 —— 屬性、插槽、事件、方法

可以封裝,但是原生UI庫(kù)提供的強(qiáng)大功能不能給封裝沒了吧,吃了回扣可是不好滴。
那么如何做到不遺漏呢?先做一個(gè)合格的傳聲筒。

傳遞屬性

先看看 el-input 提供的屬性:

太長(zhǎng)了,這里只截了一半。
這么多的屬性,如果一個(gè)一個(gè)都弄到 props 里面,然后再一個(gè)一個(gè)綁定上去,這就太麻煩了。

我們可以分成兩部分,重要的屬性做到 props 里面,其他的可以放到 $attrs 里面。

定義一個(gè)簡(jiǎn)單的組件

模板

<template>
  <div>
    <el-input
      v-model="value" // 不能直接幫的屬性
      v-bind="$attrs"  // 綁定其他屬性。
    >
    </el-input> 
  </div>
</template>

代碼

export default {
  name: 'test-text',
  inheritAttrs: false,
  props: {
    modelValue: [String, Number]
  },
  setup(props, ctx) {
    const value = debounceRef(props, ctx.emit)

    return {
      value
    }
  }
}

父組件的調(diào)用代碼:
模板

<inputtext
    v-model="value"
    v-bind="attrs"
  >
  </inputtext>

代碼

const value = ref('222')

const attrs = reactive({
  maxlength: 10,
  'show-word-limit': true,
  clearable: true
})

這里 modelValue 就是 props ,maxlength、show-word-limit、clearable 就變成了 $attrs 。

然后要看 el-input 是否是根元素,如果是跟元素的話,那么會(huì)自動(dòng)綁定上,不需要我們手動(dòng)寫 v-bind="$attrs"。

如果像上面的例子不是根元素的話,需要手動(dòng)寫 v-bind="$attrs"。

inheritAttrs

這個(gè)是指定組件是否自動(dòng)綁定 $attrs 。
默認(rèn)是 true,會(huì)自動(dòng)把 $attrs 綁定到根元素上面,不管根元素是啥。
這里設(shè)置為 false,那么$attrs 就不會(huì)自動(dòng)綁定到 div 上面了。

插槽

這個(gè)稍微復(fù)雜一點(diǎn),插槽本來就有一點(diǎn)繞,官網(wǎng)的介紹又比較含混。

我們可以找到 $slots 這個(gè)東東,但是官網(wǎng)的介紹(https://www.vue3js.cn/docs/zh/api/instance-properties.html )卻是 使用 h,這個(gè)就……

不過想要傳遞插槽,還是需要這個(gè)。

我們先看看 el-input 的插槽的使用。

  <el-input
    placeholder="請(qǐng)輸入內(nèi)容"
    v-model="input3"
    class="input-with-select"
  >
    <template #prepend>
      <el-select v-model="select" placeholder="請(qǐng)選擇">
        <el-option label="餐廳名" value="1"></el-option>
        <el-option label="訂單號(hào)" value="2"></el-option>
        <el-option label="用戶電話" value="3"></el-option>
      </el-select>
    </template>
    <template #append>
      <el-button icon="el-icon-search"></el-button>
    </template>
  </el-input>

那么想要傳遞插槽的話,是不是可以這樣?

   <!--傳遞插槽-->
    <template  v-slot:prepend> // 給遞給el-input 的插槽
      <slot name="prepend"></slot> // 接收父組件傳遞進(jìn)來的插槽
    </template> 

測(cè)試可以。

那么總不會(huì)一個(gè)一個(gè)寫吧,這也太麻煩了。如果能夠for就好了。

等等, for?那么我們是不是可以這樣。

  <!--傳遞插槽-->
  <template 
    v-for="(item, key, index) in $slots"
      :key="index"
      v-slot:[key]
  >
      <slot :name="key"></slot>
  </template>  

測(cè)試可以。

完整代碼

    <el-input
      ref="refInput"
      v-model="value"
      v-bind="$attrs"
    >
      <!--傳遞插槽-->
      <template 
        v-for="(item, key, index) in $slots"
        :key="index"
        v-slot:[key]
      >
        <slot :name="key"></slot>
      </template> 
    </el-input> 

傳遞事件

這個(gè)就簡(jiǎn)單了,啥都不用做,自動(dòng)就傳遞出去了。el-input 是否是跟元素都可以。
測(cè)試一下:

 <inputtext
    ref="refInput"
    v-model="value"
    v-bind="props"
    @clear="clear"
    @my-change="myChange"
  >

clear 是 el-input 提供的事件,外部可以直接得到這個(gè)事件,組件內(nèi)部不用做操作。
my-change 是自定義的事件。

方法

一直都忽略了,還有方法這個(gè)事,因?yàn)榛緵]用過。

使用方法嘛,就需要使用 ref,這個(gè)此 ref 非彼 ref,說不清了,還是寫代碼吧。

直接使用的方法

直接使用UI庫(kù)組件的方法,比如 el-input 的 提供的 select:

<el-input
  ref="refInput" // 注意這里的 ref 
  v-model="value"
  v-bind="$attrs" >
</el-input> 

ref 的寫法,不要加冒號(hào)。

const refInput = ref(null) // 先放一個(gè)null
onMounted(() => { // 然后在 onMounted 里面才能得到值。
  console.log('refinput', refInput) // 看看啥樣。
  refInput.value.select() // 調(diào)用方法,文本框的內(nèi)容會(huì)被選中
})

先定義一個(gè) ref,然后交給模板里的 ref,好像有點(diǎn)繞,這里必須使用 ref,reactive是不行滴。

在渲染后才能生效,也就是說必須在 onMounted 里面才能得到值,我們看看打印結(jié)果:(太長(zhǎng)只能截取一部分)

很長(zhǎng)吧。

父組件里面怎么用方法

<inputtext
    ref="refInput"
    v-model="value">
</el-input> 
// 測(cè)試方法
const refInput = ref(null)

onMounted(() => {
  console.log('refinput', refInput)
  // refInput.value.$refs.refInput.select()
  refInput.value.refInput.select()
})

父組件里面的用法是一樣的,只是需要再套一層,才能拿到自定義組件內(nèi)部的UI庫(kù)組件。

看看結(jié)構(gòu):

太長(zhǎng)了,還在下面。

這個(gè)就比較近了。

話說為啥弄得這么多屬性和方法事件呀?

父組件調(diào)用子組件內(nèi)部的方法

上面那種方式,還可以讓父組件調(diào)用子組件內(nèi)部定義的方法,比如內(nèi)部定義一個(gè)

   const setInput = () => {
      value.value = new Date()
    }

父組件可以這樣調(diào)用

refInput.value.setInput()

總結(jié)

其實(shí)事件和方法,并沒有封裝,而是直接就可以使用的。
這是 element-plus 測(cè)試的結(jié)果,其他UI庫(kù)沒有測(cè)試。

插槽需要寫一個(gè) v-for 就可以實(shí)現(xiàn)傳遞,而且是通用的代碼。
屬性 就需要規(guī)劃一下了,看設(shè)計(jì)要求,哪些放在 props里面,哪些放在attrs 里面。

總結(jié)

以上是生活随笔為你收集整理的Vue3 封装第三方组件(一)做一个合格的传声筒的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 绯色av一区二区三区高清 | 91九色国产| 国产欧美日韩在线 | 国产精品探花一区二区在线观看 | 国产精品s色 | 亚洲av无码乱码国产精品 | 免费三片在线播放 | 成人亚洲欧美 | 久久五十路 | 欧美激情视频二区 | 天天干天天做天天操 | 欧美三日本三级少妇三 | 日韩激情小视频 | 在线国产欧美 | 欧美日韩一区二区久久 | 国产精品午夜在线观看 | 欧美在线激情视频 | 嫩草视频一区二区三区 | 亚洲视频久久久 | 久久久久久久久国产精品一区 | 日韩av片在线 | 影音先锋中文字幕在线播放 | 欧美真人性野外做爰 | 久久二区三区 | av免费福利| 关之琳三级做爰 | 日本激情网 | 中文字幕在线视频一区 | 一区二区三区免费播放 | 国产中文在线播放 | 天堂av中文在线 | 国产又粗又猛又爽又黄91精品 | 日韩av高清无码 | 四虎成人网| 久久九九爱 | 国产精品美女www爽爽爽视频 | 无码人妻av一区二区三区波多野 | 69国产视频 | 国产精品ww | 欧美一区二区三区不卡视频 | 欧美理论在线 | 日韩一区免费观看 | 校花被c到呻吟求饶 | 伊人青青草 | 91色片 | 亚洲另类图区 | 九七精品 | 久久久无码人妻精品一区 | 精品人妻无码一区二区色欲产成人 | www国产精品 | av男人天堂av | 国产成人不卡 | 成人区精品一区二区婷婷 | 双腿张开被9个男人调教 | 亚洲精品乱码久久久久久 | av电影在线观看 | 男女一区二区三区 | 一个人在线观看免费视频www | 一区二区视频免费 | 一级片免费观看 | av午夜激情| 国产精品熟女久久久久久 | 婷婷色在线播放 | 免费啪视频在线观看 | 欧美黄色免费网站 | caopeng视频| 欧美破处大片 | 精品人妻一区二区三区久久 | 国产乡下妇女三片 | 日本三级中文字幕 | 狠狠干中文字幕 | 国产日韩欧美自拍 | 91免费视 | 蜜桃色一区二区三区 | 日朝毛片 | 免费久久一级欧美特大黄 | 天堂欧美城网站网址 | 精品国产三级a∨在线 | 久久2019 | 日韩在线免费观看视频 | 日韩亚洲欧美一区二区三区 | 亚洲国产图片 | 姐姐你真棒插曲快来救救我电影 | 紧身裙女教师三上悠亚红杏 | 一本到视频 | 国产一区二区在线电影 | 丰满岳乱妇一区二区 | 超碰免费公开在线 | 精品日韩一区二区三区四区 | 国产精品入口麻豆 | 成人一区二区三区四区 | 久久精品国产亚洲av麻豆蜜芽 | 97人妻精品一区二区免费 | 美女三级网站 | 老司机午夜影院 | 日本欧美韩国国产精品 | 网站久久 | 海角社区id | 亚洲色欲色欲www在线观看 |