国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Inhaltsverzeichnis
高階組件介紹
Heim Web-Frontend Front-End-Fragen und Antworten Was sind hochrangige Vue-Komponenten?

Was sind hochrangige Vue-Komponenten?

Dec 20, 2022 pm 01:24 PM
Vue Advanced Components

在vue中,高階組件其實就是一個高階函數(shù), 即返回一個組件函數(shù)的函數(shù)。高階組件的特點:1、是無副作用的純函數(shù),且不應(yīng)該修改原組件,即原組件不能有變動;2、不關(guān)心傳遞的數(shù)據(jù)(props)是什么,并且新生成組件不關(guān)心數(shù)據(jù)來源;3、接收到的props應(yīng)該傳遞給被包裝組件,即直接將原組件prop傳給包裝組件;4、高階組件完全可以添加、刪除、修改props。

Was sind hochrangige Vue-Komponenten?

本教程操作環(huán)境:windows7系統(tǒng)、vue3版,DELL G3電腦。

高階組件介紹

vue 高階組件的認識,在React中組件是以復(fù)用代碼實現(xiàn)的,而Vue中是以mixins 實現(xiàn),并且官方文檔中也缺少一些高階組件的概念,因為在vue中實現(xiàn)高階組很困難,并不像React簡單,其實vue中mixins也同樣和以代替,在讀了一部分源碼之后,對vue有了更深的認識

所謂高階組件其實就是一個高階函數(shù), 即返回一個組件函數(shù)的函數(shù),Vue中怎么實現(xiàn)呢? 注意 高階組件有如下特點

高階組件(HOC)應(yīng)該是無副作用的純函數(shù),且不應(yīng)該修改原組件,即原組件不能有變動
高階組件(HOC)不關(guān)心你傳遞的數(shù)據(jù)(props)是什么,并且新生成組件不關(guān)心數(shù)據(jù)來源
高階組件(HOC)接收到的?props?應(yīng)該傳遞給被包裝組件即直接將原組件prop傳給包裝組件
高階組件完全可以添加、刪除、修改?props

高階組件舉例

Base.vue

<template>
??<div>
????<p @click="Click">props:?{{test}}</p>
??</div>
</template>
<script>
export?default?{
??name:?'Base',
??props:?{
????test:?Number
??},
??methods:?{
????Click?()?{
??????this.$emit('Base-click')
????}
??}
}
</script>

Vue 組件主要就是三點:props、event 以及 slots。對于 Base組件 組件而言,它接收一個數(shù)字類型的 props 即 test,并觸發(fā)一個自定義事件,事件的名稱是:Base-click,沒有 slots。我們會這樣使用該組件:

現(xiàn)在我們需要 base-component 組件每次掛載完成的時候都打印一句話:haha,同時這也許是很多組件的需求,所以按照 mixins 的方式,我們可以這樣做,首先定義個 mixins

export?default?consoleMixin?{
??mounted?()?{
????console.log('haha')
??}
}

然后在 Base 組件中將 consoleMixin 混入:

<template>
??<div>
????<p @click="Click">props:?{{test}}</p>
??</div>
</template>
<script>
export?default?{
??name:?'Base',
??props:?{
????test:?Number
??},
??mixins:?[?consoleMixin?],
??methods:?{
????Click?()?{
??????this.$emit('Base-click')
????}
??}
}
</script>

這樣使用 Base 組件的時候,每次掛載完成之后都會打印一句 haha,不過現(xiàn)在我們要使用高階組件的方式實現(xiàn)同樣的功能,回憶高階組件的定義:接收一個組件作為參數(shù),返回一個新的組件,那么此時我們需要思考的是,在 Vue 中組件是什么?Vue 中組件是函數(shù),不過那是最終結(jié)果,比如我們在單文件組件中的組件定義其實就是一個普通的選項對象,如下:

export?default?{
??name:?'Base',
??props:?{...},
??mixins:?[...]
??methods:?{...}
}

這難道不是一個純對象嘛

import?Base?from?'./Base.vue'
console.log(Base)

這里的Base是什么呢 對就是一個JSON對象,而當以把他加入到一個組件的components,Vu最終會以該參數(shù)即option來構(gòu)造實例的構(gòu)造函數(shù),所以Vue中組件就是個函數(shù),但是在引入之前仍只是一個options對象,所以這樣就很好明白了 Vue中組件開始只是一個對象,即高階組件就是 一個函數(shù)接受一個純對象,并且返回一個新純對象

