Измените имя маршрута и компонент, если пользователь вошел в систему

У меня есть работающий компонент входа в мой nativescript-vue, который использует RadSideDrawer < / а>.

Все, что я хочу сделать, это изменить маршрут Login на Logout, и я не могу понять, как этого добиться. Тернарные операторы не работали бы полностью.

Я также попытался объявить новый пустой массив и поместить в него свой массив меню и манипулировать им вместо исходных данных. Это тоже не сработало.

Мне нужно было бы закрыть приложение и снова открыть его, чтобы пункт меню изменился, он не реагировал.

Во-первых, вот мой app.js

Vue.prototype.$routes = routes

new Vue({
    store,
    render (h) {
        return h(
          App,
          [
            h(DrawerContent, { slot: 'drawerContent' }),
            //h(store.getters.loggedIn ? routes.Home : routes.Login, { slot: 'mainContent' })
            h(routes.Home, { slot: 'mainContent' })
          ]
        )
      }
  }).$start()

А вот мой роутер в router/index.js, где я объявляю роутеры.

import Home from "../components/Home";
import Browse from "../components/Browse";
import Featured from "../components/Featured";
import Search from "../components/Search";
import Settings from "../components/Settings";
import Tasks from "../components/Tasks";
import Login from "../components/Login";
import Logout from "../components/Logout";

const routes = {
    Home,
    Browse,
    Featured,
    Search,
    Settings,
    Tasks,
    Login,
    Logout
}

export default routes

Я также использую $store с кучей геттеров, сеттеров, мутаций и действий, и один из этих геттеров извлекает, если пользователь вошел в систему

export const store = new Vuex.Store({
    state: {
        token: LS.getItem('access_token') || null,
        filter: 'all',
        todos: [],
        msg: ''
    },
    getters: {
        loggedIn(state) {
            return state.token !== null
        },
    }
}

А поскольку я использую навигацию по ящику, вот DrawerContent.vue

<template lang="html">
    <GridLayout rows="auto, *" class="sidedrawer sidedrawer-left">
        <StackLayout row="0" class="sidedrawer-header">
            <Label class="sidedrawer-header-image fa" text.decode="&#xf2bd;"></Label>
            <Label class="sidedrawer-header-brand" text="User Name"></Label>
            <Label class="footnote" text="[email protected]"></Label>
        </StackLayout>

        <ScrollView row="1" class="sidedrawer-content">
            <StackLayout>

                <GridLayout
                        columns="auto, *"
                        :class="'sidedrawer-list-item' + (selectedPage === page.name ? ' selected': '')"
                        v-for="(page, i) in pages"
                        :key="i"
                        @tap="goToPage(page.component)">
                    <Label col="0" :text="page.icon" class="fa"></Label>
                    <Label col="1" :text="page.name" class="p-r-10"></Label>
                </GridLayout>

            </StackLayout>
        </ScrollView>
    </GridLayout>
</template>

<script>
    import * as utils from "~/shared/utils";
    import SelectedPageService from "~/shared/selected-page-service";
    import Login from "./Login";
    import Featured from "./Featured";

    export default {
        data () {
            return {
                selectedPage: "",
                pages: [
                    {
                        path: '/',
                        name: 'Home',
                        icon: "\uf015",
                        component: this.$routes.Home
                    },
                    {
                        path: '/browse',
                        name: 'Browse',
                        icon: '\uf25a',
                        component: this.$routes.Browse,
                        meta : {
                            requiresAuth: true
                        }
                    },
                    {
                        path: '/featured',
                        name: 'Featured',
                        icon: '\uf005',
                        component: this.$routes.Featured
                    },
                    {
                        path: '/search',
                        name: 'Search',
                        icon: '\uf002',
                        component: this.$routes.Search
                    },
                    {
                        path: '/settings',
                        name: 'Settings',
                        icon: '\uf013',
                        component: this.$routes.Settings
                    },
                    {
                        path: '/tasks',
                        name: 'Tasks',
                        icon: '\uf0ae',
                        component: this.$routes.Tasks
                    },
                    {
                        path: '/login',
                        name: 'Login',
                        icon: '\uf007',
                        component: this.$routes.Login
                    }
                ]
            };
        },
        mounted() {
            SelectedPageService.getInstance().selectedPage$
                .subscribe((selectedPage) => this.selectedPage = selectedPage);
        },
        methods: {
            goToPage (pageComponent) {
                this.$navigateTo(pageComponent, {
                    clearHistory: true
                });
                utils.closeDrawer();
            },
        },
        computed: {
            loggedIn() {
                return this.$store.getters.loggedIn
            },
        }
    };
</script>

Как видите, здесь маршруты фактически определены в массиве pages, а затем зациклены в GridLayout выше.

Проблема в том, что он оставляет мало места для маневра, поскольку мне приходится иметь дело с данными, поступающими из самого цикла if(page.name === 'Login') { page.name = 'Logout' }

Это была моя первая попытка с использованием директивы v-if. Но я быстро отказался от него, так как это заявление было бы слишком длинным и немного запутанным.

Я также попытался удалить цикл и просто жестко запрограммировать все меню, но мне не удалось получить доступ к this.$routes.Home в разметке.

На данный момент я действительно потерялся. Я открыт для любых предложений, которые могут у вас возникнуть.


person Halnex    schedule 09.07.2019    source источник


Ответы (1)


Сделайте свойство pages геттером, чтобы вы могли легко push в массив:

computed: {
  pages: function() {
    const pages = [{
        path: '/',
        name: 'Home',
        icon: "\uf015",
        component: this.$routes.Home
      },
      {
        path: '/browse',
        name: 'Browse',
        icon: '\uf25a',
        component: this.$routes.Browse,
        meta: {
          requiresAuth: true
        }
      },
      {
        path: '/featured',
        name: 'Featured',
        icon: '\uf005',
        component: this.$routes.Featured
      },
      {
        path: '/search',
        name: 'Search',
        icon: '\uf002',
        component: this.$routes.Search
      },
      {
        path: '/settings',
        name: 'Settings',
        icon: '\uf013',
        component: this.$routes.Settings
      },
      {
        path: '/tasks',
        name: 'Tasks',
        icon: '\uf0ae',
        component: this.$routes.Tasks
      },

    ]

    if (!!this.$store.getters['loggedIn']) {
      pages.push({
        path: '/logout',
        name: 'Logout',
        icon: '....',
        component: this.$routes.Logout
      })
    } else {
      pages.push({
        path: '/login',
        name: 'Login',
        icon: '\uf007',
        component: this.$routes.Login
      })
    }

    return pages

  }
}
person Ohgodwhy    schedule 09.07.2019
comment
Спасибо чувак. Но почему вы использовали двойные восклицательные знаки в !!this.$store.getters['loggedIn']? - person Halnex; 09.07.2019
comment
@Halnex в этом нет необходимости, поскольку получатель хранилища гарантирует логическое значение, я подозреваю, что это просто защитное кодирование - person JaredMcAteer; 10.07.2019