Skip to content

Commit 2546761

Browse files
agualiseddyerburgh
authored andcommitted
fix: generate appropriate prop definitions for functional SFCs (#22)
* Generate appropriate prop definitions for functional SFCs * Fix linter errors
1 parent 88afbd0 commit 2546761

File tree

7 files changed

+53
-2
lines changed

7 files changed

+53
-2
lines changed

lib/process-functional.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module.exports = function extractProps (content) {
2+
const DETECT_PROP_DEFINITIONS = /(props\..*?)(}| |\.)/g
3+
const CHARS_TO_REMOVE = /(\.|}| |props)/g
4+
const propDefinitions = content.match(DETECT_PROP_DEFINITIONS)
5+
if (!propDefinitions) return '{}'
6+
const props = propDefinitions.map((match) => {
7+
const propName = match.trim().replace(CHARS_TO_REMOVE, '')
8+
return `'${propName}'`
9+
})
10+
return `[ ${props.join(', ')} ]`
11+
}

lib/process.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const addTemplateMapping = require('./add-template-mapping')
66
const compileBabel = require('./compilers/babel-compiler')
77
const compileTypescript = require('./compilers/typescript-compiler')
88
const compileCoffeeScript = require('./compilers/coffee-compiler')
9+
const extractPropsFromFunctionalTemplate = require('./process-functional')
910

1011
const splitRE = /\r?\n/g
1112

@@ -32,7 +33,9 @@ function isFunctionalTemplate (parts) {
3233
function changePartsIfFunctional (parts) {
3334
if (isFunctionalTemplate(parts)) {
3435
parts.lang = 'javascript'
35-
parts.script = { type: 'script', content: 'export default { props: { props: Object } }' }
36+
const functionalProps = extractPropsFromFunctionalTemplate(parts.template.content)
37+
parts.template.content = parts.template.content.replace('props.', '')
38+
parts.script = { type: 'script', content: `export default { props: ${functionalProps} }` }
3639
}
3740
}
3841

test/FunctionalSFC.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import FunctionalSFC from './resources/FunctionalSFC.vue'
33

44
test('processes .vue file with functional template', () => {
55
const wrapper = shallow(FunctionalSFC, {
6-
propsData: { props: { msg: 'Hello' }}
6+
propsData: { msg: 'Hello' }
77
})
88
expect(wrapper.is('div')).toBe(true)
99
expect(wrapper.text().trim()).toBe('Hello')

test/FunctionalSFCParent.spec.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { mount } from 'vue-test-utils'
2+
import FunctionalSFCParent from './resources/FunctionalSFCParent.vue'
3+
4+
test('processes .vue file with functional template from parent', () => {
5+
const wrapper = mount(FunctionalSFCParent)
6+
expect(wrapper.text().trim()).toBe('TEST')
7+
})

test/process-functional.spec.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import extractProps from '../lib/process-functional'
2+
3+
describe('when extracting props with props. prefix from functional template content', () => {
4+
it('extracts interpolated props ', () => {
5+
const content = '<div> {{props.msg1 }} {{props.msg2}}</div>'
6+
7+
expect(extractProps(content)).toBe("[ 'msg1', 'msg2' ]")
8+
})
9+
10+
it('extracts props used in v-for', () => {
11+
const content = '<div v-for="bar in props.foo.bar"> {{ bar }}} </div>'
12+
13+
expect(extractProps(content)).toBe("[ 'foo' ]")
14+
})
15+
})

test/resources/FunctionalSFC.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
{{ props.msg }}
44
</div>
55
</template>
6+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<template>
2+
<FunctionalSFC msg="TEST"/>
3+
</template>
4+
5+
<script>
6+
import Vue from 'vue'
7+
import FunctionalSFC from './FunctionalSFC'
8+
9+
Vue.component('FunctionalSFC', FunctionalSFC)
10+
11+
export default {
12+
components: FunctionalSFC
13+
}
14+
</script>

0 commit comments

Comments
 (0)