refactor: separate data and view layers 4
This commit is contained in:
parent
c768141317
commit
37341a5430
|
|
@ -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,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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]))
|
||||
|
|
|
|||
|
|
@ -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}`),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}`),
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue