Vue: [2.0] Vorlagen für Funktionskomponenten

Erstellt am 18. Okt. 2016  ·  34Kommentare  ·  Quelle: vuejs/vue

Ich möchte Vorlagen und .vue Dateien für Funktionskomponenten genauso schreiben können wie Standardkomponenten.

Ich habe einen Proof-of-Concept in dieser Geige gemacht , aber es ist ziemlich hackig. Vielleicht könnte der Template-Compiler eine functional Option haben, um die resultierenden Funktionen besser an das context Objekt und nicht an this anzupassen.

Es würde so aussehen:

Vue.component('test', {
  functional: true',
  props: ['msg'],
  template: `<div>
    <h1>{{props.msg}}</h1>
    <h2>Static content</h2>
    <span v-for="n in 10">{{n}} </span>
    <button @click="console.log('click', props.msg)"><slot></slot></button>
  </div>`,
});

Oder:

<template>
  <div class="test">
    <h1>{{props.msg}}</h1>
    <h2>Static content</h2>
    <span v-for="n in 10">{{n}} </span>
    <button @click="console.log('click', props.msg)"><slot></slot></button>
  </div>
</template>

<script>
export default {
  functional: true,
  props: ['msg'],
}
</script>

<style scoped>
.test {
  margin: 12;
}
</style>
feature request

Hilfreichster Kommentar

Es kommt bald.

Alle 34 Kommentare

Wir haben dies bereits als Option auf unserer Roadmap. Wir werden dies jedoch verschieben, bis 2.0 aus der aktuellen Post-Release-Phase heraus ist und alle Arbeiten, die wir im Ökosystem für 2.0 noch übrig haben, erledigt sind, da dies mit einem erheblichen Aufwand verbunden ist, um es richtig zu machen, zu testen und so weiter (auch , vue-loader/vueify damit arbeiten lassen usw. pp.)

Danke für den PoC, scheint hilfreich zu sein!

Ja bitte.
Ich habe mir genau das angeschaut. Für mich sind die Renderfunktionen zu überwältigend und "fühlt" sich unzusammenhängend vom Gesamtgefühl einer einzelnen Dateikomponente an.

Was für mich am nützlichsten wäre, wäre, CSS auf funktionale Komponenten zu beschränken.

Können wir eine Statusaktualisierung zu dieser funktionalen Einzeldateikomponente erhalten? Ich komme von React und vermisse das ziemlich.

Es kommt bald.

Kann mir jemand für eine n00b erklären, was das Neue an dieser gegenüber dem ist, was wir jetzt haben?

Sie können Funktionskomponenten mit .vue Dateien wie folgt erstellen:

<template functional>
  <div class="test">
    <h1>{{props.msg}}</h1>
    <h2>Static content</h2>
    <span v-for="n in 10">{{n}} </span>
    <button @click="console.log('click', props.msg)"><slot></slot></button>
  </div>
</template>

<script>
export default {
  props: ['msg'],
}
</script>

<style scoped>
.test {
  margin: 12;
}
</style>

Ahh okay danke!!

Das sieht gut aus. Haben Sie eine Vorstellung vom Zeitrahmen für die Veröffentlichung dieser Funktion?

Dies wird die Verwendung von Funktionskomponenten so viel einfacher machen!

irgendwelche Updates zu diesem Thema? Wird es Teil der Version 2.3 sein?

@Akryum Kennen Sie den Status dieses Problems? Es scheint, als wäre es seit Monaten in der Schwebe. Gibt es etwas, was wir tun können, um dies voranzutreiben?

/ping @blake-newman

Gibt es Neuigkeiten zu dieser Funktion?

Anscheinend wurde im Februar damit begonnen: https://github.com/vuejs/vue/tree/feature/fn-templates

Gibt es dazu ein Update? Es ist jetzt schon eine Weile offen - kann man etwas tun, um dieses Problem zu lösen?

@Akryum seit deinem Teaser im Februar scheint dies tot im Wasser zu sein. @blake-newman Wie ich sehe, wurdest du vor ein paar Monaten gepingt, hast du irgendwelche Informationen zu diesem Problem?

Es tut mir leid, wenn das nervig wird, ich würde nur gerne wissen, wie wir das umsetzen können :)

@scottbedard Ich habe daran gearbeitet, es gab ein paar versteckte Fallstricke. Diese könnten jedoch nur als unbrauchbare Funktionen dokumentiert werden. Die Arbeit wurde vor einiger Zeit erledigt und entspricht leider nicht dem aktuellen Stand des Rendering-Systems, so dass Arbeit geleistet werden muss.

@vuejs/collaborators Was halten Sie von dieser Funktion insgesamt, ist der Entwicklungsaufwand und die zusätzlichen Kosten für den Kern diese Funktion wert?

Ich denke, wenn es eine nette Funktion ist, da die Standardmethode zum Schreiben von Komponenten die Verwendung der Vorlagen ist. Und IMHO alle Rendering-Funktionen von den Komponenten (die im Templates-Compiler verwendet werden) zu entkoppeln, wäre großartig.

Das Problem besteht darin, dass der Umfang der funktionalen Verwendung von Vorlagen viel mehr begrenzt ist als die Verwendung von JSX/Render-Funktionen. EIN

