Today in Vue: <keep-alive>

robi
Technically Haunting
4 min readNov 18, 2019

tl;dr: Vue 3.0 request: Allow <keep-alive> to specify if a component should be kept in the activated state to allow it to reactively track its properties and do things even when it’s in keep-alive mode.

Sometimes you need to keep a complicated component alive even if it’s not the primary thing the user is facing. Like one of many items in a tab system or something simply switched out for another via a v-if. Either way, it’s a component that needs to be readily available again some time in the near future.

For that, <keep-alive> serves the purpose pretty well. It allows the component to stay resident without being cleaned up and having to go through the component lifecycle all over again. But there’s a few caveats to that.

Once your keep-alive is invoked, the component will go into a deactivated state (a formal lifestyle hook you can catch, along with the counterpart lifecycle activated). At this point, the component is still alive in memory, but any props passed in will no longer be reactive. So internally, nothing is received, but as soon as you come out of it and the activated lifecycle hook is triggered, all your props will hydrate properly. So if you don’t particularly care about the internals of your component will being kept alive, there’s not much to worry. But if your component still would like to track state of its properties because it has to do something particular, you’ll need to find another way.

My issue was that I was binding and unbinding some keyboard bindings as the component was coming in and out of focus (as determined by a tracking prop I was passing in). I also incidentally used the same variable passed to the prop to decide via a v-if if the component was supposed to be shown or not. And I wanted it to be kept-alive so I wrapped it in <keep-alive>. Needless to say, since I used the same variable, it used the v-if binding first to turn off the component to send it into keep-alive mode, then tried to pass that same var as a prop to the component which would have told it to turn off the keybindings. Except that the prop was no longer reactive, so the component never got the updated prop to tell it to turn off the keybindings and it stayed on.

Simple enough fix was to override the prop by tracking the activated/deactivated lifecycle and use that as the override to allow removal of the keybinding (activating it would be fine since the prop would be reactive). Not an ideal solution as this relies on having to know that being in a keep-alive forces it to track the new lifecycle states. And who knows what other new features may introduce new states I have to track.

The other way was to just track the v-if and the prop with 2 different vars and just make sure to pass in the variable first before toggling the v-if.

(Update: The above will be more difficult to do when doing all of this through naturally reactive variables since you have to intercept the changes and track them and execute in an appropriate order. Lots of added code for no real great reason)

It’s not a big deal to figure out how to get around it, but I would rather, in a case like this, be able to tell the keep-alive system to just let my components act as they need, to stay fully alive, but just follow the desires of the v-if and whatever other directives are controlling the visual situation.

The component should not care or need to know that it’s in a keep-alive lifecycle, else it would also be obliged to have to know about any other potential things that could trigger whatever non standard lifecycle.

And by shutting out all reactivity, it creates a problem with creating and prefetching/caching components that are encapsulated and are designed to be self contained: Think data loading based on an :id prop being passed in.

If I wanted to try to background load a data based on an :id prop passed into a component or something else in a keep-alive, I cant do that until the component exits the keep-aliveand the new :id is hydrated. Which means there will be a delay there to prepare the component for display that could have been avoided should it have been able to do that quietly in the background.

Yes, it can be possible to offload that kind of preparation to something outside if the component in a different system (Vuex store etc), but sometimes there’s some design convenience and encapsulation to just have the component know things intimately.

The long winded point of this is perhaps keep-aliveshould have an option to allow for its components to be kept active, much like it can have filters to decide which components to include (and exclude) from being kept alive.

Just something to chew on for anyone helping to build Vue 3.0 :).

--

--

robi
Technically Haunting

interface explorer @ dfstudio.com 🌑 formerly IBM 🌒 ui/ux 🌓 more social online than in person 🌔 enjoying the PNW 🌕 cats 🐾