2017-09-19 1 views
2

Was ich zu erreichen versuche

Ich versuche, eine gute Architektur für die Anwendung herauszufinden, die ich arbeite.VueJS Komponente Systemarchitektur

Wenn Sie sich screenshots of the current version of our application ansehen, sehen Sie Tabellen/Listen von Daten in verschiedenen Formaten. Die Tabelle im zweiten Screenshot hat eine eigene Navigation. In einigen Fällen können Tabellenzeilen ausgewählt werden. Auf anderen Bildschirmen kann die Liste der Elemente nach bestimmten Schlüsselwörtern gefiltert werden und so weiter.

Das Frontend wird in VueJS neu aufgebaut. Anstatt für jeden einzelnen Bildschirm einzelne Komponenten zu erstellen, möchte ich eine allgemeinere Lösung haben, die ich in der gesamten Anwendung verwenden kann.

Was ich brauche, ist ein System von Komponenten, wo die Wurzel eine Reihe von Daten enthält und die Kinder (möglicherweise mehrere) Darstellungen dieser Daten bereitstellen. Die Root-Komponente enthält auch - meist benutzerdefiniert - Config, Filter und Selektionen, mit denen die Repräsentationen gesteuert werden.

Was ich versuche zu erreichen, ist am besten mit some pseudocode veranschaulicht.

Fragen

Was ist der beste Weg, um die Daten zu speichern? Wie sollen die Kindkomponenten auf diese Daten zugreifen?

Die Daten von data-display mit Requisiten zu jedem seiner Kinder zu übergeben scheint mir umständlich. Zumal die Darstellungen impliziten Zugriff auf diese Daten haben.

Soll ich Vuex dafür verwenden? Wie würde das mit mehreren Instanzen von data-display funktionieren? Ich habe etwas über die dynamische Modulregistrierung gelesen, könnte das nützlich sein?

Gibt es bessere Möglichkeiten? Jede Hilfe wird sehr geschätzt!

Antwort

1

Ich bin mir nicht sicher, dass ich alle Details Ihrer Anforderungen erfassen, aber die Daten sind auf mehreren "Seiten" im SPA üblich. Ich würde auf jeden Fall Vuex empfehlen:

  • gleiche Daten für alle Seiten
  • Zugriff über Komponenten berechnet Eigenschaften, die reaktiven Änderungen zu speichern, sondern auch Neuberechnung speichern im Cache gespeichert, wenn keine Änderungen in Abhängigkeiten
  • sparen eine Menge von potenziell komplexen Weitergabe von Daten in Requisiten (nach unten) und Ereignissen (nach oben)

Mit Blick auf den Pseudocode, haben Sie drei Arten von Filtern auf t er Seitenleiste. Fügen Sie diese Daten ebenfalls in den Speicher ein. Dann können berechnete Eigenschaften in Ansichten Filter auf die Daten anwenden. Die Berechnungslogik wird dann einfach isoliert getestet.

child.vue

<template> 
    <div>{{ myChildData.someProperty }}</div> 
</template> 

<script> 
export default { 
    props: [...], 
    data: function() { 
    return { 
     selection: 'someValue' // set this by, e.g, click on template 
    } 
    }, 
    computed: { 
    myChildData() { 
     return this.$store.getters.filteredData(this.selection) 
    } 
    } 
} 
</script> 

speichern.js

const state = { 
    myData: { 
    ... 
    }, 
    filters: { // set by dispatch from sidebar component 
    keyword: ..., 
    toggle: ..., 
    range: ... 
    }, 
} 

const getters = { 
    filteredData: state => { 
    return childSelection => { // this extra layer allows param to be passed 
     return state.myData 
     .filter(item => item.someProp === state.filters.keyword) 
     .filter(item => item.anotherProp === childSelection) 
    } 
    }, 
} 

const mutations = { 
    'SET_DATA' (state, payload) { 
    ... 
    }, 
    'SET_FILTER' (state, payload) { 
    ... 
    } 
} 

export default { 
    state, 
    getters, 
    mutations, 
} 

Allgemein Kinder

Es gibt wahrscheinlich viele Möglichkeiten, dies zu bewältigen. Ich habe Komposition verwendet, was bedeutet, dass eine dünne Komponente für jedes Kind eine gemeinsame Komponente verwendet, aber Sie brauchen diese nur, wenn das Kind bestimmte Daten oder ein eindeutiges Markup hat, das in einen Slot eingefügt werden kann.

child1.vue

<template> 
    <page-common :childtype="childType"> 
    <button class="this-childs-button" slot="buttons"></button> 
    </page-common> 
</template> 

<script> 
import PageCommon from './page-common.vue' 
export default { 
    props: [...], 
    data: function() { 
    return { 
     childType: 'someType' 
    } 
    }, 
    components: { 
    'page-common': PageCommon, 
    } 
} 
</script> 

page-common.vue

<template> 
    ... 
    <slot name="buttons"></slot> 
</template> 

<script> 
export default { 
    props: [ 
    'childtype' 
    ], 
    data: function() { 
    return { 
     ... 
    } 
    }, 
} 
</script> 

mehrere Instanzen von Daten

Wieder viele Variationen - ich verwenden, um ein Objekt mit Eigenschaften, wie Index, so Speicher wird

store.js

const state = { 
    myData: { 
    page1: ..., // be sure to explicitly name the pages here 
    page2: ..., // otherwise Vuex cannot make them reactive 
    page3: ..., 
    }, 
    filters: { // set by dispatch from sidebar component 
    keyword: ..., 
    toggle: ..., 
    range: ... 
    }, 
} 

const getters = { 
    filteredData: state => { 
    return page, childSelection => { // this extra layer allows param to be passed 
     return state.myData[page] // sub-select the data required 
     .filter(item => item.someProp === state.filters.keyword) 
     .filter(item => item.anotherProp === childSelection) 
    } 
    }, 
} 

const mutations = { 
    'SET_DATA' (state, payload) { 
    state.myData[payload.page] = payload.myData 
    }, 
    'SET_FILTER' (state, payload) { 
    ... 
    } 
} 

export default { 
    state, 
    getters, 
    mutations, 
}