Skip to content

Commit

Permalink
fix is undefined when component has no props bug (vuejs#6263)
Browse files Browse the repository at this point in the history
  • Loading branch information
hzzhaoxinhui committed Aug 24, 2017
1 parent 82f03de commit 2689a64
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
2 changes: 1 addition & 1 deletion flow/component.js
Expand Up @@ -29,7 +29,7 @@ declare interface Component {
$slots: { [key: string]: Array<VNode> };
$scopedSlots: { [key: string]: () => VNodeChildren };
$vnode: VNode; // the placeholder node for the component in parent's render tree
$attrs: ?{ [key: string] : string };
$attrs: { [key: string] : string };
$listeners: ?{ [key: string]: Function | Array<Function> };
$isServer: boolean;

Expand Down
5 changes: 3 additions & 2 deletions src/core/instance/render.js
Expand Up @@ -49,16 +49,17 @@ export function initRender (vm: Component) {
// $attrs & $listeners are exposed for easier HOC creation.
// they need to be reactive so that HOCs using them are always updated
const parentData = parentVnode && parentVnode.data

/* istanbul ignore else */
if (process.env.NODE_ENV !== 'production') {
defineReactive(vm, '$attrs', parentData && parentData.attrs, () => {
defineReactive(vm, '$attrs', parentData && parentData.attrs || {}, () => {
!isUpdatingChildComponent && warn(`$attrs is readonly.`, vm)
}, true)
defineReactive(vm, '$listeners', vm.$options._parentListeners, () => {
!isUpdatingChildComponent && warn(`$listeners is readonly.`, vm)
}, true)
} else {
defineReactive(vm, '$attrs', parentData && parentData.attrs, null, true)
defineReactive(vm, '$attrs', parentData && parentData.attrs || {}, null, true)
defineReactive(vm, '$listeners', vm.$options._parentListeners, null, true)
}
}
Expand Down
14 changes: 14 additions & 0 deletions test/unit/features/instance/properties.spec.js
Expand Up @@ -146,6 +146,20 @@ describe('Instance properties', () => {
}).then(done)
})

// #6263
it('$attrs should not be undefined when no props passed in', () => {
const vm = new Vue({
template: `<foo/>`,
data: { foo: 'foo' },
components: {
foo: {
template: `<div>{{ this.foo }}</div>`
}
}
}).$mount()
expect(vm.$attrs).toBeDefined()
})

it('warn mutating $attrs', () => {
const vm = new Vue()
vm.$attrs = {}
Expand Down

0 comments on commit 2689a64

Please sign in to comment.