export?default?function?Console?(BaseComponent)?{
??return?{
????template:?'<wrapped v-on="$listeners" v-bind="$attrs"/>',
????components:?{
??????wrapped:?BaseComponent
????},
????mounted?()?{
??????console.log('haha')
????}
??}
}

這里 Console就是一個高階組件,它接受一個參數(shù) BaseComponent即傳入的組件,返回一個新組件,將BaseComponent作為新組件的子組件并且在mounted里設(shè)置鉤子函數(shù) 打印haha,我們可以完成mixins同樣做到的事,我們并沒有修改子組件Base,這里的 $listeners $attrs 其實是在透傳props 和事件 那這樣真的就完美解決問題了嗎?不是的,首先 template 選項只有在完整版的 Vue 中可以使用,在運行時版本中是不能使用的,所以最起碼我們應(yīng)該使用渲染函數(shù)(render)替代模板(template)

Console.js

export?default?function?Console?(BaseComponent)?{
??return?{
????mounted?()?{
??????console.log('haha')
????},
????render?(h)?{
??????return?h(BaseComponent,?{
????????on:?this.$listeners,
????????attrs:?this.$attrs,
??????})
????}
??}
}

我們將模板改寫成了渲染函數(shù),看上去沒什么問題,實際還是有問題,上面的代碼中 BaseComponent 組件依然收不到 props,為什么呢,我們不是已經(jīng)在 h 函數(shù)的第二個參數(shù)中將 attrs 傳遞過去了嗎,怎么還收不到?當然收不到,attrs 指的是那些沒有被聲明為 props 的屬性,所以在渲染函數(shù)中還需要添加 props 參數(shù):

export?default?function?Console?(BaseComponent)?{
??return?{
????mounted?()?{
??????console.log('haha')
????},
????render?(h)?{
??????return?h(BaseComponent,?{
????????on:?this.$listeners,
????????attrs:?this.$attrs,
????????props:?this.$props
??????})
????}
??}
}

那這樣呢 其實還是不行 props始終是空對象,這里的props是高階組件的對象,但是高階組件并沒有聲明props所以如此故要再聲明一個props

export?default?function?Console?(BaseComponent)?{
??return?{
????mounted?()?{
??????console.log('haha')
????},
????props:?BaseComponent.props,
????render?(h)?{
??????return?h(BaseComponent,?{
????????on:?this.$listeners,
????????attrs:?this.$attrs,
????????props:?this.$props
??????})
????}
??}
}

ok 一個差不多的高階組件就完成了 但是能還每完 我們只實現(xiàn)了 透傳props,透傳事件,emmmm就剩下slot了 我們修改 Base 組件為其添加一個具名插槽和默認插槽 Base.vue

<template>
??<div>
????<span @click="handleClick">props:?{{test}}</span>
????<slot name="slot1"/>?<!-- 具名插槽 --></slot>
????<p>===========</p>
????<slot><slot/>?<!-- 默認插槽 -->
??</div>
</template>
?
<script>
export?default?{
??...
}
</script>

<template>
??<div>
????<Base>
??????<h2 slot="slot1">BaseComponent?slot</h2>
??????<p>default?slot</p>
????</Base>
????<wrapBase>
??????<h2 slot="slot1">EnhancedComponent?slot</h2>
??????<p>default?slot</p>
????</wrapBase>
??</div>
</template>
?
<script>
??import?Base?from?'./Base.vue'
??import?hoc?from?'./Console.js'
?
??const?wrapBase?=?Console(Base)
?
??export?default?{
????components:?{
??????Base,
??????wrapBase
????}
??}
</script>

這里的執(zhí)行結(jié)果就是 wrapBase里的slot都沒有了 所以就要改一下高階組建了

function?Console?(BaseComponent)?{
??return?{
????mounted?()?{
??????console.log('haha')
????},
????props:?BaseComponent.props,
????render?(h)?{
?
??????//?將?this.$slots?格式化為數(shù)組,因為?h?函數(shù)第三個參數(shù)是子節(jié)點,是一個數(shù)組
??????const?slots?=?Object.keys(this.$slots)
????????.reduce((arr,?key)?=>?arr.concat(this.$slots[key]),?[])
?
??????return?h(BaseComponent,?{
????????on:?this.$listeners,
????????attrs:?this.$attrs,
????????props:?this.$props
??????},?slots)?//?將?slots?作為?h?函數(shù)的第三個參數(shù)
????}
??}
}

