Heim Web-Frontend HTML-Tutorial Detaillierte Einführung in Front-End-Responsive-Programmierlösungen und deren Mängel (mit Code)

Detaillierte Einführung in Front-End-Responsive-Programmierlösungen und deren Mängel (mit Code)

Aug 14, 2018 pm 03:14 PM

Dieser Artikel bietet Ihnen eine detaillierte Einführung in die Front-End-Responsive-Programmierung und ihre Mängel (mit Code). Ich hoffe, dass er für Sie hilfreich ist. helfen.

Viele Dinge in der realen Welt funktionieren responsiv. Wir werden beispielsweise Fragen von anderen entgegennehmen und dann antworten und entsprechende Antworten geben. Während des Entwicklungsprozesses habe ich auch viel Responsive Design angewendet und einige Erfahrungen gesammelt, in der Hoffnung, andere zu inspirieren.

Der Hauptunterschied zwischen reaktiver Programmierung und gewöhnlicher Programmierung besteht darin, dass die reaktive Programmierung im Push-Modus funktioniert, während die nicht-reaktive Programmierung im Pull-Modus funktioniert. Ereignisse sind zum Beispiel eine sehr häufige reaktive Programmierung:

button.on('click', () => {  
    // ...})
Nach dem Login kopieren

Auf nicht-reaktive Weise wird es so aussehen:

while (true) {  
    if (button.clicked) {        // ...
    }
}
Nach dem Login kopieren

Natürlich, egal ob in Bezug auf In Bezug auf Code-Eleganz und Ausführungseffizienz sind nicht-responsive Methoden nicht so gut wie responsive Designs.

Event Emitter

Event Emitter ist eine Event-Implementierung, mit der die meisten Menschen vertraut sind. Sie ist sehr einfach und praktisch. Wir können Event Emitter verwenden, um einfaches Responsivitätsdesign zu implementieren B. die folgende asynchrone Suche:

class Input extends Component {  
    state = {        value: ''
    }
    onChange = e => {        this.props.events.emit('onChange', e.target.value)
    }
    afterChange = value => {        this.setState({
            value
        })
    }
    componentDidMount() {        this.props.events.on('onChange', this.afterChange)
    }
    componentWillUnmount() {        this.props.events.off('onChange', this.afterChange)
    }
    render() {        
    const { value } = this.state        
    return (            <input value={value} onChange={this.onChange} />
        )
    }
}
class Search extends Component {  
    doSearch = (value) => {
        ajax(/* ... */).then(list => this.setState({
            list
        }))
    }
    componentDidMount() {
        this.props.events.on(&#39;onChange&#39;, this.doSearch)
    }
    componentWillUnmount() {
        this.props.events.off(&#39;onChange&#39;, this.doSearch)
    }
    render() {
        const { list } = this.state
        return (            <ul>
                {list.map(item => <li key={item.id}>{item.value}</li>)}            </ul>
        )
    }
}
Nach dem Login kopieren

Hier werden wir feststellen, dass die Implementierung von Event Emitter viele Mängel aufweist und wir Ressourcen in ComponentWillUnmount manuell freigeben müssen. Seine Ausdruckskraft reicht beispielsweise nicht aus, wenn wir bei der Suche mehrere Datenquellen aggregieren müssen:

class Search extends Component {  
    foo = &#39;&#39;
    bar = &#39;&#39;
    doSearch = () => {
        ajax({
            foo,
            bar
        }).then(list => this.setState({
            list
        }))
    }
    fooChange = value => {        this.foo = value        this.doSearch()
    }
    barChange = value => {        this.bar = value        this.doSearch()
    }
    componentDidMount() {        this.props.events.on(&#39;fooChange&#39;, this.fooChange)        this.props.events.on(&#39;barChange&#39;, this.barChange)
    }
    componentWillUnmount() {        this.props.events.off(&#39;fooChange&#39;, this.fooChange)        this.props.events.off(&#39;barChange&#39;, this.barChange)
    }
    render() {        // ...
    }
}
Nach dem Login kopieren

Offensichtlich ist die Entwicklungseffizienz sehr gering.

Redux

Redux verwendet einen Ereignisstrom, um Reaktivität zu implementieren. Da der Reduzierer eine reine Funktion sein muss, ist die einzige Möglichkeit, Reaktivität zu implementieren oder in Middleware.

Wenn Sie den Store abonnieren, kann Redux nur Dirty Checking verwenden, da es nicht genau ermitteln kann, welche Daten sich geändert haben. Zum Beispiel:

function createWatcher(mapState, callback) {  
    let previousValue = null
    return (store) => {
        store.subscribe(() => {            const value = mapState(store.getState())            if (value !== previousValue) {
                callback(value)
            }
            previousValue = value
        })
    }
}const watcher = createWatcher(state => {  
    // ...}, () => {    // ...})
Nach dem Login kopieren

watcher(store)

Diese Methode hat zwei Nachteile: Zum einen treten Effizienzprobleme auf, wenn die Daten komplex und die Datenmenge relativ groß ist ; Ja, es wäre schwierig, wenn die Funktion „mapState“ auf dem Kontext basieren würde. In React-Redux ist der zweite Parameter von MapStateToProps in der Connect-Funktion Props, die über die obere Komponente übergeben werden können, um den erforderlichen Kontext zu erhalten. Auf diese Weise wird der Listener jedoch zu einer React-Komponente und wird so gemountet, wie die Komponente Und das Entladen wird erstellt und zerstört. Wenn wir möchten, dass diese Reaktionsfähigkeit unabhängig von Komponenten ist, wird es ein Problem geben.

Eine andere Möglichkeit besteht darin, Datenänderungen in der Middleware zu überwachen. Dank des Redux-Designs können wir die entsprechenden Datenänderungen erhalten, indem wir bestimmte Ereignisse (Aktionen) abhören.

const search = () => (dispatch, getState) => {  
    // ...}const middleware = ({ dispatch }) => next => action => {  
    switch action.type {        case &#39;FOO_CHANGE&#39;:        case &#39;BAR_CHANGE&#39;: {            const nextState = next(action)            // 在本次dispatch完成以后再去进行新的dispatch
            setTimeout(() => dispatch(search()), 0)            return nextState
        }        default:            return next(action)
    }
}
Nach dem Login kopieren

Diese Methode kann die meisten Probleme lösen, aber in Redux abonnieren Middleware und Reduzierer tatsächlich implizit alle Ereignisse (Aktion), was offensichtlich unvernünftig ist, obwohl es keine Leistung gibt Unter der Prämisse der Frage ist es vollkommen akzeptabel .

Objektorientierte Reaktionsfähigkeit

ECMASCRIPT 5.1 führt Getter und Setter ein, und wir können eine Reaktionsfähigkeit durch Getter und Setter implementieren.

class Model {  
    _foo = &#39;&#39;
    get foo() {        return this._foo
    }
    set foo(value) {        this._foo = value        this.search()
    }
    search() {        // ...
    }
}// 当然如果没有getter和setter的话也可以通过这种方式实现class Model {  
    foo = &#39;&#39;
    getFoo() {        return this.foo
    }
    setFoo(value) {        this.foo = value        this.search()
    }
    search() {        // ...
    }
}
Nach dem Login kopieren

Mobx und Vue verwenden diese Methode, um Reaktionsfähigkeit zu implementieren. Natürlich können wir Proxy auch verwenden, wenn die Kompatibilität nicht berücksichtigt wird.

Wenn wir auf mehrere Werte reagieren und dann einen neuen Wert erhalten müssen, können wir dies in Mobx tun:

class Model {  
    @observable hour = &#39;00&#39;
    @observable minute = &#39;00&#39;
    @computed get time() {        return `${this.hour}:${this.minute}`
    }
}
Nach dem Login kopieren

Mobx sammelt zur Laufzeit die Werte, von denen die Zeit abhängt , und verwenden Sie diese Die Neuberechnung des Zeitwerts, wenn sich der Wert ändert (Auslösen des Setters), ist offensichtlich viel bequemer und effizienter als die EventEmitter-Methode und intuitiver als die Redux-Middleware.

Hier gibt es jedoch auch einen Nachteil. Das auf dem Getter basierende berechnete Attribut kann jedoch in vielen Fällen nur die Situation von y = f(x) beschreiben werde y = warte auf f( x), Getter kann diese Situation nicht beschreiben.

In dieser Situation können wir die von Mobx bereitgestellte Autorun-Funktion verwenden, um Folgendes zu erreichen:

class Model {  
    @observable keyword = &#39;&#39;
    @observable searchResult = []    constructor() {
        autorun(() => {            // ajax ...
        })
    }
}
Nach dem Login kopieren

Da der Erfassungsprozess von Laufzeitabhängigkeiten vollständig implizit ist, tritt hier häufig ein Problem bei der Erfassung unerwarteter Abhängigkeiten auf:

class Model {  
    @observable loading = false
    @observable keyword = &#39;&#39;
    @observable searchResult = []    constructor() {
        autorun(() => {            if (this.loading) {                return
            }            // ajax ...
        })
    }
}
Nach dem Login kopieren

Offensichtlich sollte das Laden hier nicht durch den gesuchten Autorun erfasst werden. Um dieses Problem zu lösen, wird etwas zusätzlicher Code hinzugefügt, und der zusätzliche Code birgt leicht die Möglichkeit für Fehler. Alternativ können wir die erforderlichen Felder auch manuell angeben, aber diese Methode erfordert einige zusätzliche Vorgänge:

class Model {  
    @observable loading = false
    @observable keyword = &#39;&#39;
    @observable searchResult = []
    disposers = []
    fetch = () => {        // ...
    }
    dispose() {        this.disposers.forEach(disposer => disposer())
    }    constructor() {        this.disposers.push(
            observe(this, &#39;loading&#39;, this.fetch),
            observe(this, &#39;keyword&#39;, this.fetch)
        )
    }
}class FooComponent extends Component {  
    this.mode = new Model()
    componentWillUnmount() {        this.state.model.dispose()
    }    // ...}
Nach dem Login kopieren

Und wenn wir die Zeitleiste beschreiben müssen, ist Mobx etwas unzureichend. Beispielsweise müssen Sie die Suche verzögern 5 Sekunden.

Verwandte Empfehlungen:

Puzzle-responsive Front-End-Framework-Version des responsiven Backends offiziell veröffentlicht_html/css_WEB-ITnose

Verwendung ein sehr einfaches responsives Front-End-Entwicklungsframework_html/css_WEB-ITnose


Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in Front-End-Responsive-Programmierlösungen und deren Mängel (mit Code). 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

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.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
2 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Repo: Wie man Teamkollegen wiederbelebt
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Abenteuer: Wie man riesige Samen bekommt
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

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)

Schwierigkeiten bei der Aktualisierung der Zwischenspeicherung offizieller Konto -Webseiten: Wie vermeiden Sie den alten Cache, der sich auf die Benutzererfahrung nach der Versionsaktualisierung auswirkt? Schwierigkeiten bei der Aktualisierung der Zwischenspeicherung offizieller Konto -Webseiten: Wie vermeiden Sie den alten Cache, der sich auf die Benutzererfahrung nach der Versionsaktualisierung auswirkt? Mar 04, 2025 pm 12:32 PM

Das offizielle Konto -Webseite aktualisiert Cache, dieses Ding ist einfach und einfach und es ist kompliziert genug, um einen Topf davon zu trinken. Sie haben hart gearbeitet, um den offiziellen Account -Artikel zu aktualisieren, aber der Benutzer hat die alte Version immer noch geöffnet. Schauen wir uns in diesem Artikel die Wendungen und Wendungen und wie man dieses Problem anmutig ansehen. Nach dem Lesen können Sie sich leicht mit verschiedenen Caching -Problemen befassen, sodass Ihre Benutzer immer den frischesten Inhalt erleben können. Sprechen wir zuerst über die Grundlagen. Um es unverblümt auszudrücken, speichert der Browser oder Server einige statische Ressourcen (wie Bilder, CSS, JS) oder Seiteninhalte, um die Zugriffsgeschwindigkeit zu verbessern. Wenn Sie das nächste Mal darauf zugreifen, können Sie ihn direkt aus dem Cache abrufen, ohne ihn erneut herunterzuladen, und es ist natürlich schnell. Aber dieses Ding ist auch ein zweischneidiges Schwert. Die neue Version ist online,

Wie verwende ich HTML5 -Formularvalidierungsattribute, um die Benutzereingabe zu validieren? Wie verwende ich HTML5 -Formularvalidierungsattribute, um die Benutzereingabe zu validieren? Mar 17, 2025 pm 12:27 PM

In dem Artikel werden unter Verwendung von HTML5 -Formularvalidierungsattributen wie Erforderlich, Muster, Min, MAX und Längengrenzen erörtert, um die Benutzereingabe direkt im Browser zu validieren.

Was sind die besten Praktiken für die Kompatibilität des Cross-Browsers in HTML5? Was sind die besten Praktiken für die Kompatibilität des Cross-Browsers in HTML5? Mar 17, 2025 pm 12:20 PM

In Artikel werden Best Practices zur Gewährleistung der HTML5-Cross-Browser-Kompatibilität erörtert und sich auf die Erkennung von Merkmalen, die progressive Verbesserung und die Testmethoden konzentriert.

Wie füge ich PNG -Bildern auf Webseiten effizient Schlaganfalleffekte hinzu? Wie füge ich PNG -Bildern auf Webseiten effizient Schlaganfalleffekte hinzu? Mar 04, 2025 pm 02:39 PM

Dieser Artikel zeigt einen effizienten PNG -Grenzzusatz zu Webseiten mithilfe von CSS. Es wird argumentiert, dass CSS im Vergleich zu JavaScript oder Bibliotheken eine überlegene Leistung bietet, um zu beschreiben, wie die Randbreite, Stil und Farbe für subtile oder herausragende Effekte angepasst werden können

Was ist der Zweck des & lt; datalist & gt; Element? Was ist der Zweck des & lt; datalist & gt; Element? Mar 21, 2025 pm 12:33 PM

Der Artikel erörtert den HTML & lt; Datalist & gt; Element, das die Formulare verbessert, indem automatische Vorschläge bereitgestellt, die Benutzererfahrung verbessert und Fehler reduziert werden.Character Count: 159

Wie benutze ich die HTML5 & lt; Zeit & gt; Element, um Daten und Zeiten semantisch darzustellen? Wie benutze ich die HTML5 & lt; Zeit & gt; Element, um Daten und Zeiten semantisch darzustellen? Mar 12, 2025 pm 04:05 PM

Dieser Artikel erklärt den HTML5 & lt; Time & gt; Element für semantische Datum/Uhrzeit. Es betont die Wichtigkeit des DateTime-Attributs für die Maschinenlesbarkeit (ISO 8601-Format) neben menschenlesbarem Text, das Zubehör steigert

Was ist der Zweck des & lt; Fortschritts & gt; Element? Was ist der Zweck des & lt; Fortschritts & gt; Element? Mar 21, 2025 pm 12:34 PM

Der Artikel erörtert den HTML & lt; Progress & gt; Element, Absicht, Styling und Unterschiede vom & lt; Meter & gt; Element. Das Hauptaugenmerk liegt auf der Verwendung & lt; Fortschritt & gt; Für Aufgabenabschluss und & lt; Meter & gt; für stati

Was ist der Zweck des & lt; Meter & gt; Element? Was ist der Zweck des & lt; Meter & gt; Element? Mar 21, 2025 pm 12:35 PM

Der Artikel erörtert das HTML & lt; Meter & gt; Element, verwendet zur Anzeige von Skalar- oder Bruchwerten innerhalb eines Bereichs und seine gemeinsamen Anwendungen in der Webentwicklung. Es differenziert & lt; Meter & gt; von & lt; Fortschritt & gt; und Ex

See all articles