From 91a9fa70bd46c54e1264cbfddc88208c59712836 Mon Sep 17 00:00:00 2001 From: shasharoman Date: Wed, 27 Feb 2019 20:10:50 +0800 Subject: [PATCH 1/4] fix(#9577): support deep object as dynamic arguments --- src/compiler/parser/index.js | 2 +- test/unit/features/options/directives.spec.js | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js index 0279f0ffdbf..e8d9d2cfcef 100644 --- a/src/compiler/parser/index.js +++ b/src/compiler/parser/index.js @@ -33,7 +33,7 @@ const dynamicArgRE = /^\[.*\]$/ const argRE = /:(.*)$/ export const bindRE = /^:|^\.|^v-bind:/ const propBindRE = /^\./ -const modifierRE = /\.[^.]+/g +const modifierRE = /\.[^.\]]+(?=\.|$)/g const slotRE = /^v-slot(:|$)|^#/ diff --git a/test/unit/features/options/directives.spec.js b/test/unit/features/options/directives.spec.js index 4f9a23ce79c..e627de2f5e0 100644 --- a/test/unit/features/options/directives.spec.js +++ b/test/unit/features/options/directives.spec.js @@ -287,4 +287,28 @@ describe('Options directives', () => { }).$mount() vm.key = 'bar' }) + + it('deep object as dynamic arguments', done => { + const vm = new Vue({ + template: `
`, + data: { + deep: { + key: 'foo' + } + }, + directives: { + my: { + bind(el, binding) { + expect(binding.arg).toBe('foo') + }, + update(el, binding) { + expect(binding.arg).toBe('bar') + expect(binding.oldArg).toBe('foo') + done() + } + } + } + }).$mount() + vm.deep.key = 'bar' + }) }) From 246cacde96e5684d6b906b27e62eb8a7efa79f1a Mon Sep 17 00:00:00 2001 From: shasharoman Date: Wed, 27 Feb 2019 23:09:58 +0800 Subject: [PATCH 2/4] fix(complier): support dynamic arguments like `a.b.c` format --- src/compiler/parser/index.js | 4 +-- test/unit/features/options/directives.spec.js | 34 ++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js index e8d9d2cfcef..5f9013a3a18 100644 --- a/src/compiler/parser/index.js +++ b/src/compiler/parser/index.js @@ -33,7 +33,7 @@ const dynamicArgRE = /^\[.*\]$/ const argRE = /:(.*)$/ export const bindRE = /^:|^\.|^v-bind:/ const propBindRE = /^\./ -const modifierRE = /\.[^.\]]+(?=\.|$)/g +const modifierRE = /(\.[^.\]]+)+$/g const slotRE = /^v-slot(:|$)|^#/ @@ -906,7 +906,7 @@ function parseModifiers (name: string): Object | void { const match = name.match(modifierRE) if (match) { const ret = {} - match.forEach(m => { ret[m.slice(1)] = true }) + match[0].slice(1).split('.').forEach(item => ret[item] = true) return ret } } diff --git a/test/unit/features/options/directives.spec.js b/test/unit/features/options/directives.spec.js index e627de2f5e0..15e29682a7a 100644 --- a/test/unit/features/options/directives.spec.js +++ b/test/unit/features/options/directives.spec.js @@ -288,12 +288,12 @@ describe('Options directives', () => { vm.key = 'bar' }) - it('deep object as dynamic arguments', done => { + it('deep object like `deep.a` as dynamic arguments', done => { const vm = new Vue({ - template: `
`, + template: `
`, data: { deep: { - key: 'foo' + a: 'foo' } }, directives: { @@ -309,6 +309,32 @@ describe('Options directives', () => { } } }).$mount() - vm.deep.key = 'bar' + vm.deep.a = 'bar' + }) + + it('deep object like `deep.a.b` as dynamic arguments', done => { + const vm = new Vue({ + template: `
`, + data: { + deep: { + a: { + b: 'foo' + } + } + }, + directives: { + my: { + bind(el, binding) { + expect(binding.arg).toBe('foo') + }, + update(el, binding) { + expect(binding.arg).toBe('bar') + expect(binding.oldArg).toBe('foo') + done() + } + } + } + }).$mount() + vm.deep.a.b = 'bar' }) }) From 1eef097af511ee9308198ceb3ce1d59d6c663382 Mon Sep 17 00:00:00 2001 From: shasharoman Date: Thu, 28 Feb 2019 01:04:01 +0800 Subject: [PATCH 3/4] perf: improve the performance of parseModifiers method --- src/compiler/parser/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js index 5f9013a3a18..01cbadd1ded 100644 --- a/src/compiler/parser/index.js +++ b/src/compiler/parser/index.js @@ -33,7 +33,7 @@ const dynamicArgRE = /^\[.*\]$/ const argRE = /:(.*)$/ export const bindRE = /^:|^\.|^v-bind:/ const propBindRE = /^\./ -const modifierRE = /(\.[^.\]]+)+$/g +const modifierRE = /\.[^.\]]+(?=[^\]]*$)/g const slotRE = /^v-slot(:|$)|^#/ @@ -906,7 +906,7 @@ function parseModifiers (name: string): Object | void { const match = name.match(modifierRE) if (match) { const ret = {} - match[0].slice(1).split('.').forEach(item => ret[item] = true) + match.forEach(m => { ret[m.slice(1)] = true }) return ret } } From 90b037dfb62a80995b0659dcf06a20acee557070 Mon Sep 17 00:00:00 2001 From: shasharoman Date: Thu, 28 Feb 2019 01:04:25 +0800 Subject: [PATCH 4/4] test: add test case for dynamic arguments with modifiers --- test/unit/features/options/directives.spec.js | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/unit/features/options/directives.spec.js b/test/unit/features/options/directives.spec.js index 15e29682a7a..f7a69402d0b 100644 --- a/test/unit/features/options/directives.spec.js +++ b/test/unit/features/options/directives.spec.js @@ -337,4 +337,32 @@ describe('Options directives', () => { }).$mount() vm.deep.a.b = 'bar' }) + + it('deep object as dynamic arguments with modifiers', done => { + const vm = new Vue({ + template: `
`, + data: { + deep: { + a: { + b: 'foo' + } + } + }, + directives: { + my: { + bind(el, binding) { + expect(binding.arg).toBe('foo') + expect(binding.modifiers.x).toBe(true) + expect(binding.modifiers.y).toBe(true) + }, + update(el, binding) { + expect(binding.arg).toBe('bar') + expect(binding.oldArg).toBe('foo') + done() + } + } + } + }).$mount() + vm.deep.a.b = 'bar' + }) })