|
| 1 | +<script setup> |
| 2 | +import SwitchComponent from './keep-alive-demos/SwitchComponent.vue' |
| 3 | +</script> |
| 4 | + |
1 | 5 | # KeepAlive
|
2 | 6 |
|
3 | 7 | ## Basic Usage
|
4 | 8 |
|
5 |
| -:::tip |
6 |
| -When used in [DOM templates](/guide/essentials/component-basics.html#dom-template-parsing-caveats), it should be referenced as `<keep-alive>`. |
7 |
| -::: |
8 |
| - |
9 |
| -Earlier, we used the `is` attribute to switch between components in a tabbed interface: |
| 9 | +In the Component Basics chapter, we introduced the syntax for [Dynamic Components](/guide/essentials/component-basics.html#dynamic-components), using the `<component>` special element: |
10 | 10 |
|
11 | 11 | ```vue-html
|
12 |
| -<component :is="currentTabComponent"></component> |
| 12 | +<component :is="activeComponent" /> |
13 | 13 | ```
|
14 | 14 |
|
15 |
| -When switching between these components though, you'll sometimes want to maintain their state or avoid re-rendering for performance reasons. For example, when expanding our tabbed interface a little: |
| 15 | +By default, an active component instance will be unmounted when switched away from. This will cause any changed state it holds to be lost. |
| 16 | + |
| 17 | +In the example below, we have two stateful components - A contains a counter, while B contains a message synced with an input via `v-model`. Try update the state of one of them, switch away, and then switch back to it: |
16 | 18 |
|
17 |
| -<!-- <common-codepen-snippet title="Dynamic components: without keep-alive" slug="jOPjZOe" tab="html,result" /> --> |
| 19 | +<SwitchComponent /> |
18 | 20 |
|
19 |
| -You'll notice that if you select a post, switch to the _Archive_ tab, then switch back to _Posts_, it's no longer showing the post you selected. That's because each time you switch to a new tab, Vue creates a new instance of the `currentTabComponent`. |
| 21 | +You'll notice that when switched back, the previous changed state would have been reset. |
20 | 22 |
|
21 |
| -Recreating dynamic components is normally useful behavior, but in this case, we'd really like those tab component instances to be cached once they're created for the first time. To solve this problem, we can wrap our dynamic component with a `<keep-alive>` element: |
| 23 | +Creating fresh component instance on switch is normally useful behavior, but in this case, we'd really like the two component instances to be preserved even when they are inactive. To solve this problem, we can wrap our dynamic component with the `<KeepAlive>` built-in component: |
22 | 24 |
|
23 | 25 | ```vue-html
|
24 | 26 | <!-- Inactive components will be cached! -->
|
25 |
| -<keep-alive> |
26 |
| - <component :is="currentTabComponent"></component> |
27 |
| -</keep-alive> |
| 27 | +<KeepAlive> |
| 28 | + <component :is="activeComponent" /> |
| 29 | +</KeepAlive> |
28 | 30 | ```
|
29 | 31 |
|
30 |
| -Check out the result below: |
| 32 | +Now, the state will be persisted across component switches: |
31 | 33 |
|
32 |
| -<!-- <common-codepen-snippet title="Dynamic components: with keep-alive" slug="VwLJQvP" tab="html,result" /> --> |
| 34 | +<SwitchComponent use-KeepAlive /> |
33 | 35 |
|
34 |
| -Now the _Posts_ tab maintains its state (the selected post) even when it's not rendered. |
| 36 | +<div class="composition-api"> |
35 | 37 |
|
36 |
| -Check out more details on `<keep-alive>` in the [API reference](/api/built-in-components.html#keep-alive). |
| 38 | +[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHNoYWxsb3dSZWYgfSBmcm9tICd2dWUnXG5pbXBvcnQgQ29tcEEgZnJvbSAnLi9Db21wQS52dWUnXG5pbXBvcnQgQ29tcEIgZnJvbSAnLi9Db21wQi52dWUnXG5cbmNvbnN0IGN1cnJlbnQgPSBzaGFsbG93UmVmKENvbXBBKVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cbiAgPGRpdiBjbGFzcz1cImRlbW9cIj5cbiAgICA8bGFiZWw+PGlucHV0IHR5cGU9XCJyYWRpb1wiIHYtbW9kZWw9XCJjdXJyZW50XCIgOnZhbHVlPVwiQ29tcEFcIiAvPiBBPC9sYWJlbD5cbiAgICA8bGFiZWw+PGlucHV0IHR5cGU9XCJyYWRpb1wiIHYtbW9kZWw9XCJjdXJyZW50XCIgOnZhbHVlPVwiQ29tcEJcIiAvPiBCPC9sYWJlbD5cbiAgICA8S2VlcEFsaXZlPlxuICAgICAgPGNvbXBvbmVudCA6aXM9XCJjdXJyZW50XCI+PC9jb21wb25lbnQ+XG4gICAgPC9LZWVwQWxpdmU+XG4gIDwvZGl2PlxuPC90ZW1wbGF0ZT5cbiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0iLCJDb21wQS52dWUiOiI8c2NyaXB0IHNldHVwPlxuaW1wb3J0IHsgcmVmIH0gZnJvbSAndnVlJ1xuXG5jb25zdCBjb3VudCA9IHJlZigwKVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cbiAgPHA+Q3VycmVudCBjb21wb25lbnQ6IEE8L3A+XG4gIDxzcGFuPmNvdW50OiB7eyBjb3VudCB9fTwvc3Bhbj5cbiAgPGJ1dHRvbiBAY2xpY2s9XCJjb3VudCsrXCI+KzwvYnV0dG9uPlxuPC90ZW1wbGF0ZT5cbiIsIkNvbXBCLnZ1ZSI6IjxzY3JpcHQgc2V0dXA+XG5pbXBvcnQgeyByZWYgfSBmcm9tICd2dWUnXG5jb25zdCBtc2cgPSByZWYoJycpXG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuICA8cD5DdXJyZW50IGNvbXBvbmVudDogQjwvcD5cbiAgPHNwYW4+TWVzc2FnZSBpczoge3sgbXNnIH19PC9zcGFuPlxuICA8aW5wdXQgdi1tb2RlbD1cIm1zZ1wiPlxuPC90ZW1wbGF0ZT5cbiJ9) |
| 39 | + |
| 40 | +</div> |
| 41 | +<div class="options-api"> |
| 42 | + |
| 43 | +[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmltcG9ydCBDb21wQSBmcm9tICcuL0NvbXBBLnZ1ZSdcbmltcG9ydCBDb21wQiBmcm9tICcuL0NvbXBCLnZ1ZSdcbiAgXG5leHBvcnQgZGVmYXVsdCB7XG4gIGNvbXBvbmVudHM6IHsgQ29tcEEsIENvbXBCIH0sXG4gIGRhdGEoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGN1cnJlbnQ6ICdDb21wQSdcbiAgICB9XG4gIH1cbn1cbjwvc2NyaXB0PlxuXG48dGVtcGxhdGU+XG4gIDxkaXYgY2xhc3M9XCJkZW1vXCI+XG4gICAgPGxhYmVsPjxpbnB1dCB0eXBlPVwicmFkaW9cIiB2LW1vZGVsPVwiY3VycmVudFwiIHZhbHVlPVwiQ29tcEFcIiAvPiBBPC9sYWJlbD5cbiAgICA8bGFiZWw+PGlucHV0IHR5cGU9XCJyYWRpb1wiIHYtbW9kZWw9XCJjdXJyZW50XCIgdmFsdWU9XCJDb21wQlwiIC8+IEI8L2xhYmVsPlxuICAgIDxLZWVwQWxpdmU+XG4gICAgICA8Y29tcG9uZW50IDppcz1cImN1cnJlbnRcIj48L2NvbXBvbmVudD5cbiAgICA8L0tlZXBBbGl2ZT5cbiAgPC9kaXY+XG48L3RlbXBsYXRlPlxuIiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwidnVlXCI6IFwiaHR0cHM6Ly9zZmMudnVlanMub3JnL3Z1ZS5ydW50aW1lLmVzbS1icm93c2VyLmpzXCJcbiAgfVxufSIsIkNvbXBBLnZ1ZSI6IjxzY3JpcHQ+XG5leHBvcnQgZGVmYXVsdCB7XG4gIGRhdGEoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvdW50OiAwXG4gICAgfVxuICB9XG59XG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuICA8cD5DdXJyZW50IGNvbXBvbmVudDogQTwvcD5cbiAgPHNwYW4+Y291bnQ6IHt7IGNvdW50IH19PC9zcGFuPlxuICA8YnV0dG9uIEBjbGljaz1cImNvdW50KytcIj4rPC9idXR0b24+XG48L3RlbXBsYXRlPlxuIiwiQ29tcEIudnVlIjoiPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbXNnOiAnJ1xuICAgIH1cbiAgfVxufVxuPC9zY3JpcHQ+XG5cblxuPHRlbXBsYXRlPlxuICA8cD5DdXJyZW50IGNvbXBvbmVudDogQjwvcD5cbiAgPHNwYW4+TWVzc2FnZSBpczoge3sgbXNnIH19PC9zcGFuPlxuICA8aW5wdXQgdi1tb2RlbD1cIm1zZ1wiPlxuPC90ZW1wbGF0ZT5cbiJ9) |
| 44 | + |
| 45 | +</div> |
| 46 | + |
| 47 | +:::tip |
| 48 | +When used in [DOM templates](/guide/essentials/component-basics.html#dom-template-parsing-caveats), it should be referenced as `<keep-alive>`. |
| 49 | +::: |
37 | 50 |
|
38 | 51 | ## Include / Exclude
|
39 | 52 |
|
| 53 | +By default, `<KeepAlive>` will cache any component instance inside. We can customize this behavior via the `include` and `exclude` props. Both props can be a comma-delimited string, a `RegExp`, or an array containing either types: |
| 54 | + |
| 55 | +```vue-html |
| 56 | +<!-- comma-delimited string --> |
| 57 | +<KeepAlive include="a,b"> |
| 58 | + <component :is="view"></component> |
| 59 | +</KeepAlive> |
| 60 | +
|
| 61 | +<!-- regex (use `v-bind`) --> |
| 62 | +<KeepAlive :include="/a|b/"> |
| 63 | + <component :is="view"></component> |
| 64 | +</KeepAlive> |
| 65 | +
|
| 66 | +<!-- Array (use `v-bind`) --> |
| 67 | +<KeepAlive :include="['a', 'b']"> |
| 68 | + <component :is="view"></component> |
| 69 | +</KeepAlive> |
| 70 | +``` |
| 71 | + |
| 72 | +The match is checked against the component's [`name`](/api/options-misc.html#name) option, so components that need to be conditionally cached by `KeepAlive` must explicitly delcare a `name` option. |
| 73 | + |
40 | 74 | ## Max Cached Instances
|
| 75 | + |
| 76 | +We can limit the maximum number of component instances that can be cached via the `max` prop. When `max` is specified, `<KeepAlive>` behaves like an [LRU cache](<https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)>): if the number of cached instances is about to exceed the specified max count, the least recently accessed cached instance will be destroyed to make room for the new one. |
| 77 | + |
| 78 | +```vue-html |
| 79 | +<KeepAlive :max="10"> |
| 80 | + <component :is="activeComponent" /> |
| 81 | +</KeepAlive> |
| 82 | +``` |
0 commit comments