refactor: separate data and view layers 4

This commit is contained in:
Sándor Levcsák 2020-11-07 07:28:04 +02:00
parent 35a4464461
commit 412fc70710
4 changed files with 82 additions and 76 deletions

View File

@ -1,5 +1,9 @@
<template>
<ArticlesListNavigation v-bind="$attrs" />
<ArticlesListNavigation
v-bind="$attrs"
:tag="tag"
:username="username"
/>
<div
v-if="articlesDownloading"
@ -51,6 +55,7 @@ export default defineComponent({
fetchArticles, articlesDownloading,
articlesCount, articles, updateArticle,
page, changePage,
tag, username,
} = useArticles()
await fetchArticles()
@ -62,6 +67,8 @@ export default defineComponent({
page,
changePage,
updateArticle,
tag,
username,
}
},
})

View File

@ -27,7 +27,7 @@ import { computed, defineComponent } from 'vue'
import type { RouteParams } from 'vue-router'
import type { AppRouteNames } from '../router'
import { useArticlesMeta, ArticlesType } from '../composable/useArticlesMeta'
import type { ArticlesType } from '../composable/useArticles'
import { isAuthorized } from '../store/user'
@ -47,10 +47,10 @@ export default defineComponent({
useTagFeed: { type: Boolean, default: false },
useUserFeed: { type: Boolean, default: false },
useUserFavorited: { type: Boolean, default: false },
tag: { type: String, required: true },
username: { type: String, required: true },
},
setup (props) {
const { tag, username } = useArticlesMeta()
const allLinks = computed<ArticlesListNavLink[]>(() => [
{
name: 'global-feed',
@ -65,21 +65,21 @@ export default defineComponent({
{
name: 'tag-feed',
routeName: 'tag',
routeParams: { tag: tag.value },
title: tag.value,
routeParams: { tag: props.tag },
title: props.tag,
icon: 'ion-pound',
},
{
name: 'user-feed',
routeName: 'profile',
routeParams: { username: username.value },
routeParams: { username: props.username },
title: 'My articles',
},
{
name: 'user-favorites-feed',
routeName: 'profile-favorites',
routeParams: { username: username.value },
routeParams: { username: props.username },
title: 'Favorited Articles',
},
])
@ -87,9 +87,9 @@ export default defineComponent({
const show = computed<Record<ArticlesType, boolean>>(() => ({
'global-feed': props.useGlobalFeed,
'my-feed': props.useMyFeed && isAuthorized.value,
'tag-feed': props.useTagFeed && tag.value !== '',
'user-feed': props.useUserFeed && username.value !== '',
'user-favorites-feed': props.useUserFavorited && username.value !== '',
'tag-feed': props.useTagFeed && props.tag !== '',
'user-feed': props.useUserFeed && props.username !== '',
'user-favorites-feed': props.useUserFavorited && props.username !== '',
}))
const links = computed<ArticlesListNavLink[]>(() => allLinks.value.filter(link => show.value[link.name]))

View File

@ -1,4 +1,6 @@
import { ref, watch } from 'vue'
import { computed, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import type { AppRouteNames } from '../router'
import createAsyncProcess from '../utils/create-async-process'
@ -10,10 +12,8 @@ import {
getArticlesByTag,
} from '../services/article/getArticles'
import { useArticlesMeta } from './useArticlesMeta'
export function useArticles () {
const { articlesType, tag, username, metaChanged } = useArticlesMeta()
const { articlesType, tag, username, metaChanged } = getArticlesMeta()
const articles = ref<Article[]>([])
const articlesCount = ref(0)
@ -73,5 +73,65 @@ export function useArticles () {
page,
changePage,
updateArticle,
tag,
username,
}
}
export type ArticlesType = 'global-feed' | 'my-feed' | 'tag-feed' | 'user-feed' | 'user-favorites-feed'
export const articlesTypes: ArticlesType[] = ['global-feed', 'my-feed', 'tag-feed', 'user-feed', 'user-favorites-feed']
export const isArticlesType = (type: any): type is ArticlesType => articlesTypes.includes(type)
const routeNameToArticlesType: Partial<Record<AppRouteNames, ArticlesType>> = ({
'global-feed': 'global-feed',
'my-feed': 'my-feed',
tag: 'tag-feed',
profile: 'user-feed',
'profile-favorites': 'user-favorites-feed',
})
function getArticlesMeta () {
const route = useRoute()
const tag = ref('')
const username = ref('')
const articlesType = ref<ArticlesType>('global-feed')
watch(
() => route.name,
routeName => {
const possibleArticlesType = routeNameToArticlesType[routeName as AppRouteNames]
if (!isArticlesType(possibleArticlesType)) return
articlesType.value = possibleArticlesType
},
{ immediate: true },
)
watch(
() => route.params.username,
usernameParam => {
if (usernameParam !== username.value) {
username.value = typeof usernameParam === 'string' ? usernameParam : ''
}
},
{ immediate: true },
)
watch(
() => route.params.tag,
tagParam => {
if (tagParam !== tag.value) {
tag.value = typeof tagParam === 'string' ? tagParam : ''
}
},
{ immediate: true },
)
return {
tag: computed(() => tag.value),
username: computed(() => username.value),
articlesType: computed(() => articlesType.value),
metaChanged: computed(() => `${articlesType.value}-${username.value}-${tag.value}`),
}
}

View File

@ -1,61 +0,0 @@
import { computed, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import type { AppRouteNames } from '../router'
export type ArticlesType = 'global-feed' | 'my-feed' | 'tag-feed' | 'user-feed' | 'user-favorites-feed'
export const articlesTypes: ArticlesType[] = ['global-feed', 'my-feed', 'tag-feed', 'user-feed', 'user-favorites-feed']
export const isArticlesType = (type: any): type is ArticlesType => articlesTypes.includes(type)
const routeNameToArticlesType: Partial<Record<AppRouteNames, ArticlesType>> = ({
'global-feed': 'global-feed',
'my-feed': 'my-feed',
tag: 'tag-feed',
profile: 'user-feed',
'profile-favorites': 'user-favorites-feed',
})
export function useArticlesMeta () {
const route = useRoute()
const tag = ref('')
const username = ref('')
const articlesType = ref<ArticlesType>('global-feed')
watch(
() => route.name,
routeName => {
const possibleArticlesType = routeNameToArticlesType[routeName as AppRouteNames]
if (!isArticlesType(possibleArticlesType)) return
articlesType.value = possibleArticlesType
},
{ immediate: true },
)
watch(
() => route.params.username,
usernameParam => {
if (usernameParam !== username.value) {
username.value = typeof usernameParam === 'string' ? usernameParam : ''
}
},
{ immediate: true },
)
watch(
() => route.params.tag,
tagParam => {
if (tagParam !== tag.value) {
tag.value = typeof tagParam === 'string' ? tagParam : ''
}
},
{ immediate: true },
)
return {
tag: computed(() => tag.value),
username: computed(() => username.value),
articlesType: computed(() => articlesType.value),
metaChanged: computed(() => `${articlesType.value}-${username.value}-${tag.value}`),
}
}