Repository: vuejs/vue
Pull request: Support array syntax for keep-alive include and exclude

Support array syntax for keep-alive include and exclude. [#5914](https://github.com/vuejs/vue/issues/5914)

API looks like:
``` vue
<keep-alive :include="['a', 'b', 'c']" :exclude="['foo']"></keep-alive>
```
<!--
Please make sure to read the Pull Request Guidelines:
https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#pull-request-guidelines
-->

<!-- PULL REQUEST TEMPLATE -->
<!-- (Update "[ ]" to "[x]" to check a box) -->

**What kind of change does this PR introduce?** (check at least one)

- [ ] Bugfix
- [x] Feature
- [ ] Code style update
- [ ] Refactor
- [ ] Build-related changes
- [ ] Other, please describe:

**Does this PR introduce a breaking change?** (check one)

- [ ] Yes
- [x] No

If yes, please describe the impact and migration path for existing applications:

**The PR fulfills these requirements:**

- [x] It's submitted to the `dev` branch for v2.x (or to a previous version branch), _not_ the `master` branch
- [ ] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
- [x] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
- [x] New/updated tests are included

If adding a **new feature**, the PR's description includes:
- [ ] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

**Other information:**


Changed files:
filename: src/core/components/keep-alive.js
patch: @@ -5,14 +5,16 @@ import { getFirstComponentChild } from 'core/vdom/helpers/index'
 
 type VNodeCache = { [key: string]: ?VNode };
 
-const patternTypes: Array<Function> = [String, RegExp]
+const patternTypes: Array<Function> = [String, RegExp, Array]
 
 function getComponentName (opts: ?VNodeComponentOptions): ?string {
   return opts && (opts.Ctor.options.name || opts.tag)
 }
 
-function matches (pattern: string | RegExp, name: string): boolean {
-  if (typeof pattern === 'string') {
+function matches (pattern: string | RegExp | Array<string>, name: string): boolean {
+  if (Array.isArray(pattern)) {
+    return pattern.indexOf(name) > -1
+  } else if (typeof pattern === 'string') {
     return pattern.split(',').indexOf(name) > -1
   } else if (isRegExp(pattern)) {
     return pattern.test(name)
@@ -62,10 +64,10 @@ export default {
   },
 
   watch: {
-    include (val: string | RegExp) {
+    include (val: string | RegExp | Array<string>) {
       pruneCache(this.cache, this._vnode, name => matches(val, name))
     },
-    exclude (val: string | RegExp) {
+    exclude (val: string | RegExp | Array<string>) {
       pruneCache(this.cache, this._vnode, name => !matches(val, name))
     }
   },

filename: test/unit/features/component/component-keep-alive.spec.js
patch: @@ -272,6 +272,24 @@ describe('Component keep-alive', () => {
     sharedAssertions(vm, done)
   })
 
+  it('include (array)', done => {
+    const vm = new Vue({
+      template: `
+        <div v-if="ok">
+          <keep-alive :include="['one']">
+            <component :is="view"></component>
+          </keep-alive>
+        </div>
+      `,
+      data: {
+        view: 'one',
+        ok: true
+      },
+      components
+    }).$mount()
+    sharedAssertions(vm, done)
+  })
+
   it('exclude (string)', done => {
     const vm = new Vue({
       template: `
@@ -308,6 +326,24 @@ describe('Component keep-alive', () => {
     sharedAssertions(vm, done)
   })
 
+  it('exclude (array)', done => {
+    const vm = new Vue({
+      template: `
+        <div v-if="ok">
+          <keep-alive :exclude="['two']">
+            <component :is="view"></component>
+          </keep-alive>
+        </div>
+      `,
+      data: {
+        view: 'one',
+        ok: true
+      },
+      components
+    }).$mount()
+    sharedAssertions(vm, done)
+  })
+
   it('include + exclude', done => {
     const vm = new Vue({
       template: `