溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

vue3中的透?jìng)鱝ttributes怎么用

發(fā)布時(shí)間:2022-08-29 17:03:41 來(lái)源:億速云 閱讀:222 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容介紹了“vue3中的透?jìng)鱝ttributes怎么用”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

    綁定樣式

    vue 的樣式綁定要人性化很多,react 實(shí)現(xiàn) vue 的這種寫(xiě)法,還需要專(zhuān)門(mén)下載一個(gè)第三方庫(kù): classnames。

    vue 的樣式綁定有兩種形式:對(duì)象數(shù)組

    相對(duì)而言,個(gè)人還是比較的偏向對(duì)象的寫(xiě)法,可能 react 寫(xiě)習(xí)慣了吧。原因有兩點(diǎn):

    • 數(shù)組能實(shí)現(xiàn)的,對(duì)象也能使用(反之亦然)。

    • 在 DOM 結(jié)構(gòu)中,使用數(shù)組的[]形式,感覺(jué)看起來(lái)比較的怪異,復(fù)雜。

    對(duì)象

    我把對(duì)象的形式分為三種場(chǎng)景,分別如下:

    場(chǎng)景一:循環(huán)列表,根據(jù)列表項(xiàng)的某屬性的不同而展示不同

     <script setup lang="ts">
     const list = [
       {
         id: "1",
         name: "name1",
         isActive: true,
       },
       {
         id: "2",
         name: "name2",
         isActive: false,
       },
       {
         id: "3",
         name: "name3",
         isActive: false,
       },
     ];
     </script>
     <template>
       <div
         v-for="item in list"
         :key="item.id"
         class="common"
         :class="{ isActive: item.isActive }" 
       >
         {{ item.name }}
       </div>
     </template>
     <style>
     .isActive {
       color: red;
     }
     </style>

    根據(jù)列表項(xiàng)的isActive的屬性值不同,來(lái)判斷是否顯示isActive類(lèi)名。

    場(chǎng)景二:通過(guò)觸發(fā)事件,來(lái)展示不同的樣式。

    這種情況一般針對(duì)于用戶操作,比如點(diǎn)擊按鈕觸發(fā)事件,來(lái)修改某一內(nèi)容的樣式。

     <script setup lang="ts">
     import { ref } from "vue";
     const isActive = ref<boolean>(false);
     // 事件改變 data 屬性值  
     const btn = () => {
       isActive.value = !isActive.value;
     };
     </script>
     <template>
       <div class="common" :class="{ isActive: isActive }">文字說(shuō)明</div>
       <button @click="btn">改變樣式</button>
     </template>
     <style>
     .common {
       font-size: 20px;
     }
     .isActive {
       color: red;
     }

    通過(guò)點(diǎn)擊事件,修改 data 中的值,從而影響到 div 標(biāo)簽的類(lèi)名展示。

    情況三:當(dāng)關(guān)聯(lián)多個(gè)動(dòng)態(tài)樣式,直接綁定一個(gè)對(duì)象

    上面的情況,當(dāng)存在少量的動(dòng)態(tài)樣式(1~2個(gè))的時(shí)候,可以直接寫(xiě)在DOM結(jié)構(gòu)中,閱讀性可觀。當(dāng)存在多個(gè)的時(shí)候,還這樣寫(xiě)的話,可能 DOM 就顯的混亂了,閱讀性極低,這時(shí)借助一個(gè)對(duì)象就很好的解決了這個(gè)問(wèn)題。

     <script setup lang="ts">
     import { reactive } from "vue";
     const classObj = reactive({
       isActive: true,
       hasError: false,
       textRed: true,
     });
     </script>
     <template>
       <div class="common" :class="classObj">文字說(shuō)明</div>
     </template>

    數(shù)組

    數(shù)組的寫(xiě)法,對(duì)于個(gè)人來(lái)說(shuō),就大致的了解下就行了。

    形式一:綁定多個(gè)class

     <script setup lang="ts">
     import { ref } from "vue";
     const activeClass = ref("active");
     const errorClass = ref("text-danger");
     </script>
     <template>
       <div :class="[activeClass, errorClass]"></div>
     </template>

    最后渲染出來(lái)的結(jié)果:

     <div class="active text-danger"></div>

    形式二:數(shù)組中的判斷

     <!--三目運(yùn)算符的判斷-->
     <div :class="[isActive ? activeClass : '', errorClass]"></div>
     <!--數(shù)組中嵌套對(duì)象的判斷-->
     <div :class="[{activeClass: isActive}, errorClass]"></div>

    vue 中的動(dòng)態(tài) style 跟 class 的用法基本相似的,就不用多說(shuō)了。

    透?jìng)鞯腶ttributes

    在上面的樣式綁定中,都是把 class 寫(xiě)在了原生標(biāo)簽上,那么如果把 class 寫(xiě)在組件上,效果是什么呢?

    在此之前,先來(lái)彌補(bǔ)兩個(gè)小知識(shí)點(diǎn)。

    知識(shí)點(diǎn)一:vue3 支持多個(gè)根節(jié)點(diǎn)

     <!--vue2: 錯(cuò)誤的寫(xiě)法-->
     <template>
       <div></div>
       <div></div>
     </template>
     <!--vue3: 正確-->
     <template>
       <div></div>
       <div></div>
     </template>

    知識(shí)點(diǎn)二:什么是透?jìng)鞯腶ttributes?

    “透?jìng)?attribute”指的是傳遞給一個(gè)組件,卻沒(méi)有被該組件聲明為 props 或 emits 的 attribute 或者 v-on 事件監(jiān)聽(tīng)器。常見(jiàn)的有 class style id.

    簡(jiǎn)單的理解就是:傳遞給子組件的屬性,但是被沒(méi)有在子組件聲明,就是透?jìng)?attributes。

    準(zhǔn)備工作完成,可以開(kāi)始正題了。

    透?jìng)?attributes 之樣式綁定

    分為兩種情況,只有一個(gè)根節(jié)點(diǎn)或者多個(gè)根節(jié)點(diǎn)。

    情況一:子組件只有一個(gè)根節(jié)點(diǎn)

     <!--son子組件-->
     <template>
       <div class="own">son組件</div>
     </template>

    存在自身的類(lèi)名 own

     <!--父組件使用Son-->
     <Son class='abc' />

    class 并沒(méi)有在 props 中申明,那么它就是透?jìng)?attributes。

    那么最后渲染的結(jié)果:

     <div class='abc own'>son組件</div>

    就會(huì)主動(dòng)的綁定到根節(jié)點(diǎn)上去,與原來(lái)的 class 進(jìn)行組合。

    情況二:子組件有多個(gè)根節(jié)點(diǎn)

    存在多個(gè)根節(jié)點(diǎn)的時(shí)候,并且還傳遞了透?jìng)?attributes,如果沒(méi)有手動(dòng)處理的話,是會(huì)存在警告的。

     <!--son子組件-->
     <template>
       <div class="own">son組件1</div>
       <div class="own">son組件2</div>
     </template>
     <!--父組件使用Son-->
     <Son class='abc' />

    沒(méi)有處理,拋出警告:

    vue3中的透?jìng)鱝ttributes怎么用

    那么處理警告的方式兩種:

    • 禁用透?jìng)?attributes,設(shè)置 inheritAttrs 為 false(后面再說(shuō))。

    • 手動(dòng)處理,具體綁定在哪一個(gè)根節(jié)點(diǎn)。

     <!--son子組件-->
     <template>
       <div class="own" :class="$attrs['class']">son組件1</div>
       <div class="own">son組件2</div>
     </template>

    這樣警告也會(huì)消失,并且把透?jìng)?attributes 綁定在了第一個(gè)根節(jié)點(diǎn)上。這里的$attrs是一個(gè)對(duì)象,需要具體指明某個(gè)屬性。

    最后渲染的結(jié)果:

     <div class="own abc">son組件1</div>
     <div class="own">son組件2</div>

    透?jìng)?attributes 之事件綁定

    上面只是針對(duì)樣式進(jìn)行了透?jìng)鳎敲词录脑?,又?huì)是怎么樣的呢?

    先說(shuō)結(jié)論吧,表現(xiàn)形式跟樣式綁定是基本一樣的。

     <!--子組件Son-->
     <script setup lang="ts">
     const btn1 = () => {
       console.log("子組件的點(diǎn)擊事件");
     };
     </script>
     <template>
       <button @click="btn1">點(diǎn)擊</button>
     </template>

    現(xiàn)在子組件的根節(jié)點(diǎn)是一個(gè) button 標(biāo)簽,并且上面綁定了一個(gè)點(diǎn)擊事件。

     <!--父組件使用-->
     <script setup lang="ts">
     import Son from "./Son.vue";
     const btn = () => {
       console.log("父組件的點(diǎn)擊事件");
     };
     </script>
     <template>
       <Son @click="btn" />
     </template>

    父組件調(diào)用,也傳遞了一個(gè)透?jìng)鞯氖录^(guò)來(lái)。當(dāng)點(diǎn)擊按鈕:

    vue3中的透?jìng)鱝ttributes怎么用

    發(fā)現(xiàn),子組件的事件被觸發(fā)了,父組件傳遞過(guò)來(lái)的事件也被觸發(fā)了,順序?yàn)?strong>先子后父。

    透?jìng)鞯?attributes 基本說(shuō)完了,接下來(lái)就看看幾個(gè)特殊部分吧。

    特殊1:組件嵌套

    有些情況下一個(gè)組件會(huì)在根節(jié)點(diǎn)上渲染另一個(gè)組件。那么透?jìng)?attributes 也會(huì)繼續(xù)傳遞下去。

     <!--baseChild-->
     <template>
       <div></div>
     </template>
     <!--child-->
     <template>
       <base-child />
     </template>
     <!--father-->
     <Child class='abc'/>

    那么最后渲染的結(jié)果:

     <div class='abc'></div>

    特殊2:禁用透?jìng)鱝ttributes

    設(shè)置 inheritAttrs:false,就禁止使用了自動(dòng)綁定,可以消除前面所說(shuō)的警告;然后就可以自由的綁定 $attrs, 該對(duì)象就包含了傳遞過(guò)來(lái)的透?jìng)?attributes。

     <!--如果是setup寫(xiě)法,就需要單獨(dú)添加一個(gè)script標(biāo)簽,暴露一個(gè)配置對(duì)象-->
     <script lang="ts">
     export default {
       inheritAttrs: false, // 禁用
     };
     </script>
     <script setup lang="ts">
     const btn1 = () => {
       console.log("子組件的點(diǎn)擊事件");
     };
     </script>
     <template>
       <button @click="btn1">點(diǎn)擊</button>
     </template>

    需要注意的是:

    • 和 props 有所不同,透?jìng)?attributes 在 JavaScript 中保留了它們?cè)嫉拇笮?xiě),所以像 foo-bar 這樣的一個(gè) attribute 需要通過(guò) $attrs['foo-bar'] 來(lái)訪問(wèn)。

    • 像 @click 這樣的一個(gè) v-on 事件監(jiān)聽(tīng)器將在此對(duì)象下被暴露為一個(gè)函數(shù) $attrs.onClick。

    特殊3:在 javascript 中訪問(wèn)透?jìng)鞯腶ttributes

    在組件實(shí)例中獲取,通過(guò) this 的形式

     export default {
       created() {
         console.log(this.$attrs)
       }
     }

    “vue3中的透?jìng)鱝ttributes怎么用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

    向AI問(wèn)一下細(xì)節(jié)
    AI