Ich denke, beim Erstellen funktionaler Komponenten passen die Einschränkungen und Entwurfsmuster nicht zu einem Vorlagenmodell. Diese Funktion erfordert etwas zusätzliche Laufzeit (https://github.com/vuejs/vue/commit/f63203310f01e9f0813e0316c308f9f21d0ee717#diff-4d479bb000ed54582de8e4cd8318ef64R157) und wird niemals die gleiche Leistung wie reine Renderfunktionen haben.

Wenn Sie diese Funktion aktivieren, wird eine bessere Leistung vorausgesetzt, im Vergleich zu reinen Renderfunktionen ist dies nicht der Fall. Meine Haltung zu dieser Funktion ist im Moment, dass sie nur Vorlagen zur Verwendung von Funktionen befähigt, aber keine echte Belohnung bietet.

Außerdem wäre es schön, eine bereichsbezogene Stilunterstützung für funktionale Komponenten zu haben, aber dies kann nicht zusammenhängen.

Das hat nichts damit zu tun, ich glaube das funktioniert. Daran habe ich schon gearbeitet. Es sei denn, es gibt eine Regression?

Die funktionalen Komponenten von Vue sind im Vergleich zu React etwas hässlich. template weit weniger funktional als jsx . Vielleicht können Sie vue-loader für die Konvertierungsverarbeitung ausleihen, hoffentlich so:

<script functional>
const DumbCmp = props => (
  <Button>{props.label}</Button>
);

export default DumbCmp;
</script>

tatsächlich haben einige Jungs diesen Serval vor Monaten gemacht https://github.com/nickmessing/babel-plugin-jsx-vue-functional

Ja, Vue 2.5 + vue-loader 13.3 wird die richtige Unterstützung für die Kompilierung von Vorlagen, Scoped CSS und Hot-Reload für funktionale Komponenten bieten :)

Ist es möglich, von Funktionskomponenten $emittieren zu können?

Wenn ich mich nicht irre, lautet die kurze Antwort nein. Eine funktionale Komponente ist keine Instanz und hat daher keine Methoden.

Ich glaube, dass Sie durch einige Hacker tatsächlich emittieren können. Das Kontextobjekt, das der Render-Fn empfängt, enthält ein parent das immer eine vue-Instanz sein sollte. Sie können sich für context.parent.$emit() oder context.parent.$root.$emit() , um einen globaleren Ansatz zu wählen. Wie Sie sehen, wird dies nicht von der funktionalen Komponente ausgegeben, sodass dies je nach Anwendungsfall wahrscheinlich nicht die beste Lösung ist.

Hey, ich habe daran geforscht, einige unserer Dashboard-Elemente zu optimieren und die Funktion einer SFC-Komponente großartig klingen zu lassen, aber ich werde dort keine Methoden oder berechneten Requisiten haben können, oder?
Wenn ich eine Renderfunktion oder JSX verwende, kann ich diese zumindest in der Renderfunktion selbst definieren, richtig?

Ist es möglich, von Funktionskomponenten $emittieren zu können?

Sie können auf das Objekt listeners im funktionalen Kontext zugreifen. Zum Beispiel:

<my-functional-component @request-something="onRequestSomething" />

Rufen Sie den Listener wie eine Methode innerhalb von my-functional-component :

listeners['request-something'](42)

Wenn ich eine Renderfunktion oder JSX verwende, kann ich diese zumindest in der Renderfunktion selbst definieren, richtig?

Jawohl.

@Akryum danke. Größere, vorlagenlastigere Funktionskomponenten sind mit JSX möglicherweise besser dran, da Standard-Renderfunktionen die Lesbarkeit etwas erschweren würden. Ein fortgeschritteneres Tutorial dazu wäre wirklich süß :)

Sie müssen keine Renderfunktion mehr mit Funktionskomponenten verwenden.
Sie können Vorlagen verwenden

Am Freitag, 5. Januar 2018 um 4:53 Uhr, Dobromir Hristov [email protected]
schrieb:

@Akryum https://github.com/akryum danke. Größer, schwerer Schablonen
func-Komponenten könnten mit JSX besser dran sein, da Standard-Rendering
Funktionen würden die Lesbarkeit etwas erschweren. Ein fortgeschritteneres Tutorial
darauf wäre echt süß :)


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/vuejs/vue/issues/3977#issuecomment-355514921 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AACouk0kTLUHRjQDnXj2vn2v4Rq7maXOks5tHfExgaJpZM4KaIfu
.

@blocka wie verwenden Sie eine Funktion, um etwas zu tun? zum Beispiel ein Diagramm instanziieren?

es sei denn, Sie rendern ein Diagramm vollständig mit vnodes, benötigen Sie a
reguläre Komponente mit Lifecycle-Methoden, um dies zu tun

Am Freitag, 5. Januar 2018 um 5:41 Uhr, Dobromir Hristov [email protected]
schrieb:

@blocka https://github.com/blocka wie werden Sie eine Funktion verwenden ?
etwas? zum Beispiel ein Diagramm instanziieren?


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/vuejs/vue/issues/3977#issuecomment-355524605 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AACouvWQNer0XUjuzBDHgePpZQ-D2DAWks5tHfx2gaJpZM4KaIfu
.

@Akryum Ihre Lösung funktioniert, aber ich habe das Gefühl, dass funktionale sfc-Vorlagen etwas mehr Liebe gebrauchen könnten. Ich bin dabei, mehrere Komponenten neu zu schreiben, die von Anfang an hätten funktionieren können, und ich bin von der Erfahrung etwas enttäuscht. Die sfc verfügt bereits über einen Kontext, auf den über die Vorlage für props und listeners zugegriffen werden kann. Könnten diese Eigenschaften nicht einfach dem 'root' für Requisiten und '$emit' für Listener zugeordnet werden, damit jeder SFC-Typ mit derselben API arbeiten kann.

<template functional>
    <div @click="listeners['request-something'](42)">
        {{props.hello}}
        {{props.world}}
    </div>
</template>

<script>
export default {
    props: ["hello", "world"]
}
</script>

könnte werden

<template functional>
    <div @click="$emit('request-something', 42)">
        {{hello}}
        {{world}}
    </div>
</template>

<script>
export default {
    props: ["hello", "world"]
}
</script>
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen