-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2.0 Changes #2873
Comments
I just saw that certain features will only be available in the standalone build. Does that mean that this and the NPM version are significantly different? |
@rekateka 2.0 standalone build means (compiler + runtime). The default export of the NPM package will be runtime only, because if installing from NPM, you will likely pre-compile the templates with a build tool. |
Thanks, @yyx990803. I still have a couple more questions regarding the compiler and other features, but I've used the forum for that. |
Are there any worrisome changes made to docs I should review by any chance? Great work! Keep it up man. You're redefining web development. Thank you! |
Can I get I see <!-- show @ 0, img @ 1-->
<img v-show="true" v-img:200*200="imgSrc"> <!-- img @ 0, show @ 1-->
<img v-img:200*200="imgSrc" v-show="true"> Should I use |
@banricho good point, that's been overlooked! See updated directive function signature. |
First of all, sorry for I am not quite sure that could I ask this problem here, and I have a little bit requirements want to say.
I hope the children can be as some kind of arguments, not only limit in attributes
But I think it's not quite good, I hope it can like this one I made before in React coverflow |
@andyyou - that question is probably best posted on the forum, since it isn't an issue, nor a clear suggestion, nor any real help to this issue. If you find out that your requirements can't be met with Vue in your forum thread, then you can open a new issue here. Scott |
@smolinari Thanks |
"But for more complex cases, it is recommended to introduce a dedicated state management layer using Vuex." This seems to imply that state should be used over events. I see them as completely separate - an event is a moment in time, whereas state does not change. You could say that you could watch the state, but that also does not convey a specific moment, but instead anytime something changes. I'm interested in the meaning behind this recommendation. |
@jrenton Generally, we can consider the event system simply as component A telling component B to change it's state, or A telling B to do something else. |
@jrenton instead of a soup of components talking to each other Vuex suggest a single channel for components to express "intentions" with actions, and record "facts" with mutations. |
I'm using Twig along with Vue. Until now (vue 1.0) I've been passing data into my components like this:
(Note that If I'm understanding things correctly, in Vue 2.0 I should do it like this:
|
@gholol no it's just <my-component :data="{{ DATA }}"></my-component> Actually it seems your old usage shouldn't work in the first place. |
Well it worked fine... Like I said, the data are coming from twig templating engine. Now in Vue 2.0 it doesn't work. I've been trying to pass it like you said (without single apostrophes) but data property gets undefined.
EDIT: It works, I forgot to mention that the DATA variable is a string |
@jrenton My idea and motivation is quite simple seems Vue doesn't like React that compel us to use JSX. We can choose a lot of I hope I can use children element syntax as a parameter(arguments) pass args to parent because in some template language like |
@yyx990803 Feeling adventurous today wanted to see how much effort would it take to migrate some 1.0 to 2.0a, unfortunately since it's not possible to use simple interpolation anymore, how would I go about and do something simple as |
ES6 inline templates work in binding expressions:
|
If that's the only way to get this working on 2.0, then don't mind me saying that that's a regression in the lovely syntax 1.0 got us used to – yes I know that's just ES2015. I assume interpolation was removed for performance reasons? I just hope it's worth the uglier syntax. |
@oskarkrawczyk I assume you want to end up with something like The 2.0 version (and proper 1.0, in fact) will be |
@simplesmiler Understood. I think |
@yyx990803 can I dynamically insert component, like this?
|
How I can bind few values for an attribute which depend on expression? For example: new Vue({
el:'body',
data:{
flag: true
}
}) <input type="text" v-bind:placeholder="{test: flag, test2: !flag}" /> I expect next result: <input type="text" placeholder="test" />
<!-- or -->
<input type="text" placeholder="test2" /> |
@nervgh this is not the right place to ask this question. |
@wprater please avoid using this thread for unrelated questions. If there's a bug, file issue at corresponding repo with reproduction. |
Does Vue JSX support the object spread operator ? I've tried it but it doesn't work. |
It does and @yyx990803 put in a lot of effort to get it working. I'm doing this |
@blocka Thanks ! I thought the property name |
@yyx990803 e.g. var Parent = Vue.extend({
name: 'parent',
template: '<div><slot></slot></div>'
})
var Child = Vue.extend({
name: 'child',
template: '<span>hello</span>'
})
new Vue({
el: '#app',
components: [
Parent,
Child
],
replace: false,
template: '<parent><child></child></parent>'
}) It's bug? |
@QingWei-Li they are simply not supported anymore, since it was never an officially documented feature. The reason is that with ES2015 you can just write |
just a small suggestion, which will make more sense for users coming from php and even consistent with |
@ctf0 We are in RC stage, the API will not change anymore. And we won't introduce alternative syntax for doing the same thing either. I don't think that the mental overhead of |
With this new version, i would you handle this case. I have a calendar component (coming from semantic ui), which uses a classic text input, and show the date in a human format (like "July 10, 2016" for example). With v1.0, i was using a two-ways filter to convert that string into a proper date so my object data was directly ready for submit. But since filters won't work anymore in v-model, how could i do the same thing now in v2.0 ? Thanks |
@shadowRR would it be possible to see some code? |
@p-adams Sure. Here you go. First, my filter, which is use on my v-model for my calendar input. It's only purpose is to write, when the value change, a proper date type to my data (postgres date).
And i would you use it like this on my component (the input has a calendar system which return my date in the human readable format)
|
I'd recommend reading @yyx990803's post here: #2756 where he discusses two-way filters on |
I missed the post you're talking about, gonna see that, thanks ;) |
Hi, |
@f15gdsy |
I may have missed a few posts here, but what's the design decision behind this? 1.0: <foo @click="bar"></foo> 2.0: <div @click=bar>
<foo></foo>
<div> |
@fnlctrl, use the native modifier: |
@miljan-aleksic Thank you very much! I think this modifier should be added to |
Could I use Koa(1.x or 2.x) as the server? Is there any problem on |
import Vue from 'vue'
Vue.component('expanding', {
functional: true,
render (createElement, { children }) {
const data = {
props: {
name: 'expanding',
},
on: {
beforeEnter ($el) {
$el.classList.add('collapse')
console.log('beforeEnter')
},
enter ($el) {
$el.classList.remove('collapse')
$el.classList.add('collapsing')
$el.style.height = `${$el.scrollHeight}px`
console.log('enter')
},
afterEnter ($el) {
$el.classList.remove('collapsing')
$el.classList.add('collapse', 'in')
console.log('afterEnter')
},
beforeLeave ($el) {
$el.classList.add('collapsing')
$el.classList.remove('collapse', 'in')
$el.style.height = 0
console.log('beforeLeave')
},
leave ($el) {
console.log('leave')
},
afterLeave ($el) {
$el.classList.remove('collapsing')
$el.classList.add('collapse')
$el.style.display = 'none'
console.log('afterLeave')
}
}
}
return createElement('transition', data, children)
}
}) <a href="#" :aria-expanded="showItem ? 'true' : 'false'" @click="showItem = !showItem">
<span class="icon is-small"><i class="fa fa-table"></i></span>
Tables
<span class="icon is-small is-angle"><i class="fa fa-angle-down"></i></span>
</a>
<expanding appear="true">
<ul v-show="showItem">
<li>
<router-link to="/tables/basic">Basic</router-link>
</li>
<li>
<router-link to="/tables/handsontable">Handsontable</router-link>
</li>
</ul>
</expanding> Why do not call the enter hook? |
@fundon You should ask the question on the forums or the gitter chat |
Locking this thread because:
If you have a bug, please open a separate issue following the issue reporting guide, if you have a question, please use the forum or gitter. |
Update: For a more definitive and detailed list of changes in 2.0, see the new migration guide. |
General Notes
High Level Changes
<script type="text/x-template">
, inline JavaScript strings, or compiled via single-file components), you are no longer subject to any of the template parsing limitations in 1.x. However, if you are relying on mounting to an element with existing content as template (using theel
option), you will still be subject to those limitations.vueify
orvue-loader
will perform the template pre-compilation.Global config
logging the error stackthrowing in place)v-on
.Vue.config.debugdeprecated, no longer useful since warnings come with stack traces by default nowVue.config.asyncdeprecated, async is required for rendering performanceVue.config.delimitersreworked as a component-level optionVue.config.unsafeDelimitersdeprecated, use v-htmlGlobal API
staggerdeprecated, set and access data-index onel
insteadVue.elementDirectivedeprecated, just use componentsVue.partialdeprecated, use functional componentsOptions
data
coercedeprecated. If you want to convert a prop, setup a local computed value based on it.prop binding modesdeprecated (v-model can work on components)DOM
replacedeprecated, components now must have exactly one root element.Lifecycle Hooks
initbeforeCreatereadydeprecated, use mounted (there's no longer the guarantee to be in-document)activatedeprecated, moved into vue-routerbeforeCompiledeprecated, use createdcompileddeprecated, use mountedattacheddeprecated, use custom in-dom check in other hooksdetacheddeprecated, same as aboveAssets
partialsdeprecatedelementDirectivesdeprecatedMisc
eventsdeprecated, since no more event propagationInstance Properties
vm.$elsdeprecated, merged with $refsInstance Methods
data
vm.$getdeprecated, just retrieve values directlyvm.$setdeprecated, use Vue.setvm.$deletedeprecated, use Vue.deletevm.$evaldeprecated, no real usevm.$interpolatedeprecated, no real usevm.$logdeprecated, use devtoolsevents
vm.$dispatchdeprecated, use global event bus or Vuex. (see below)vm.$broadcastdeprecated, same as aboveDOM
vm.$appendTodeprecated, just use native DOM API on vm.$el.vm.$beforedeprecatedvm.$afterdeprecatedvm.$removedeprecatedLifecycle
Directives
{{{ }}}
shorthand has been deprecated(value, index) in arr
,(value, key, index) in obj
deprecated$index
and$key
Vue.config.keyCodes
instead ofVue.directive('on').keyCodes
)debouncedeprecated, use v-on:input + 3rd party debounce functionv-refnow just a special attribute asref
v-eldeprecated (merged with ref)Special Components
<component>
<transition>
<transition-group>
<keep-alive>
<slot>
partialdeprecatedSpecial Attributes
Server-side Rendering
Other Breaking Changes
v-for
iteration syntax changeDeprecating
$index
and$key
Both of these are being deprecated in favor of more explicit named indices and keys. This syntax is a bit magical and has limitations in nested loops. As a bonus, there will be two fewer points of syntax for newcomers to learn.
New array syntax
value in arr
(value, index) in arr
(switched order of arguments to be more consistent with JavaScript'sforEach
andmap
)New object syntax
value in obj
(value, key) in obj
(switched order of arguments, partly to be more consistent with many common object iterators, such as lodash's)(value, key, index) in obj
(index will now be available in object iteration for visual purposes, such as table striping)Directive interface change
In general, in 2.0 directives have a greatly reduced scope of responsibility: they are now only used for applying low-level direct DOM manipulations. In most cases, you should prefer using Components as the main code-reuse abstraction.
Directives no longer have instances - this means there's no more
this
inside directive hooks andbind
,update
andunbind
now receives everything as arguments.Note the
binding
object is immutable, settingbinding.value
will have no effect, and properties added to it will not be persisted. You can persist directive state onel
if you absolutely need to:You can use destructuring if you only care about the value:
In addition, the
update
hook has a few changes:bind
.binding.value === binding.oldValue
to skip unnecessary updates, but there are also cases where you'd want to always apply updates, e.g. when the directive is bound to an Object that might have been mutated instead of replaced.elementDirective
, directive params and directive options such asacceptStatement
,deep
etc. are all deprecated.Filter Usage and Syntax Change
In Vue 2.0, there are several changes to the filter system:
Filters can now only be used inside text interpolations (
{{}}
tags). In the past we've found using filters with directives such asv-model
,v-on
etc. led to more complexity than convenience, and for list filtering onv-for
it is more appropriate to move that logic into JavaScript as computed properties.Vue 2.0 will not ship with any built-in filters. It is recommended to use standalone libraries dedicated for solving problems in a specific domain, e.g. moment.js for formatting dates and accounting.js for formatting financial currencies. You are also welcome to create your own filter pack and share it with the community!
The filter syntax has changed to be more inline with JavaScript function invocation, instead of taking space-delimited arguments:
Transition System
Transition CSS class changes:
The always-on
v-transition
class is no longer added and Vue now uses the same classes Angular and React CSSTransitionGroup does:v-enter
: applied before element is inserted, remove after 1 tick. (starting state for enter)v-enter-active
: applied before element is inserted, removed when transition/animation finishes. (active + ending state for enter)v-leave
: applied right when the leave transition is triggered, remove after 1 tick (starting state for leave)v-leave-active
: applied right when the leave transition is triggered, removed when the transition/animation finishes. (active + ending state for leave)v-enter-active
andv-leave-active
gives you the ability to specify different easing curves for enter/leave transitions. In most cases, upgrading means simply replacing your currentv-leave
withv-leave-active
. (For CSS animations, usev-enter-active
+v-leave-active
)Transition API Change
The
<transition>
componentAll single-element transition effects are now applied by wrapping the target element/component with the
<transition>
built-in component. This is an abstract component, which means it does not render an extra DOM element, nor does it show up in the inspected component hierarchy. It simply applies the transition behavior to the wrapped content inside.The simplest usage example:
The component defines a number of props and events that maps directly to the old transition definition options:
Props
name: String
Used to automatically generate transition CSS class names. e.g.
name: 'fade'
will auto expand to.fade-enter
,.fade-enter-active
, etc. Defaults to"v"
.appear: Boolean
Whether to apply transition on initial render. Defaults to
false
.css: Boolean
Whether to apply CSS transition classes. Defaults to
true
. If set tofalse
, will only trigger JavaScript hooks registered via component events.type: String
Specify the type of transition events to wait for to determine transition end timing. Available values are
"transition"
and"animation"
. By default, it will automatically detect the type that has a longer duration.mode: String
Controls the timing sequence of leaving/entering transitions. Available modes are
"out-in"
and"in-out"
; defaults to simultaneous.enterClass, leaveClass, enterActiveClass, leaveActiveClass, appearClass, appearActiveClass: String
Individually configure transition CSS classes.
Example applying transition to dynamic components:
Events
Corresponds to the JavaScript hooks available in 1.x API.
Example:
When the entering transition completes, the component's
transitionComplete
method will be called with the transitioned DOM element as the argument.Some notes:
leave-cancelled
is no longer available for insertion/removals. Once a leave transition starts, it cannot be cancelled. It is, however, still available forv-show
transitions.enter
andleave
hooks, the presence ofcb
as the second argument indicates the user wants explicit control of the ending timing of the transition.The
<transition-group>
componentAll multi-element transition effects are now applied by wrapping the elements with the
<transition-group>
built-in component. It exposes the same props and events as<transition>
does. The difference being that:<transition>
,<transition-group>
renders a real DOM element. By default it renders a<span>
, and you can configure what element is should render via thetag
prop. You can also use it with theis
attribute, e.g.<ul is="transition-group">
.<transition-group>
does not support themode
prop.<transition-group>
must be uniquely keyed.Example:
Moving Transitions
<transition-group>
supports moving transitions via CSS transform. When a child's position on screen has changed after an updated, it will get applied a moving CSS class (auto generated from thename
prop or configured with themoveClass
prop). If the CSStransform
property is "transition-able" when the moving class is applied, the element will be smoothly animated to its destination using the FLIP technique.See a live demo here.
Creating Reusable Transitions
Now that transitions are applied via components, they are no longer considered an asset type, so the global
Vue.transition()
method and thetransition
option are both deprecated. You can just configure the transition inline with component props and events. But how do we create reusable transition effects now, especially those with custom JavaScript hooks? Well, the answer is creating your own transition components (they are particularly suitable as functional components):You can then use it like this:
v-model changes
The
lazy
andnumber
params are now modifiers:New modifier:
.trim
- trims the input, as the name suggests.The
debounce
param has been deprecated. (See upgrade tip at bottom)v-model
no longer cares about initial inlinevalue
. It will always treat the Vue instance data as the source of truth. This means the following will render with a value of 1 instead of 2:Same goes for
<textarea>
with existing content. So instead of:Do:
The main idea is that the JS side should be considered the source of truth, not your templates.
v-model
no longer works when used on av-for
iterated primitive value:This doesn't work because it's the equivalent of this in JavaScript:
As you can see, setting
str
to another value in the iterator function will do nothing because it's just a local variable in the function scope. Instead, you should use an array of objects so thatv-model
can update the field on the object:Props Behavior
.once
and.sync
are deprecated. Props are now always one-way down. To produce side effects in the parent scope, a component needs to explicitly emit an event instead of relying on implicit binding.a
and then setthis.a = someOtherValue
in the component. Due to the new rendering mechanism, whenever the parent component re-renders, the child component's local changes will be overwritten. In general, in 2.0 you should treat props as immutable. Most use cases of mutating a prop can be replaced by either a data property or a computed property.keep-alive
keep-alive
is no longer a special attribute: it is now a wrapper component, similar to<transition>
:This makes it possible to use
keep-alive
on multiple conditional children (note the children should eventually evaluate to a single child - any child other than the first one will be ignored):When used together with
<transition>
, make sure to nest it inside:Slots
<slot>
s with the same name in the same template. When a slot is rendered it is "used up" and cannot be rendered elsewhere in the same render tree.<slot>
no longer preserves theslot
attribute. Use a wrapper element to style them, or, for advanced use cases, modify the inserted content programmatically using render functions.Refs
v-ref
is now no longer a directive: it is now a special attribute similar tokey
andtransition
:Dynamic ref bindings are now also supported:
vm.$els
andvm.$refs
are merged. When used on a normal element the ref will be the DOM element, and when used on a component the ref will be the component instance.vm.$refs
are no longer reactive, because they are registered/updated during the render process itself. Making them reactive would require duplicate renders for every change.On the other hand,
$refs
are designed primarily for programmatic access in JavaScript - it is not recommended to rely on$refs
in templates because it entails referring to state that does not belong to the instance itself.Misc
track-by
has been replaced withkey
. It now follows the same rule for binding an attribute: withoutv-bind:
or:
prefix, it is treated as a literal string. In most cases you'd want to use a dynamic binding, which expects a full expression instead of a string key. For example:Interpolation inside attributes are deprecated:
Attribute binding behavior change: only
null
,undefined
andfalse
are considered falsy when binding attributes. This means0
and empty strings will render as-is. For enumerated attributes. This means:draggable="''"
will render asdraggable="true"
.Also, for enumerated attributes, in addition to the falsy values above, the string value of "false" will also render as attr="false".
When used on a custom component,
v-on
now only listens to custom events $emitted by that component. (no longer listens to DOM events)v-else
no longer works withv-show
- just use negation expression.One time bindings (
{{* foo }}
) deprecated - usev-once
instead.Array.prototype.$set/$remove deprecated (use Vue.set or Array.prototype.splice instead)
:style
no longer supports inline!important
root instance can no longer use template props (use
propsData
instead)The
el
option can no longer be used inVue.extend
. It can now only be used as an instance creation option.Vue.set
andVue.delete
cannot work on Vue instances. It is now mandatory to properly declare all top-level reactive properties in thedata
option.It is now also prohibited to replace a component instance's root
$data
. This prevents some edge cases in the reactivity system and makes the component state more predictable (especially with type-checking systems).User watchers created via
vm.$watch
are now fired before the associated component re-renders. This gives the user a chance to further update other state before the component re-render, thus avoiding unnecessary updates. For example, you can watch a component prop and update the component's own data when the prop changes.To do something with the DOM after component updates, just use the updated lifecycle hook.
Upgrade Tips
How to Deal with Deprecation of
$dispatch
and$broadcast
?The reason that we are deprecating
$dispatch
and$broadcast
is that event flows that depend on the components tree structure can be hard to reason about when the components tree becomes large (simply put: it doesn't scale well in large apps and we don't want to set you up for pain later).$dispatch
and$broadcast
also do not solve the communication between sibling components. Instead, you can use a pattern similar to the EventEmitter in Node.js: a centralized event hub that allows components to communicate, no matter where they are in the components tree. Because Vue instances implement the event emitter interface, you can actually use an empty Vue instance for that purpose:And don't forget to use $off to unbind the event.
This pattern can serve as a replacement for
$dispatch
and$broadcast
in simple scenarios. But for more complex cases, it is recommended to introduce a dedicated state management layer using Vuex.How to Deal with the Deprecation of Array Filters?
For list filtering with
v-for
- one of the more common usage of filters - it is now recommended to use computed properties that return a processed copy of the original Array (see updated data grid example). The benefits is that you are no longer limited by the arbitrary filter syntax/API - it's just plain JavaScript now, and you naturally have access to the filtered result because it is a computed property.Also see this discussion thread.
How to Deal with the Deprecation of
debounce
forv-model
?Debouncing is used to limit how often we execute Ajax requests and other expensive operations. Vue's
debounce
attribute parameter forv-model
makes this easy, but it also debounces state updates rather than the expensive operations themselves, which comes with limitations.These limitations become apparent when designing a search indicator. Take a look at that example. Using the
debounce
attribute, there'd be no way to detect a dirty input before the search begins, because we'd lose access to the input's real-time state. By decoupling the debounce function from Vue, we're able to debounce only the operation we want to limit.There will be other times when debouncing isn't quite the right wrapper function. In the very common example of hitting an API for search suggestions, waiting to offer suggestions until after the user has stopped typing isn't an ideal experience. What you probably want instead is a throttling function. Now since you're already using a utility library like lodash for
debounce
, refactoring to usethrottle
instead takes only a few seconds!The text was updated successfully, but these errors were encountered: