Att bygga en RSS-Viewer Med Vue: Del 2

0
29

Välkommen till Del 2 av denna mini-serie på att bygga en RSS-viewer med Vue. I förra inlägget gick jag igenom hur jag byggde min demo med Vue.js och Vuetify på fronten och Webtask på baksidan slutet. När jag byggde den första versionen, jag visste att det var exakt thatmdash;en “första” versionen. Jag tog en del tid att arbeta med några uppdateringar, och även om jag inte vågar kalla detta en “perfekt” version, jag tror att jag har gjort vissa förbättringar, och jag vill dela dem med dig.

Artikel-Serien:

  1. Installation och första iteration
  2. Förbättringar och slutliga versionen (Detta Inlägg)

Innan jag komma igång, här är länkar till färdig demo och källkod.

Visa Demo Visa Kod

Känn dig fri att gaffel, fil PRs, och rapportera buggar till ditt hjärta innehåll!

Planen

När jag delade den första versionen i Del 1, som jag skisserat några idéer för att förbättra RSS-läsare, bland annat:

  • Flyttar till Vuex.
  • Börjar byta till komponenter i layouten. (Ja, jag var redan använder Vuetify komponenter, men jag menade anpassade komponenter för min ansökan.)
  • Med hjälp av IndexedDB att lagra foder objekt för snabbare åtkomst och offline-stöd.

Det var planen, och som de flesta planer, jag var inte nödvändigtvis kunna slå allt i den här uppdateringen (och jag ska förklara varför i slutet). Men förhoppningsvis kommer du att se de förbättringar som en allmän “i rätt riktning” för programmet. Med det ur vägen, låt oss komma igång!

Att Genomföra Vuex

Jag ska börja diskutera den största förändringen till ansökan, förutom av Vuex. Som jag sa i tidigare inlägg, Vuex beskriver sig själv som en “statlig förvaltning mönster + biblioteket” på deras “Vad är Vuex” sida. Inte illa för att deras dokumentation, men jag hade en svår tid omslag mitt huvud kring exakt vad detta innebar, från en praktisk mening.

Efter att ha använt det i några små projekt nu, jag kommer att uppskatta vad det ger. För mig är kärnan fördel är att tillhandahålla ett centralt gränssnitt för dina data. Om jag har fått en grundläggande Vue app som arbetar med en array av värden, jag kan ha flera olika metoder att ändra det. Vad händer när jag börjar har vissa regler som måste följas innan uppgifterna ändras? Som ett enkelt exempel, föreställ dig en mängd RSS-feeds. Innan jag lägger till en ny, jag vill säkerställa att det inte redan finns i listan. Om jag har en metod som lägger till i kanallistan, det är inte ett problem, men om jag har mer, kan det bli besvärligt att hålla denna logik i synk över olika metoder. Jag kunde helt enkelt bygga ett verktyg för att göra detta, men vad händer när jag har andra komponenter i spela så bra?

Medan det är absolut inte en en-till-en jämförelse, jag känner mig som Vuex påminner mig om hur Leverantörer eller Tjänster fungerar i Kantiga. Om jag någonsin vill arbeta med andra uppgifter, jag kommer att se till att jag använder en central leverantör för att hantera alla tillgång till informationen. Det är hur jag ser på Vuex.

Så den stora förändringen i denna ansökan var att migrera alla data relaterade poster till en butik. Jag började med att lägga till biblioteket för att min HTML:

<script src=”https://unpkg.com/vuex”></script>

Woot! Halvvägs klar! (OK kanske inte.)

Jag skapade sedan en instans av min butik i min JavaScript-fil:

const feedStore = new Vuex.Store({
// massor av saker här
});

och ingår det i min Vue app:

låt app = new Vue({
el: ‘#app”,
butik:feedStore,
// massor av saker här också…
});

Nu kommer den intressanta delen. Någon gång mitt Vue ansökan behöver uppgifter, som i huvudsak består av lista med inlägg och artiklar från dessa flöden, att det kommer att be butiken för dem. Så, till exempel, mina flöden värde är nu beräknas:

flöden() {
tillbaka feedStore.stat.flöden;
},

Detta är nu definieras i den statliga delen av min butik:

tillstånd: {
allItems: [],
flöden: [],
selectedFeed: null
},

Observera att flöden standard är en tom array. Jag hade tidigare använt den som skapat händelsen i mitt Vue app för att läsa in data från localStorage. Nu vill jag be butiken att göra det:

skapat() {
feedStore.dispatch(‘restoreFeeds’);
},

Tillbaka i butiken, logiken är ganska mycket samma:

restoreFeeds(sammanhang) {
låt feedsRaw = fönster.localStorage.getItem(‘feeds’);
om(feedsRaw) {
try {
låt feeds = JSON.parse(feedsRaw);
sammanhanget.stat.feeds = flöden;
sammanhanget.stat.feeds.forEach(f => {
sammanhanget.dispatch(‘loadFeed’, f);
});
} catch(e) {
konsolen.error(‘Fel återställa json-feed’+e);
// dåliga json eller andra frågan, nuke det
fönster.localStorage.removeItem(‘feeds’);
}
}
},

Jag säger “i stort sett samma” utom nu gör jag lite av felkontroll på värdet läsas från localStorage. Men här är den avgörande biten. Jag har redan sagt att jag misslyckades i termer av att byta till IndexedDB, men i teorin, att jag kunde bygga en tredje versionen av detta program med en uppdaterad lagra och min Vue app kommer inte att veta skillnaden. Och det var där jag började bli riktigt upphetsad. Ju mer jag arbetade, desto mer “dum” min Vue app blev och mindre knutna det var något särskilt genomförandet av lagring. Låt oss titta på den kompletta Vue app nu:

låt app = new Vue({
el: ‘#app”,
butik:feedStore,
data() {
return {
låda:sant,
addFeedDialog:false,
addURL:”,
urlError:false,
urlRules:[],
selectedFeed:null
}
},
beräknad: {
showIntro() {
tillbaka detta.feeds.längd == 0;
},
flöden() {
tillbaka feedStore.stat.flöden;
},
objekt() {
tillbaka feedStore.getter.poster.
}
},
skapat() {
feedStore.dispatch(‘restoreFeeds’);
},
metoder:{
addFeed() {
detta.addFeedDialog = true;
},
allFeeds() {
feedStore.dispatch(‘filterFeed”, null);
},
addFeedAction() {
detta.urlError = false;
detta.urlRules = [];

feedStore.dispatch(‘addFeed’, {url:här.addURL})
.då(res => {
detta.addURL = “;
detta.addFeedDialog = false;
})
.catch(e =>{
konsolen.log(‘err för att lägga till’, e),
detta.urlError = true;
detta.urlRules = [“URL finns redan.”];
});
},
deleteFeed(foder) {
feedStore.dispatch(‘deleteFeed’, foder);
},
filterFeed(foder) {
feedStore.dispatch(‘filterFeed’, foder);
}
}
})

Det du kommer märka är att ganska mycket av den faktiska logik är nu borta och allt jag egentligen gör här är att UI grejer. Öppna en spärrad här, lägg till ett fel finns, och så vidare.

Du kan se hela arkivet här, även om jag ber om ursäkt för att klumpa ihop allt i en fil.

Lägga till en Komponent

En av de andra förändringar som jag nämnde var början till “component-ize” visa lager. Det slutade med att jag bara gör en komponent -, foder-post. Detta minskade det totala antalet rader i HTML-lite:

<v-flex xs12 v-for=”objekt i objekt” :key=”posten.länk”>
<feed-post :titel=”posten.title” :content=”posten.content” :länk=”posten.länk” :feedtitle=”posten.feedTitle” :color=”posten.feedColor” :publicerat=”posten.pubDate”></feed-item>
</v-flex>

Det är inte en enorm förändring på något sätt, men det gjorde det lite lättare för mig när jag började arbeta på foder displayen. Eftersom jag inte använder en fancy builder ännu, jag definierade min-komponenten direkt i JavaScript som så:

Vue.komponent (“feed-item’, {
rekvisita:[
‘color’,’titel’,’innehåll’,’länk’,’feedtitle’, ‘publicerat’
],
mall: `
<v-kortet :color=”färg”>
<v-card-avdelning primary-title>
<div class=”rubrik”>{{titel}} ({{publicerat | dtFormat}})</div>
</v-card-title>
<v-card-text>
{{content | maxText }}
</v-card-text>
<v-card-åtgärder>
<v-btn platt target=”_new” :href=”länk”>Läs på {{feedtitle}}</v-btn>
</v-card-åtgärder>
</v-kort>
`
});

Jag gör inte något alls sugen i heremdash;det finns ingen dynamisk logik eller händelser eller något sånt, men jag kan verkligen lägga till det senare när det är meningsfullt. Jag gjorde till slut komma runt att lägga till datum och tid för publicering. Om du är nyfiken på hur jag byggde formatter som används för det, läs min artikel Bygga Ett Filter med Hjälp av i18n Vue.js & Native Web Specifikationer.”

Kraften i att ta Bort!

Åh, och jag äntligen lagt ett sätt att ta bort feeds:

Ikonen för papperskorgen, FTW!

Detta bara skjuter i väg en metod på Vue objekt som i sin tur skjuter ut en ring till butiken som tar hand om att ta bort fodret och objekt från UI och då kvarstår det. En liten sak, men, oj, gjorde jag önskar att jag hade den i den första versionen för att testa. Och här är en sista bild av allt:

Awesome app i all awesomeness

Nästa Steg… och Vad Hände med IndexedDB?

Som jag sa i början, denna version är fortfarande inte perfekt, men jag känner definitivt bättre om det. Jag rekommenderar varmt att du dela med dig tips, förslag och felrapporter i kommentarerna nedan eller på GitHub-repo.

Så vad hände med IndexedDB stöd? Problemet jag stötte på var hur man korrekt att initiera databasen. Vuex butiker inte har ett begrepp om en skapad process. Jag kunde ha gjort något liknande detta:

// dummy-kod för att få feeds
dispatch(‘getDB’)
.då(() =>
// gör saker
);

Där getDB åtgärder returnerar ett löfte och handtag gör en one-time IndexedDB öppna och lagra värdet i staten. Jag kan ge detta en chans senare, och igen, vad jag älskar om Vuex är att jag vet att jag säkert kan göra det utan att störa resten av ansökan.

Artikel-Serien:

  1. Installation och första iteration
  2. Förbättringar och slutliga versionen (Detta Inlägg)

Jetpack WordPress plugin som körs på denna webbplats, driver inte bara relaterade inlägg nedan, men säkerhet och backup, Wiki-stöd, sök på sajten, kommentera form, sociala nätverk, och mycket mer!