Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 91国高清视频,日韩精品一区二区三区在线观看,日本一级淫片bbbxxx

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          Vue3 封裝第三方組件(一)做一個(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#slots )卻是 使用 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 里面。

          .什么是字體圖標(biāo)

          可以看作一種特殊字體,其展示的是圖標(biāo),而不再是文字,其擁有字體的特性,比如大小、顏色、透明效果、陰影等,字體圖標(biāo)加載快、不變形。也可以看作是矢量格式的圖標(biāo)。

          2.字體圖標(biāo)常用免費(fèi)資源

          (1)iconmoon字體圖標(biāo)庫(kù):https://icomoon.io/app

          (2)阿里iconfont字體圖標(biāo)庫(kù):https://www.iconfont.cn/

          (3)font-awesome字體圖標(biāo)庫(kù):

          3.字體圖標(biāo)使用步驟

          以iconmoon為例

          (1)選擇需要的圖標(biāo)并下載

          1)在fonts文件夾下有四種類型的字體文件,每種字體文件兼容瀏覽器的種類不同

          a).tff格式(TrueTypeFont),美國(guó)蘋果公司和微軟公司共同開發(fā)的,在Windows和Mac操作系統(tǒng)中為默認(rèn)字體;IE9+、FireFox3.5+、Chrome4+、Safari3+、Opera10+、IOS Mobile中的Safari4.2+等瀏覽器支持該字體。

          b).woff格式(Web Open Font Format-Web開放字體格式),是一種網(wǎng)頁所采用的字體格式標(biāo)準(zhǔn),使用zlib壓縮,文件大小一般比TTF小40%;IE9+、FireFox3.6+、Chrome6+、Safari5.1+、Opera11.1+等瀏覽器支持該字體。

          c).eot格式(Embedded Open Type-嵌入式OpenType ),微軟設(shè)計(jì)用來在網(wǎng)頁使用的字體格式,是OpenType字體的壓縮格式,IE專用,IE4+支持該字體。

          d).svg格式(Scalable Vector Graphics-可縮放的矢量圖形),它是一種用XML定義的語言,用來描述二維矢量及矢量/柵格圖形;Chrome4+、Safari3.1+、Opera10+、IOS Mobile中Safari3.2+等瀏覽器支持該字體。

          其他字體

          e).otf格式(Open Type Font),Microsoft和Adobe公司開發(fā)的,.otf格式比.ttf更為強(qiáng)大,可以把PostScript字體嵌入到TrueType中。

          2)字體轉(zhuǎn)換

          https://www.fontke.com/tool/convfont/

          (2)字體圖標(biāo)的引入

          1)把字體放到項(xiàng)目的相應(yīng)位置

          將下載解壓后的fonts文件夾放到項(xiàng)目路徑下

          2)在html頁面中引入字體

          利用CSS的@font-face屬性,引入外部字體;

          在style.css文件中有如下代碼,為固定用法,注意url中字體路徑,其它可以不變。

          在html的style標(biāo)簽中引入如下代碼:

          @font-face {
            font-family: 'icomoon';
            src:  url('fonts/icomoon.eot?8l3wc0');
            src:  url('fonts/icomoon.eot?8l3wc0#iefix') format('embedded-opentype'),
              url('fonts/icomoon.ttf?8l3wc0') format('truetype'),
              url('fonts/icomoon.woff?8l3wc0') format('woff'),
              url('fonts/icomoon.svg?8l3wc0#icomoon') format('svg');
            font-weight: normal;
            font-style: normal;
            font-display: block;
          }

          3)為元素用該字體

          span {
                  font-family: "icomoon";
              }

          4)為元素添加內(nèi)容

          復(fù)制demo.html中需要的圖標(biāo),如下,將其作為元素的內(nèi)容。

          <span>?</span> 

          (3)新增字體圖標(biāo)的引入

          當(dāng)利用iconmoon選用字體圖標(biāo)時(shí),如果有新增的字體圖標(biāo)需要加入,則需要用到.json文件,如下,在原先選擇的基礎(chǔ)上,再選擇新選擇的字體圖標(biāo),然后再下載使用。

          前端的開發(fā)過程中,需要用到大量的圖片,當(dāng)使用這些圖片一段時(shí)間后,會(huì)發(fā)現(xiàn)這個(gè)過程是千篇一律的,設(shè)計(jì),切圖,適配。當(dāng)然,許多人也喜歡用字體圖標(biāo)。時(shí)間久了,這很枯燥,作為一個(gè)前端,不就是喜歡折騰嗎?不折騰不舒服斯基,那么這次就來嘗試用純css繪制動(dòng)畫線性icon吧。

          當(dāng)我第一次使用純css線性icon的時(shí)候,那感覺就像呼吸到了新鮮空氣一般,它的高可擴(kuò)展性、易使用、加載速度快的特定給我留下了非常深刻的印象。

          線性圖標(biāo)使用了什么技術(shù)呢?

          其實(shí)很容易猜到,它使用了svg技術(shù)。整個(gè)開始過程其實(shí)是把svg放到一個(gè)背景中,然后用一張線性漸變的背景覆蓋在上方,然后使用css的mix-blend-mode的屬性來裁剪、混合。最后線性漸變背景的混合模式設(shè)置為mix-blend-mode: screen后,線性漸變會(huì)漸漸消失在白色背景上。這就形成了我們的漸變圖標(biāo)。

          下面是具體的代碼實(shí)現(xiàn):

          一、編寫背景樣式

          背景圖可以是亮的或是暗的,如果是暗背景,那漸變層需要設(shè)置mix-blend-mode: multiply,如果背景圖是亮的,那漸變的混合屬性需要設(shè)置為mix-blend-mode:screen,下面,我們選擇一個(gè)亮的背景:

          二、添加線性圖標(biāo)

          <divclass="icon-background"><svgxmlns="http://www.w3.org/2000/svg"viewBox="0 0 50 62"><rectx="19"y="6"width="12"height="4"/><rectx="1"y="38"width="48"height="4"/><linex1="25"y1="1"x2="25"y2="6"/><linex1="25"y1="42"x2="25"y2="58"/><lineclass="cls-1"x1="38"y1="42"x2="44"y2="61"/><linex1="12"y1="42"x2="6"y2="61"/><linex1="8.53"y1="53"x2="41.47"y2="53"/><polygonpoints="3 38 16.75 25.99 24.59 31.99 36.92 20 47 29.82 47 37.98 3 38"/><circlecx="14"cy="18"r="3"/><polygonpoints="31 8 31 10 19 10 19 8 3 8 3 38 47 38 47 8 31 8"/></svg></div>

          svg的顏色需要設(shè)置為黑色:

          svg{ color:#000; position:relative; opacity:.9; width:100%; height:100%; display:block; transition:transform .3s ease;}

          三、制作漸變層

          該層需要緊跟著icon層,并且需要設(shè)置漸變屬性



          四、添加動(dòng)畫效果

          該步驟非常簡(jiǎn)單,只要使用keyframes并配以旋轉(zhuǎn)動(dòng)畫即可。


          主站蜘蛛池模板: 久久精品视频一区二区三区| 无码福利一区二区三区| 国偷自产一区二区免费视频| 免费人人潮人人爽一区二区| 无码日本电影一区二区网站| 亚洲国产成人久久一区二区三区| 精品国产鲁一鲁一区二区| 亚洲Av无码一区二区二三区| 无码一区二区波多野结衣播放搜索 | 日韩人妻无码免费视频一区二区三区| 国产一区二区成人| 日本一区二区三区在线观看视频| 色综合视频一区二区三区44| 日本精品一区二区久久久| 在线精品亚洲一区二区小说| 亚洲无圣光一区二区| 国产第一区二区三区在线观看| 国产成人一区二区三区免费视频 | 人妻无码久久一区二区三区免费| 久久久综合亚洲色一区二区三区| 无码国产精品一区二区免费式芒果| 制服丝袜一区在线| 一区二区三区杨幂在线观看| 久久久91精品国产一区二区| 在线播放一区二区| 无码人妻精品一区二| 精品成人乱色一区二区| 久久AAAA片一区二区| 亚洲日韩国产一区二区三区在线| 男人免费视频一区二区在线观看| 国模精品一区二区三区| 国产品无码一区二区三区在线| 日本精品一区二区三区四区| 精品一区二区在线观看| 国产一区二区三区在线观看免费| 中文无码AV一区二区三区| 国产香蕉一区二区精品视频| 制服中文字幕一区二区| 国产在线观看一区二区三区 | 影音先锋中文无码一区| 日本一区午夜艳熟免费|