這時 slot內(nèi)容確實渲染出來了 但是順序不太對 高階組件的全部渲染到了末尾。。 其實 Vue在處理具名插槽會考慮作用域的因素 首先 Vue 會把模板(template)編譯成渲染函數(shù)(render),比如如下模板:

<div>
??<p slot="slot1">Base?slot</p>
</div>

會被編譯成如下渲染函數(shù):

var?render?=?function()?{
??var?_vm?=?this
??var?_h?=?_vm.$createElement
??var?_c?=?_vm._self._c?||?_h
??return?_c("div",?[
????_c("div",?{
??????attrs:?{?slot:?"slot1"?},
??????slot:?"slot1"
????},?[
??????_vm._v("Base?slot")
????])
??])
}

觀察上面的渲染函數(shù)我們發(fā)現(xiàn)普通的 DOM 是通過 _c 函數(shù)創(chuàng)建對應(yīng)的 VNode 的?,F(xiàn)在我們修改模板,模板中除了有普通 DOM 之外,還有組件,如下:

<div>
??<Base>
????<p slot="slot1">Base?slot</p>
????<p>default?slot</p>
??</Base>
</div>

其render函數(shù)

var?render?=?function()?{
??var?_vm?=?this
??var?_h?=?_vm.$createElement
??var?_c?=?_vm._self._c?||?_h
??return?_c(
????"div",
????[
??????_c("Base",?[
????????_c("p",?{?attrs:?{?slot:?"slot1"?},?slot:?"slot1"?},?[
??????????_vm._v("Base?slot")
????????]),
????????_vm._v("?"),
????????_c("p",?[_vm._v("default?slot")])
??????])
????],
??)
}

我們發(fā)現(xiàn)無論是普通DOM還是組件,都是通過 _c 函數(shù)創(chuàng)建其對應(yīng)的 VNode 的 其實 _c 在 Vue 內(nèi)部就是 createElement 函數(shù)。createElement 函數(shù)會自動檢測第一個參數(shù)是不是普通DOM標簽如果不是普通DOM標簽?zāi)敲?createElement 會將其視為組件,并且創(chuàng)建組件實例,注意組件實例是這個時候才創(chuàng)建的 但是創(chuàng)建組件實例的過程中就面臨一個問題:組件需要知道父級模板中是否傳遞了 slot 以及傳遞了多少,傳遞的是具名的還是不具名的等等。那么子組件如何才能得知這些信息呢?很簡單,假如組件的模板如下

<div>
??<Base>
????<p slot="slot1">Base?slot</p>
????<p>default?slot</p>
??</Base>
</div>

父組件的模板最終會生成父組件對應(yīng)的 VNode,所以以上模板對應(yīng)的 VNode 全部由父組件所有,那么在創(chuàng)建子組件實例的時候能否通過獲取父組件的 VNode 進而拿到 slot 的內(nèi)容呢?即通過父組件將下面這段模板對應(yīng)的 VNode 拿到

<Base>
????<p slot="slot1">Base?slot</p>
????<p>default?slot</p>
??</Base>

如果能夠通過父級拿到這段模板對應(yīng)的 VNode,那么子組件就知道要渲染哪些 slot 了,其實 Vue 內(nèi)部就是這么干的,實際上你可以通過訪問子組件的 this.$vnode 來獲取這段模板對應(yīng)的 VNode

this.$vnode 并沒有寫進 Vue 的官方文檔

子組件拿到了需要渲染的 slot 之后進入到了關(guān)鍵的一步,這一步就是導(dǎo)致高階組件中透傳 slot 給 Base組件 卻無法正確渲染的原因 children的VNode中的context引用父組件實例 其本身的context也會引用本身實例 其實是一個東西

console.log(this.?vnode.context===this.vnode.componentOptions.children[0].context) //ture

而 Vue 內(nèi)部做了一件很重要的事兒,即上面那個表達式必須成立,才能夠正確處理具名 slot,否則即使 slot 具名也不會被考慮,而是被作為默認插槽。這就是高階組件中不能正確渲染 slot 的原因

即 高階組件中 本來時父組件和子組件之間插入了一個組件(高階組件),而子組件的 this.$vnode其實是高階組件的實例,但是我們將slot透傳給子組件,slot里 VNode 的context實際引用的還是父組件 所以

console.log(this.vnode.context === this.vnode.componentOptions.children[0].context) // false

最終導(dǎo)致具名插槽被作為默認插槽,從而渲染不正確。

