Description
Changes
Props
Component no longer need to delcare props in order to receive props. Everything passed from parent vnode's data
(with the exception of internal properties, i,e. key
, ref
, slots
and nativeOn*
) will be available in this.$props
and also as the first argument of the render function. This eliminates the need for this.$attrs
and this.$listeners
.
When no props are declared on a component, props will not be proxied on the component instance and can only be accessed via this.$props
or the props
argument in render functions.
You still can delcare props in order to specify default values and perform runtime type checking, and it works just like before. Declared props will also be proxied on the component instance. However, the behavior of undeclared props falling through as attrs will be removed; it's as if inheritAttr
now defaults to false
. The component will be responsible for merging the props as attrs onto the desired element.
VNodes
Flat Data Format
// before
{
attrs: { id: 'foo' },
domProps: { innerHTML: '' },
on: { click: foo },
key: 'foo',
ref: 'bar'
}
// after (consistent with JSX usage)
{
id: 'foo',
domPropsInnerHTML: '',
onClick: foo,
key: 'foo',
ref: ref => {
this.$refs.bar = ref
}
}
- Less memory allocation & faster diffs
- Makes it consistent with JSX
- Easier spread operations
VNodes are now context-free
h
can now be globally imported and is no longer bound to component instacnes. VNodes created are also no longer bound to compomnent instances (this means you can no longer access vnode.context
to get the component instance that created it)
Component in Render Functions
No longer resolves component by string names; Any h
call with a string is considered an element. Components must be resolved before being passed to h
.
import { resolveComponent } from 'vue'
render (h) {
// only necessary when you are trying to access a registered component instead
// of an imported one
const Comp = resolveComponent(this, 'foo')
return h(Comp)
}
In templates, components should be uppercase to differentiate from normal elements.
NOTE: how to tell in browser templates? In compiler, use the following intuitions:
- If uppercase -> Component
- If known HTML elements -> element
- Treat as unknown component - at runtime, try resolving as a component first, if not found, render as element. (
resolveComponent
returns name string if component is not found)
Slots
Unifying Normnal Slots and Scoped Slots
Scoped slots and normal slots are now unified. There's no more difference between the two. Inside a component, all slots on this.$slots
will be functions and all them can be passed arguments.
Usage Syntax Change
// before
h(Comp, [
h('div', { slot: 'foo' }, 'foo')
h('div', { slot: 'bar' }, 'bar')
])
// after
h(Comp, () => h('div', 'default slot'))
// or
import { childFlags } from 'vue/flags'
h(Comp, null, {
slots: {
foo: () => h('div', 'foo'),
bar: () => h('div', 'bar')
}
}, childFlags.COMPILED_SLOTS)
// also works
h(Comp, null, {
foo: () => h('div', 'foo'),
bar: () => h('div', 'bar')
})
Functional Component
Functional components can now really be just functions.
// before
const Func = {
functional: true,
render (h, ctx) {
return h('div')
}
}
// Now can also be:
const Func = (h, props, slots, ctx) => h('div')
Func.pure = true
Async Component
Async components now must be explicitly created.
import { createAsyncComponent } from 'vue'
const AsyncFoo = createAsyncComponent(() => import('./Foo.vue'))
Directives
-
Now are internally on-vnode hooks with the exact same lifecycle as components.
-
Custom directives are now applied via a helper:
import { applyDirective, resolveDirective } from 'vue'
render (h) {
// equivalent for v-my-dir
const myDir = resolveDirective(this, 'my-dir')
return applyDirective(h('div', 'hello'), [[myDir, this.someValue]])
}
Styles
No longer performs auto-prefixing.
Attributes
- No longer auto coerces boolean or enumerated attribute values.
- No longer removes attribute if value is boolean
false
. Instead, it's set asattr="false"
instead. To remove the attribute, usenull
.
Filters
Filters are gone for good (or can it?)
Refs
- Function refs are now supported.
- String refs are no longer supported in render functions (now only supported in templates and compiled into function refs)
- String refs no longer automatically generates an array when used with
v-for
. Instead, use something like:ref="'foo' + key"
or function refs.