Reputation: 162
I'm working on a single-page app in Vuejs and I'm wondering how I create a navbar that shows/hides different sections of the app based on what I click. I have the navbar laid out, I just need to figure out how to make it show/hide components. I tried to make the navbar component modify an array that tells my app which components to display, but it can't access the array. What should I do instead?
Upvotes: 1
Views: 4441
Reputation: 280
Here is an example of a recent project I made with vue-router. The syntax maybe a little off in the first snippet as I'm used to creating and writing in vue CLI, but you insert the tag in App.vue in the main tag, setup your router page and your router config component.
I would recommend setting up a vue cli create app.
In terminal - vue create hello-world (add vue-router in create steps prompt), vue add vuetify after if you like!
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<div id="app">
<v-app>
<v-main>
<TopToolbar class="topTool"></TopToolbar>
<v-main>
<router-view></router-view>
</v-main>
<BottomNav class="bottomN"></BottomNav>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
<script>
import BottomNav from 'path';
new Vue({
el: '#app',
vuetify: new Vuetify(),
components: {TopToolbar, BottomNav},
data: () => ({
}),
})
</script>
</body>
</html>
<template>
<v-bottom-navigation
scroll-threshold="800"
absolute
color="primary"
light
grow
background-color="primary"
height="56"
>
<v-btn value="scan" :to="{ name: 'Scan'}">
<span v-if="this.$route.name != 'Scan'" style="color: #fff">Scan</span>
<v-icon v-if="this.$route.name != 'Scan'" size="24" color="#fff">mdi-barcode-scan</v-icon>
<v-icon v-else size="24" color="primary">mdi-barcode-scan</v-icon>
</v-btn>
<v-btn value="create" :to="{ path: '/'}">
<span v-if="this.$route.name != 'Create'" style="color: #fff">Create</span>
<v-icon v-if="this.$route.name != 'Create'" size="24" color="#fff">mdi-barcode</v-icon>
<v-icon v-else size="24" color="primary">mdi-barcode</v-icon>
</v-btn>
<v-btn value="print" :to="{ name: 'Print'}">
<span v-if="this.$route.name != 'Print'" style="color: #fff">Print</span>
<v-icon v-if="this.$route.name != 'Print'" size="24" color="#fff">mdi-printer</v-icon>
<v-icon v-else size="24" color="primary">mdi-printer</v-icon>
</v-btn>
</v-bottom-navigation>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component({})
export default class BottomNav extends Vue {}
</script>
<style scoped>
</style>
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const routes = [
{
path: '/scan',
name: 'Scan',
component: () => import('../views/Scan.vue'),
},
{
path: '/',
name: 'Create',
component: () => import('../views/Create.vue'),
},
{
path: '/print',
name: 'Print',
component: () => import('../views/Print.vue'),
}
];
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
});
export default router;
Upvotes: 1
Reputation: 280
If you're not using Vue-Router, this may be what you're looking for.
Vue-Router would be preferable in most Vue SPAs though.
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<div id="app">
<v-app>
<v-main>
<template>
<div>
<v-tabs
v-model="tab"
background-color="blue accent-4"
class="elevation-2"
dark
:centered="centered"
:grow="grow"
:vertical="vertical"
:right="right"
:prev-icon="prevIcon ? 'mdi-arrow-left-bold-box-outline' : undefined"
:next-icon="nextIcon ? 'mdi-arrow-right-bold-box-outline' : undefined"
:icons-and-text="icons"
>
<v-tabs-slider></v-tabs-slider>
<v-tab
v-for="i in tabs"
:key="i"
:href="`#tab-${i}`"
>
Tab {{ i }}
</v-tab>
<v-tab-item
v-for="i in tabs"
:key="i"
:value="'tab-' + i"
>
<v-card
flat
tile
>
<v-card-text>{{ text }}</v-card-text>
</v-card>
</v-tab-item>
</v-tabs>
</div>
</template>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
tab: null,
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
icons: false,
centered: false,
grow: false,
vertical: false,
prevIcon: false,
nextIcon: false,
right: false,
tabs: 3,
}),
})
</script>
</body>
</html>
Upvotes: 3