決辦法也很簡單,只需要手動設(shè)置一下 slot 中 VNode 的 context 值為高階組件實例即可

function Console (Base) {
  return {
    mounted () {
      console.log(&#39;haha&#39;)
    },
    props: Base.props,
    render (h) {
      const slots = Object.keys(this.$slots)
        .reduce((arr, key) => arr.concat(this.$slots[key]), [])
        // 手動更正 context
        .map(vnode => {
          vnode.context = this._self //綁定到高階組件上
          return vnode
        })
 
      return h(WrappedComponent, {
        on: this.$listeners,
        props: this.$props,
        attrs: this.$attrs
      }, slots)
    }
  }
}

說明白就是強制把slot的歸屬權(quán)給高階組件 而不是 父組件 通過當前實例 _self 屬性訪問當實例本身,而不是直接使用 this,因為 this 是一個代理對象

【相關(guān)推薦:vuejs視頻教程、web前端開發(fā)

Das obige ist der detaillierte Inhalt vonWas sind hochrangige Vue-Komponenten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erkl?rung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Hei?e KI -Werkzeuge

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem v?llig kostenlosen KI-Gesichtstausch-Tool aus!

Hei?e Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Hei?e Themen

PHP-Tutorial
1502
276
Wie geht React mit dem Fokusmanagement und der Zug?nglichkeit um? Wie geht React mit dem Fokusmanagement und der Zug?nglichkeit um? Jul 08, 2025 am 02:34 AM

React selbst verwaltet den Fokus oder die Zug?nglichkeit nicht direkt, sondern bietet Tools, um diese Probleme effektiv zu behandeln. 1. Verwenden Sie Refs, um den Fokus programmgesteuert zu verwalten, z. B. das Festlegen von Elementfokus durch Useref. 2. Verwenden Sie ARIA -Attribute, um die Zug?nglichkeit zu verbessern, z. B. die Definition der Struktur und des Status von Registerkartenkomponenten; 3. achten Sie auf die Tastaturnavigation, um sicherzustellen, dass die Fokuslogik in Komponenten wie Modalboxen klar ist. 4. Versuchen Sie, native HTML -Elemente zu verwenden, um das Arbeitsload und das Fehlerrisiko einer benutzerdefinierten Implementierung zu verringern. 5. React unterstützt die Zug?nglichkeit, indem es das DOM steuert und ARIA -Attribute addiert. Die korrekte Verwendung h?ngt jedoch immer noch von Entwicklern ab.

Serverseitiges Rendering mit Next.js erl?utert Serverseitiges Rendering mit Next.js erl?utert Jul 23, 2025 am 01:39 AM

Server-Siderenderering (SSR) Innext.JSGenerateshtmlontheserverforeachRequest, VerbesserungsprequerformanceAndseo.1.SSRISIDEALFORDYNAMICCONTTHATCHANGESFREQUELFREQUELLE, SHOasUserDashboards.2.

Ein tiefes Eintauchen in die WebAssembly (WASM) für Front-End-Entwickler Ein tiefes Eintauchen in die WebAssembly (WASM) für Front-End-Entwickler Jul 27, 2025 am 12:32 AM

WebAssembly (WASM) Isagame-ChangerForFront-EnddeveloperSeekinghigh-Performancewebapplications.1. GWASMISABINYINTRUCTUCTIONFORMATTHATRUNSATNEAR-NATIVESPEED, EnablingLuageslikerust, C und GotoexecuteintheBrowser.2.

Wie verwaltete ich den Komponentenzustand mit unver?nderlichen Updates in React? Wie verwaltete ich den Komponentenzustand mit unver?nderlichen Updates in React? Jul 10, 2025 pm 12:57 PM

Unver?nderliche Aktualisierungen sind bei React von entscheidender Bedeutung, da sichergestellt wird, dass Zustands?nderungen korrekt erkannt werden k?nnen, wodurch die Neuaufnahme des Komponenten und die Vermeidung von Nebenwirkungen ausgel?st werden. Durch direktes ?ndern des Zustands wie Push oder Zuordnung kann React ?nderungen nicht erkennen k?nnen. Die richtige Art und Weise, dies zu tun, besteht darin, neue Objekte anstelle alter Objekte zu erstellen, z. B. das Aktualisieren eines Arrays oder Objekts mit dem Erweiterungsbetreiber. Für verschachtelte Strukturen müssen Sie Schicht für Schicht kopieren und nur den Zielteil ?ndern, z. Zu den gemeinsamen Vorg?ngen geh?ren das Aktualisieren von Array -Elementen mit Karten, das L?schen von Elementen mit Filtern, das Hinzufügen von Elementen mit Scheiben oder Erweiterungen. Werkzeugbibliotheken wie Immer k?nnen den Prozess vereinfachen und "scheinbar" den ursprünglichen Zustand ?ndern, aber neue Kopien generieren, aber die Projektkomplexit?t erh?hen. Zu den wichtigsten Tipps geh?ren jeweils

Sicherheitsheader für Frontend -Anwendungen Sicherheitsheader für Frontend -Anwendungen Jul 18, 2025 am 03:30 AM

Front-End-Anwendungen sollten Sicherheitsheader einstellen, um die Sicherheit zu verbessern, einschlie?lich: 1. Konfigurieren Sie grundlegende Sicherheitsheader wie CSP, um XSS, X-In-Inhalts-Typ-Optionen zu verhindern, um MIME-Erraten, X-Frame-Optionen zu verhindern, um Klick-Hijacking, X-XSS-Protekte zu verhindern, an diehbare alte Filter, HSTS-HSTS to-Kraft-HTTPs. 2. CSP-Einstellungen sollten vermeiden, unsichere In-Linien und unsichere Eval zu verwenden, Nonce oder Hash zu verwenden und den Berichtstests zu aktivieren. 3. HTTPS-bezogene Header umfassen die automatische Upgrade-Anforderung von HSTS und Referrer-Policy, um den Referator zu steuern. 4. Andere empfohlene Header wie Permis

Was sind benutzerdefinierte Datenattribute (Daten-*)? Was sind benutzerdefinierte Datenattribute (Daten-*)? Jul 10, 2025 pm 01:27 PM

Das Datenattribut wird in HTML verwendet, um zus?tzliche Daten zu speichern, und die Vorteile umfassen, dass die Daten eng mit Elementen zusammenh?ngen und die HTML5-Standards entsprechen. 1. Bei der Verwendung beginnt es mit Daten, z. B. Datenprodukt-ID; 2. Es kann über JavaScripts GetArttribute oder Datensatz zugegriffen werden. 3. Die Best Practices sind das Vermeiden sensibler Informationen, eine angemessene Benennung, die Beachtung der Leistung und das Ersetzen des Staatsmanagements.

Anwenden von CSS -Stilen auf skalierbare Vektorgrafiken (SVG) Anwenden von CSS -Stilen auf skalierbare Vektorgrafiken (SVG) Jul 10, 2025 am 11:47 AM

Um SVGs mit CSS zu stylen, müssen Sie zun?chst SVGs Inline in HTML einbetten, um eine feine Kontrolle zu erhalten. 1. Inline SVG erm?glicht es, seine internen Elemente wie oder direkt über CSS ausgew?hlt zu werden und Stile anzuwenden, w?hrend externe SVG nur globale Stile wie Breite und H?he oder Filter unterstützt. 2. Verwenden Sie die regul?re CSS-Syntax wie .class: HOVER, um interaktive Effekte zu erzielen, aber verwenden Sie Füll anstelle von Farbe, um die Farbe zu steuern, und verwenden Sie Hub und Schlaganfall, um den Umriss zu steuern. 3. Verwenden Sie Klassennamen, um Stile zu organisieren, um Doppelarbeit zu vermeiden und auf Namenskonflikte und das Umfangsmanagement zu achten. 4. Der SVG -Stil kann von der Seite von SVG*{fill: Keine; Schlaganfall: Keine;} zu vermeiden, kann durch SVG*{FILL: Keine zurückgesetzt werden

Wie füge ich einer Website einen Favicon hinzu? Wie füge ich einer Website einen Favicon hinzu? Jul 09, 2025 am 02:21 AM

Das Hinzufügen von Website Favicon erfordert die Vorbereitung von Symboldateien, das Bestehen des richtigen Pfades und das Zitieren. 1. Bereiten Sie Multisize .ico- oder .png-Symbole vor, die von Online-Tools generiert werden k?nnen. 2. Favicon.ICo in das Root -Verzeichnis der Website; 3. Wenn Sie den Pfad anpassen oder mehr Ger?te unterstützen müssen, müssen Sie eine Link -Tag -Referenz in die HTMLHEAD hinzufügen. 4. L?schen Sie den Cache oder verwenden Sie das Tool, um zu überprüfen, ob es effektiv ist.

See all articles