Reputation: 2519
I'm trying to create a simple SPA using Vue Router and the Vuetify framework. I have several components connected to my router. When I first reload a view, everything works fine, but when I move from that view and come back, I completely lose the contents of it.
Here is HTML code:
<template>
<v-layout fill-height id="map" class="cadetblue" style="width: 100%">
<v-dialog v-model="dialog" width="500">
<v-card>
<v-img src="https://cdn.vuetifyjs.com/images/cards/sunshine.jpg" height="200px"></v-img>
<v-card-title primary-title>
<div>
<div class="headline">Select layers</div>
<span class="grey--text">Some layers are avaliable</span>
</div>
</v-card-title>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn icon @click="layers = !layers">
<v-icon>{{ layers ? 'keyboard_arrow_down' : 'keyboard_arrow_up' }}</v-icon>
</v-btn>
</v-card-actions>
<v-slide-y-transition>
<v-card-text v-show="true">
<v-checkbox @change="clickMew()" id="dofLayer" label="DOF"></v-checkbox>
<v-checkbox name="tkLayer" id="tkLayer" label="TK25"></v-checkbox>
</v-card-text>
</v-slide-y-transition>
</v-card>
</v-dialog>
<v-flex>
<v-btn
absolute
id="zoomIn"
@click="zoomIn()"
dark
fab
top
left
small
color="pink"
class="mt-5"
>
<v-icon>add</v-icon>
</v-btn>
<v-btn
absolute
id="zoomOut"
@click="zoomOut()"
dark
fab
top
left
small
color="pink"
class="mt-6"
>
<v-icon>remove</v-icon>
</v-btn>
<v-btn absolute id="home" @click="home()" dark fab top left small color="green" class="mt-7">
<v-icon>home</v-icon>
</v-btn>
<v-speed-dial
class="mb-5"
fixed
bottom
right
direction="top"
transition="slide-y-reverse-transition"
>
<v-btn slot="activator" id="test" color="blue darken-2" dark fab>
<v-icon>account_circle</v-icon>
</v-btn>
<v-btn fab id="addLayer" dark small color="green">
<v-icon>edit</v-icon>
</v-btn>
<v-btn fab @click="dialog = true" dark small color="green">
<v-icon>layers</v-icon>
</v-btn>
</v-speed-dial>
</v-flex>
</v-layout>
</template>
And here are script part:
import {
map,
initMap,
interactivity,
zoomIn,
zoomOut,
home,
addHok,
consoleMsg
} from "../../scripts/cro";
export default {
data: () => {
return {
links: [
{ icon: "account_circle", color: "blue darken-2" },
{ icon: "edit", color: "green" },
{ icon: "add", color: "indigo" }
],
neven: "TEsting Neven",
dialog: false,
layers: false
};
},
methods: {
zoomIn() {
zoomIn();
},
zoomOut() {
zoomOut();
},
home() {
home();
},
clickMew() {
addHok();
}
},
created() {
this.$nextTick(() => {
initMap();
});
},
mounted() {
this.$nextTick(() => {
initMap();
consoleMsg();
// interactivity();
});
}
};
Here is the router page (router.js):
import Vue from 'vue'
import Router from 'vue-router'
import Dashboard from './views/Dashboard.vue'
import Projects from './views/Projects.vue'
import Team from './views/Team.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'dashboard',
component: Dashboard
},
{
path: '/projects',
name: 'projects',
component: Projects
},
{
path: '/team',
name: 'team',
component: Team
}
]
})
UPDATE
As ljubadr pointed out, there is some workaround with keep-alive
. I tried wrapping router-view
like this:
<template>
<v-app>
<Navbar></Navbar>
<Modal></Modal>
<v-content>
<keep-alive include="projects">
<router-view></router-view>
</keep-alive>
</v-content>
<Footer></Footer>
</v-app>
</template>
Here is App.vue
It did not help :(
<template>
<v-app>
<Navbar></Navbar>
<Modal></Modal>
<v-content>
<keep-alive include="projects">
<router-view></router-view>
</keep-alive>
</v-content>
<Footer></Footer>
</v-app>
</template>
<script>
import Navbar from "@/components/NavBar";
import Footer from "@/components/Footer";
import Modal from "@/components/Modal";
export default {
name: "App",
components: { Navbar, Footer, Modal }
};
</script>
Upvotes: 0
Views: 1347
Reputation: 2254
You can use <keep-alive>
. Read more about it here
There are some disadvantages to this approach:
you lose lifecycle hooks like created, mounted, etc. since the component is not being rebuilt from scratch anymore. You can replace those lifecycle hooks with hooks that are specific to keep-alive components
First approach
You can then specify which components to keep alive, by specifying
<keep-alive include="component1,component2">
<router-view></router-view>
</keep-alive>
where those components need to have the matching name
property:
name: 'component1'
Second approach
We can also use <keep-alive>
with Route Meta Fields, where we have more granular control in the router on which components to keep alive (I've used the code from this codepen by Linusborg)
Router
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/',
component: Home,
meta: { keepAlive: false }
},
{ path: '/foo',
component: Foo,
meta: { keepAlive: true }
}
]
})
Template
<transition name="fade" mode="out-in">
<keep-alive v-if="$route.meta.keepAlive">
<router-view></router-view>
</keep-alive>
<router-view v-else></router-view>
</transition>
Upvotes: 3