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

Closed
yyx990803 opened this Issue May 13, 2016 · 210 comments

Comments

Projects
None yet
@yyx990803
Member

yyx990803 commented May 13, 2016

This is a live document. Last update: 08/17/2016 as of 2.0.0-rc.2

General Notes

  • A checked item means it has been implemented in the 2.0 development branch.
  • Features subject to change during development.
  • The breaking change list is not guaranteed to be complete during development.
  • There are some upgrade tips at the end.

High Level Changes

  • The template parser no longer relies on the DOM (unless you are using the real DOM as your template), so as long as you are using string templates (<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 the el option), you will still be subject to those limitations.
  • The compiler (the part which converts a template string to a render function) and the runtime can now be separated. There will be two different builds:
    • Standalone build: includes both the compiler and the runtime. This functions basically exactly the same Vue 1.x does.
    • Runtime only build: since it doesn't include the compiler, you need to either pre-compiled templates in a compile step, or manually written render functions. The npm package will export this build by default, since when consuming Vue from npm, you will likely be using a compilation step (with Browserify or Webpack), during which vueify or vue-loader will perform the template pre-compilation.

Global config

  • Vue.config.silent
  • Vue.config.optionMergeStrategies
  • Vue.config.devtools
  • Vue.config.errorHandler new - global hook for handling uncaught errors during component render and watchers (default behavior is logging the error stack throwing in place)
  • Vue.config.keyCodes new - configure custom key aliases for v-on.
  • Vue.config.debug deprecated, no longer useful since warnings come with stack traces by default now
  • Vue.config.async deprecated, async is required for rendering performance
  • Vue.config.delimiters reworked as a component-level option
  • Vue.config.unsafeDelimiters deprecated, use v-html

Global API

  • Vue.extend
  • Vue.nextTick
  • Vue.set
  • Vue.delete
  • Vue.directive
  • Vue.component
  • Vue.use
  • Vue.mixin
  • Vue.compile new (only in standalone build)
  • Vue.transition
    • stagger deprecated, set and access data-index on el instead
  • Vue.filter
  • Vue.elementDirective deprecated, just use components
  • Vue.partial deprecated, use functional components

Options

data
  • data
  • props
    • prop validation
    • default value
    • coerce deprecated. If you want to convert a prop, setup a local computed value based on it.
    • prop binding modes deprecated (v-model can work on components)
  • propsData new, instantiation only
  • computed
  • methods
  • watch
DOM
  • el
  • template
  • render new
  • replace deprecated, components now must have exactly one root element.
Lifecycle Hooks
  • init beforeCreate
  • created
  • beforeDestroy
  • destroyed
  • beforeMount new
  • mounted new
  • beforeUpdate new
  • updated new
  • activated new (for keep-alive)
  • deactivated new (for keep-alive)
  • ready deprecated, use mounted (there's no longer the guarantee to be in-document)
  • activate deprecated, moved into vue-router
  • beforeCompile deprecated, use created
  • compiled deprecated, use mounted
  • attached deprecated, use custom in-dom check in other hooks
  • detached deprecated, same as above
Assets
  • directives
  • components
  • transitions
  • filters
  • partials deprecated
  • elementDirectives deprecated
Misc
  • parent
  • mixins
  • name
  • extends
  • delimiters new, replacing the original global config option. Only available in standalone build.
  • functional new, makes the component stateless and instance-less (just a render function that returns virtual nodes)
  • events deprecated, since no more event propagation

Instance Properties

  • vm.$data
  • vm.$el
  • vm.$options
  • vm.$parent
  • vm.$root
  • vm.$children
  • vm.$refs
  • vm.$els deprecated, merged with $refs

Instance Methods

data
  • vm.$watch
  • vm.$get deprecated, just retrieve values directly
  • vm.$set deprecated, use Vue.set
  • vm.$delete deprecated, use Vue.delete
  • vm.$eval deprecated, no real use
  • vm.$interpolate deprecated, no real use
  • vm.$log deprecated, use devtools
events
  • vm.$on
  • vm.$once
  • vm.$off
  • vm.$emit
  • vm.$dispatch deprecated, use global event bus or Vuex. (see below)
  • vm.$broadcast deprecated, same as above
DOM
  • vm.$nextTick
  • vm.$appendTo deprecated, just use native DOM API on vm.$el.
  • vm.$before deprecated
  • vm.$after deprecated
  • vm.$remove deprecated
Lifecycle
  • vm.$mount
  • vm.$destroy

Directives

  • v-text
  • v-html but {{{ }}} shorthand has been deprecated
  • v-if
  • v-show
  • v-else
  • v-for
    • key (replacing track-by)
    • Object v-for
    • range v-for
    • argument order updates: (value, index) in arr, (value, key, index) in obj
    • $index and $key deprecated
  • v-on
    • modifiers
    • on child component
    • custom keyCodes (now avaiable via Vue.config.keyCodes instead of Vue.directive('on').keyCodes)
  • v-bind
    • as prop
    • xlink
    • bind object
  • v-bind:style
    • prefix sniffing
  • v-bind:class
  • v-model
    • lazy (as modifier)
    • number (as modifier)
    • ignoring composition events
    • debounce deprecated, use v-on:input + 3rd party debounce function
  • v-cloak
  • v-pre
  • v-once new
  • v-ref now just a special attribute as ref
  • v-el deprecated (merged with ref)

Special Components

  • <component>
    • :is
    • async components
    • inline-template
  • <transition>
  • <transition-group>
  • <keep-alive>
  • <slot>
  • partial deprecated

Special Attributes

  • key
  • ref
  • slot

Server-side Rendering

  • renderToString
  • renderToStream
  • client-side hydration

Other Breaking Changes

v-for iteration syntax change

  • Deprecating $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's forEach and map)
  • 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 and bind, update and unbind now receives everything as arguments.

Note the binding object is immutable, setting binding.value will have no effect, and properties added to it will not be persisted. You can persist directive state on el if you absolutely need to:

<div v-example:arg.modifier="a.b"></div>
// example directive
export default {
  bind (el, binding, vnode) {
    // the binding object exposes value, oldValue, expression, arg and modifiers.
    binding.expression // "a.b"
    binding.arg // "arg"
    binding.modifiers // { modifier: true }
    // the context Vue instance can be accessed as vnode.context.
  },

  // update has a few changes, see below
  update (el, binding, vnode, oldVnode) { ... },

  // componentUpdated is a new hook that is called AFTER the entire component
  // has completed the current update cycle. This means all the DOM would
  // be in updated state when this hook is called. Also, this hook is always
  // called regardless of whether this directive's value has changed or not.
  componentUpdated (el, binding, vnode, oldVNode) { ... },

  unbind (el, binding, vnode) { ... }
}

You can use destructuring if you only care about the value:

export default {
  bind (el, { value }) {
    // ...
  }
}

In addition, the update hook has a few changes:

  1. It no longer gets called automatically after bind.
  2. It now always gets calls when the component is re-rendered, regardless of whether the value it's bound to has changed or not. You can compare 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 as acceptStatement, deep etc. are all deprecated.

Filter Usage and Syntax Change

In Vue 2.0, there are several changes to the filter system:

  1. Filters can now only be used inside text interpolations ({{}} tags). In the past we've found using filters with directives such as v-model, v-on etc. led to more complexity than convenience, and for list filtering on v-for it is more appropriate to move that logic into JavaScript as computed properties.

  2. 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!

  3. The filter syntax has changed to be more inline with JavaScript function invocation, instead of taking space-delimited arguments:

    {{ date | formatDate('YY-MM-DD') }}
    

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 and v-leave-active gives you the ability to specify different easing curves for enter/leave transitions. In most cases, upgrading means simply replacing your current v-leavewith v-leave-active. (For CSS animations, use v-enter-active + v-leave-active)

Transition API Change

  • The <transition> component

    All 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:

    <transition>
      <div v-if="ok">toggled content</div>
    </transition>

    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 to false, 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:

    <transition name="fade" mode="out-in" appear>
      <component :is="view"></component>
    </transition>

    Events

    Corresponds to the JavaScript hooks available in 1.x API.

    • before-enter
    • enter
    • after-enter
    • before-leave
    • leave
    • after-leave
    • before-appear
    • appear
    • after-appear

    Example:

    <transition @after-enter="transitionComplete">
      <div v-show="ok">toggled content</div>
    </transition>

    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 for v-show transitions.
    • Similar to 1.0, for enter and leave hooks, the presence of cb as the second argument indicates the user wants explicit control of the ending timing of the transition.
  • The <transition-group> component

    All 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:

    1. Unlike <transition>, <transition-group> renders a real DOM element. By default it renders a <span>, and you can configure what element is should render via the tag prop. You can also use it with the is attribute, e.g. <ul is="transition-group">.
    2. <transition-group> does not support the mode prop.
    3. Every child in a <transition-group> must be uniquely keyed.

    Example:

    <transition-group tag="ul" name="slide">
      <li v-for="item in items" :key="item.id">
        {{ item.text }}
      </li>
    </transition-group>

    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 the name prop or configured with the moveClass prop). If the CSS transform 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 the transition 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):

    Vue.component('fade', {
      functional: true,
      render (createElement, { children }) {
        const data = {
          props: {
            name: 'fade'
          },
          on: {
            beforeEnter () { /* ... */ }, // <-- Note hooks use camelCase in JavaScript (same as 1.x)
            afterEnter () { /* ... */ }
          }
        }
        return createElement('transition', data, children)
      }
    })

    You can then use it like this:

    <fade>
      <div v-if="ok">toggled content</div>
    </fade>

v-model changes

  • The lazy and number params are now modifiers:

    <input v-model.lazy="text">
  • 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 inline value. 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:

    data: {
      val: 1
    }
    <input v-model="val" value="2">

    Same goes for <textarea> with existing content. So instead of:

    <textarea v-model="val">hello world</textarea>

    Do:

    data () {
      return {
        val: 'hello world'
      }
    }
    <textarea v-model="val"></textarea>

    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 a v-for iterated primitive value:

    <input v-for="str in strings" v-model="str">

    This doesn't work because it's the equivalent of this in JavaScript:

    strings.map(function (str) {
      return createElement('input', ...)
    })

    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 that v-model can update the field on the object:

    <input v-for="obj in objects" v-model="obj.str">

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.
  • Mutating a prop locally is now considered an anti-pattern, e.g. declaring a prop a and then set this.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>:

  <keep-alive>
    <component :is="view"></component>
  </keep-alive>

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):

  <keep-alive>
    <comp-a v-if="a > 1"></comp-a>
    <comp-b v-else></comp-b>
  </keep-alive>

When used together with <transition>, make sure to nest it inside:

  <transition>
    <keep-alive>
      <component :is="view"></component>
    </keep-alive>
  </transition>

Slots

  • It is no longer supported to have duplicate <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.
  • Content inserted via named <slot> no longer preserves the slot 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 to key and transition:

    <!-- before -->
    <comp v-ref:foo></comp>
    
    <!-- after -->
    <comp ref="foo"></comp>

    Dynamic ref bindings are now also supported:

    <comp :ref="dynamicRef"></comp>
  • vm.$els and vm.$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 with key. It now follows the same rule for binding an attribute: without v-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:

    <!-- 1.x -->
    <div v-for="item in items" track-by="id">
    
    <!-- 2.0 -->
    <div v-for="item in items" :key="item.id">
  • Interpolation inside attributes are deprecated:

    <!-- 1.x -->
    <div id="{{ id }}">
    
    <!-- 2.0 -->
    <div :id="id">
  • Attribute binding behavior change: only null, undefined and false are considered falsy when binding attributes. This means 0 and empty strings will render as-is. For enumerated attributes. This means :draggable="''" will render as draggable="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 with v-show - just use negation expression.

  • One time bindings ({{* foo }}) deprecated - use v-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 in Vue.extend. It can now only be used as an instance creation option.

  • Vue.set and Vue.delete cannot work on Vue instances. It is now mandatory to properly declare all top-level reactive properties in the data 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:

var bus = new Vue()
// in component A's method
bus.$emit('id-selected', 1)
// in component B's created hook
bus.$on('id-selected', this.someMethod)

And don't forget to use $off to unbind the event.

// in component B's destroyed hook
bus.$off('id-selected', this.someMethod)

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 for v-model?

Debouncing is used to limit how often we execute Ajax requests and other expensive operations. Vue's debounce attribute parameter for v-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 use throttle instead takes only a few seconds!

@yyx990803 yyx990803 added the 2.0 label May 13, 2016

@yyx990803 yyx990803 added this to the 2.0-beta milestone May 13, 2016

@rekateka

This comment has been minimized.

Show comment
Hide comment
@rekateka

rekateka May 14, 2016

Contributor

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?

Contributor

rekateka commented May 14, 2016

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?

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 May 14, 2016

Member

@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.

Member

yyx990803 commented May 14, 2016

@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.

@rekateka

This comment has been minimized.

Show comment
Hide comment
@rekateka

rekateka May 15, 2016

Contributor

Thanks, @yyx990803. I still have a couple more questions regarding the compiler and other features, but I've used the forum for that.

Contributor

rekateka commented May 15, 2016

Thanks, @yyx990803. I still have a couple more questions regarding the compiler and other features, but I've used the forum for that.

@roblav96

This comment has been minimized.

Show comment
Hide comment
@roblav96

roblav96 May 19, 2016

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!

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!

@banricho

This comment has been minimized.

Show comment
Hide comment
@banricho

banricho May 24, 2016

Can I get this.arg of my directive?

I see vnode.data.directives has arg, but when I have two or more directives, I can not know the index.

<!-- 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 forEach? Thank you!

banricho commented May 24, 2016

Can I get this.arg of my directive?

I see vnode.data.directives has arg, but when I have two or more directives, I can not know the index.

<!-- 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 forEach? Thank you!

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 May 24, 2016

Member

@banricho good point, that's been overlooked! See updated directive function signature.

Member

yyx990803 commented May 24, 2016

@banricho good point, that's been overlooked! See updated directive function signature.

@andyyou

This comment has been minimized.

Show comment
Hide comment
@andyyou

andyyou May 28, 2016

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.
The requirement is I hope I can design my component's usage like this

<carousel>
  <img src="..." alt="..." desc="..." is="argument">
  <img src="..." alt="..." desc="..." is="argument">
</carousel>

I hope the children can be as some kind of arguments, not only limit in attributes
For now I can make a component, the usage like

<carousel items="[{}, {}, {}]"></carousel>

But I think it's not quite good, I hope it can like this one I made before in React coverflow

andyyou commented May 28, 2016

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.
The requirement is I hope I can design my component's usage like this

<carousel>
  <img src="..." alt="..." desc="..." is="argument">
  <img src="..." alt="..." desc="..." is="argument">
</carousel>

I hope the children can be as some kind of arguments, not only limit in attributes
For now I can make a component, the usage like

<carousel items="[{}, {}, {}]"></carousel>

But I think it's not quite good, I hope it can like this one I made before in React coverflow

@smolinari

This comment has been minimized.

Show comment
Hide comment
@smolinari

smolinari May 28, 2016

@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.

http://forum.vuejs.org/

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

@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.

http://forum.vuejs.org/

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

@andyyou

This comment has been minimized.

Show comment
Hide comment

andyyou commented May 28, 2016

@smolinari Thanks

@jrenton

This comment has been minimized.

Show comment
Hide comment
@jrenton

jrenton May 28, 2016

"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 commented May 28, 2016

"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.

@fnlctrl

This comment has been minimized.

Show comment
Hide comment
@fnlctrl

fnlctrl May 28, 2016

Member

@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.
So for the first case, we can use state management (managing a shared state for A and B) instead of using event system to let A tell B to change state.
For the second case, I think it can be handled with the 'event bus' approach pretty well.

Member

fnlctrl commented May 28, 2016

@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.
So for the first case, we can use state management (managing a shared state for A and B) instead of using event system to let A tell B to change state.
For the second case, I think it can be handled with the 'event bus' approach pretty well.

@simplesmiler

This comment has been minimized.

Show comment
Hide comment
@simplesmiler

simplesmiler May 28, 2016

Member

@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.

Member

simplesmiler commented May 28, 2016

@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.

@gholol

This comment has been minimized.

Show comment
Hide comment
@gholol

gholol May 29, 2016

I'm using Twig along with Vue.

Until now (vue 1.0) I've been passing data into my components like this:

<my-component data="{{ DATA }}"><my-component>

(Note that {{ and }} are twig tags - for vue I've been using custom delimiters ${ and })

If I'm understanding things correctly, in Vue 2.0 I should do it like this:

<my-component :data=" '{{ DATA }}' "></my-component>
right?

gholol commented May 29, 2016

I'm using Twig along with Vue.

Until now (vue 1.0) I've been passing data into my components like this:

<my-component data="{{ DATA }}"><my-component>

(Note that {{ and }} are twig tags - for vue I've been using custom delimiters ${ and })

If I'm understanding things correctly, in Vue 2.0 I should do it like this:

<my-component :data=" '{{ DATA }}' "></my-component>
right?

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 May 29, 2016

Member

@gholol no it's just

<my-component :data="{{ DATA }}"></my-component>

Actually it seems your old usage shouldn't work in the first place.

Member

yyx990803 commented May 29, 2016

@gholol no it's just

<my-component :data="{{ DATA }}"></my-component>

Actually it seems your old usage shouldn't work in the first place.

@yyx990803 yyx990803 closed this May 29, 2016

@yyx990803 yyx990803 reopened this May 29, 2016

@gholol

This comment has been minimized.

Show comment
Hide comment
@gholol

gholol May 29, 2016

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.

Error: SyntaxError: missing } after property list

EDIT: It works, I forgot to mention that the DATA variable is a string

gholol commented May 29, 2016

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.

Error: SyntaxError: missing } after property list

EDIT: It works, I forgot to mention that the DATA variable is a string

@andyyou

This comment has been minimized.

Show comment
Hide comment
@andyyou

andyyou May 30, 2016

@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 template.

I hope I can use children element syntax as a parameter(arguments) pass args to parent because in some template language like slim if you have a bit many attributes or say the attr's name is quite long then we have to put all the things in one line. it's easier make code of one line over 80 characters.

andyyou commented May 30, 2016

@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 template.

I hope I can use children element syntax as a parameter(arguments) pass args to parent because in some template language like slim if you have a bit many attributes or say the attr's name is quite long then we have to put all the things in one line. it's easier make code of one line over 80 characters.

@oskarkrawczyk

This comment has been minimized.

Show comment
Hide comment
@oskarkrawczyk

oskarkrawczyk Jun 1, 2016

@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 <input type="text" name="account[categories][{{ category.id }}]"> in 2.0?

@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 <input type="text" name="account[categories][{{ category.id }}]"> in 2.0?

@LinusBorg

This comment has been minimized.

Show comment
Hide comment
@LinusBorg

LinusBorg Jun 1, 2016

Member

ES6 inline templates work in binding expressions:

<input type="text" :name="`account[categories][${ category.id }]`">

https://jsfiddle.net/Linusborg/cm4v75xh/

Member

LinusBorg commented Jun 1, 2016

ES6 inline templates work in binding expressions:

<input type="text" :name="`account[categories][${ category.id }]`">

https://jsfiddle.net/Linusborg/cm4v75xh/

@oskarkrawczyk

This comment has been minimized.

Show comment
Hide comment
@oskarkrawczyk

oskarkrawczyk Jun 1, 2016

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.

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.

@simplesmiler

This comment has been minimized.

Show comment
Hide comment
@simplesmiler

simplesmiler Jun 1, 2016

Member

@oskarkrawczyk I assume you want to end up with something like name="account[categories][fruits]" in your DOM, because this is what your expression would render.

The 2.0 version (and proper 1.0, in fact) will be :name=" 'account[categories][' + category.id + ']' ".

Member

simplesmiler commented Jun 1, 2016

@oskarkrawczyk I assume you want to end up with something like name="account[categories][fruits]" in your DOM, because this is what your expression would render.

The 2.0 version (and proper 1.0, in fact) will be :name=" 'account[categories][' + category.id + ']' ".

@oskarkrawczyk

This comment has been minimized.

Show comment
Hide comment
@oskarkrawczyk

oskarkrawczyk Jun 1, 2016

@simplesmiler Understood. I think {{ }} just spoiled me a bit.

@simplesmiler Understood. I think {{ }} just spoiled me a bit.

@hilongjw

This comment has been minimized.

Show comment
Hide comment
@hilongjw

hilongjw Jun 3, 2016

@yyx990803 can I dynamically insert component, like this?

    render () {
        return this.$createElement('div', { staticClass: 'list-container' }, this.list)
    },
    data () {
         return {
               list: []
         }
    },
    method: {
         a () {
               this.list.push(this.$createElement('myComponent', {}))    
         }
    }

hilongjw commented Jun 3, 2016

@yyx990803 can I dynamically insert component, like this?

    render () {
        return this.$createElement('div', { staticClass: 'list-container' }, this.list)
    },
    data () {
         return {
               list: []
         }
    },
    method: {
         a () {
               this.list.push(this.$createElement('myComponent', {}))    
         }
    }
@nervgh

This comment has been minimized.

Show comment
Hide comment
@nervgh

nervgh Jun 3, 2016

Contributor

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" />
Contributor

nervgh commented Jun 3, 2016

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" />
@simplesmiler

This comment has been minimized.

Show comment
Hide comment
@simplesmiler

simplesmiler Jun 3, 2016

Member

@nervgh this is not the right place to ask this question.
Use ternary expression, v-bind:placeholder="flag ? 'test' : 'test2'".

Member

simplesmiler commented Jun 3, 2016

@nervgh this is not the right place to ask this question.
Use ternary expression, v-bind:placeholder="flag ? 'test' : 'test2'".

@nervgh

This comment has been minimized.

Show comment
Hide comment
@nervgh

nervgh Jun 3, 2016

Contributor

@simplesmiler , thanks for your answer. I try to say that Object-Syntax will be useful in these cases, but is does not work as I expect.

Contributor

nervgh commented Jun 3, 2016

@simplesmiler , thanks for your answer. I try to say that Object-Syntax will be useful in these cases, but is does not work as I expect.

@simplesmiler

This comment has been minimized.

Show comment
Hide comment
@simplesmiler

simplesmiler Jun 3, 2016

Member

@nervgh object syntax is only applicable to attributes that take a list of strings. Of native attributes the only such attribute is class, and for the components there would be no way to detect from the child side whether you meant to send a list of strings or a proper object.

Member

simplesmiler commented Jun 3, 2016

@nervgh object syntax is only applicable to attributes that take a list of strings. Of native attributes the only such attribute is class, and for the components there would be no way to detect from the child side whether you meant to send a list of strings or a proper object.

@JasonWoof

This comment has been minimized.

Show comment
Hide comment
@JasonWoof

JasonWoof Jun 4, 2016

Re: .once and .sync are deprecated.

Doesn't this break really common design patterns?

I can't think how you'd be able to have simple components for handling form fields without these.

I have simple components for different form field types, eg here's my "textbox" component template::

<label>{{type.caption}}:<input type="text" v-model="data"></label>

...and also a more complex component for lists which provides a ui to add and remove elements from arrays in the data structure

Then I use these components eg like so:

<div v-for="field in type.fields">
    <component :data.sync="data[field.name]" :is="field.ctype" :type="field">

Note: All of these components have two props: data and type. data is the node in the data structure being edited that the component is responsible for providend a UI for editing, and type is the node in the (massive, static) data structure which contains the types/fields hierarchy.

How can stuff like that work without .sync?

It seems to me that it would severely complicate things to create some sort of messaging system between these components where the sub-components can somehow communicate to the parent which sub-component they are, and the parent can then figure out what part of its data structure to modify.

I really hope I'm missing something.... because it looks like you're saying that using components to create editors for parts of your data structure is an anti-pattern. Whaat? So far that's the only thing I've used Vue for. I'm guessing you think that removing this feature will encourage people to write cleaner code. Maybe it will have that effect on some people, but many people will write much nastier code to work around this limitation. Modifying state is the only useful thing that computers do. Please continue to make this easier.

Re: .once and .sync are deprecated.

Doesn't this break really common design patterns?

I can't think how you'd be able to have simple components for handling form fields without these.

I have simple components for different form field types, eg here's my "textbox" component template::

<label>{{type.caption}}:<input type="text" v-model="data"></label>

...and also a more complex component for lists which provides a ui to add and remove elements from arrays in the data structure

Then I use these components eg like so:

<div v-for="field in type.fields">
    <component :data.sync="data[field.name]" :is="field.ctype" :type="field">

Note: All of these components have two props: data and type. data is the node in the data structure being edited that the component is responsible for providend a UI for editing, and type is the node in the (massive, static) data structure which contains the types/fields hierarchy.

How can stuff like that work without .sync?

It seems to me that it would severely complicate things to create some sort of messaging system between these components where the sub-components can somehow communicate to the parent which sub-component they are, and the parent can then figure out what part of its data structure to modify.

I really hope I'm missing something.... because it looks like you're saying that using components to create editors for parts of your data structure is an anti-pattern. Whaat? So far that's the only thing I've used Vue for. I'm guessing you think that removing this feature will encourage people to write cleaner code. Maybe it will have that effect on some people, but many people will write much nastier code to work around this limitation. Modifying state is the only useful thing that computers do. Please continue to make this easier.

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 Jun 4, 2016

Member

@JasonWoof v-model in 2.0 can work on custom components. The component simply needs to:

  1. expose a prop named value
  2. emit an input event when the value needs to be synced to parent, e.g. this.$emit('input', value)

See example.

Member

yyx990803 commented Jun 4, 2016

@JasonWoof v-model in 2.0 can work on custom components. The component simply needs to:

  1. expose a prop named value
  2. emit an input event when the value needs to be synced to parent, e.g. this.$emit('input', value)

See example.

@JasonWoof

This comment has been minimized.

Show comment
Hide comment
@JasonWoof

JasonWoof Jun 4, 2016

@yyx990803 Thanks for the explanation and link. Now I'm just stuck on:

Why remove .sync?

I don't see the advantage, only disadvantages. The example you linked shows that you can achieve the same thing with either :selected.sync or v-model. I only see disadvantages for the v-model method:

  1. It requires significant boiler-plate on the sub-component side, is more complicated, more to learn, etc.
  2. You can only pass one value with v-model, but you can have multiple .sync props

I don't see how switching to v-model makes anything clearer/cleaner. In both cases, the only indication in the parent that the child component can easily modify parent state is the syntax of the prop in the template. I would even argue that .sync is more clear.

The other thing is that when you pass objects/arrays/etc as props, then they are mutable from the child component. So you can't shield programmers from being able to change the state from the child components in this case (which I assume is very common.) So it seems to me like you are introducing a stumbling block by removing the thing that makes it so passing string values works the same as passing object values. .sync makes my code simpler and more consistent by always having my "data" props writable from the child side, no matter the data type.

I'm new to Vue.js (3 days ago) but from what I can see so far, Vue.js is valuable mainly because of two things:

  1. easy dom manipulation with templates
  2. automatic value/data change propagation, including triggering template changes

At least that's what I've discovered so far.

It seems to me that removing .sync makes it difficult to get Vue.js to consistently do the second.

@yyx990803 Thanks for the explanation and link. Now I'm just stuck on:

Why remove .sync?

I don't see the advantage, only disadvantages. The example you linked shows that you can achieve the same thing with either :selected.sync or v-model. I only see disadvantages for the v-model method:

  1. It requires significant boiler-plate on the sub-component side, is more complicated, more to learn, etc.
  2. You can only pass one value with v-model, but you can have multiple .sync props

I don't see how switching to v-model makes anything clearer/cleaner. In both cases, the only indication in the parent that the child component can easily modify parent state is the syntax of the prop in the template. I would even argue that .sync is more clear.

The other thing is that when you pass objects/arrays/etc as props, then they are mutable from the child component. So you can't shield programmers from being able to change the state from the child components in this case (which I assume is very common.) So it seems to me like you are introducing a stumbling block by removing the thing that makes it so passing string values works the same as passing object values. .sync makes my code simpler and more consistent by always having my "data" props writable from the child side, no matter the data type.

I'm new to Vue.js (3 days ago) but from what I can see so far, Vue.js is valuable mainly because of two things:

  1. easy dom manipulation with templates
  2. automatic value/data change propagation, including triggering template changes

At least that's what I've discovered so far.

It seems to me that removing .sync makes it difficult to get Vue.js to consistently do the second.

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 Jun 4, 2016

Member

@JasonWoof because explicit vs. implicit side effects outside of the components own scope makes all the difference in long term maintainability.

Member

yyx990803 commented Jun 4, 2016

@JasonWoof because explicit vs. implicit side effects outside of the components own scope makes all the difference in long term maintainability.

@yyx990803 yyx990803 closed this Jun 4, 2016

@yyx990803 yyx990803 reopened this Jun 4, 2016

@LinusBorg

This comment has been minimized.

Show comment
Hide comment
@LinusBorg

LinusBorg Jun 4, 2016

Member

... and while one could argue that people simply should learn when to not use .sync, our experience so far is different. people tend to rely too much on this and create code they later can hardly debug.

so this is a design decision to force people to do it right from the beginning.

an example:

  • We sync a value name between a parent and a child. all is well.
  • we decide 'hey, when that value changes, we need to do something in the parent!'
  • So, we create a watchfunction. Nice!
  • Later on we realize that the watcher seems to fire when we don't want it to. But we can't really tell why, because we can't really put console.log() anywhere to trace the behaviour.
  • After much hard thinking, we realize that we really only want that something to happen when the value is changed in the parent, not the child or the "grandparent".
  • Now we try to find a way to differenciate these scenarios in the watch function somehow.
  • Only to realize that this makes a simple thing very complicated
  • and in the end, someone tells us to remove sync, so we throw it all away and use a one-way prop and an emitted event to handle the situation - the code becomes simpler and more explicit, so it's simple to reason about how and when data flows and it becomes easier to debug it. The bug is found quickly and we can move on.

...and this becomes even more crazy when you sync more than one level deep.

This is an (anti-)pattern we have seen over and over on the forums and in the gitter chat.

Removing .sync forces people to write clear, explizit, maintainable code from the start, because their code won't stay simple enough for .sync for very long, most of the time.

Member

LinusBorg commented Jun 4, 2016

... and while one could argue that people simply should learn when to not use .sync, our experience so far is different. people tend to rely too much on this and create code they later can hardly debug.

so this is a design decision to force people to do it right from the beginning.

an example:

  • We sync a value name between a parent and a child. all is well.
  • we decide 'hey, when that value changes, we need to do something in the parent!'
  • So, we create a watchfunction. Nice!
  • Later on we realize that the watcher seems to fire when we don't want it to. But we can't really tell why, because we can't really put console.log() anywhere to trace the behaviour.
  • After much hard thinking, we realize that we really only want that something to happen when the value is changed in the parent, not the child or the "grandparent".
  • Now we try to find a way to differenciate these scenarios in the watch function somehow.
  • Only to realize that this makes a simple thing very complicated
  • and in the end, someone tells us to remove sync, so we throw it all away and use a one-way prop and an emitted event to handle the situation - the code becomes simpler and more explicit, so it's simple to reason about how and when data flows and it becomes easier to debug it. The bug is found quickly and we can move on.

...and this becomes even more crazy when you sync more than one level deep.

This is an (anti-)pattern we have seen over and over on the forums and in the gitter chat.

Removing .sync forces people to write clear, explizit, maintainable code from the start, because their code won't stay simple enough for .sync for very long, most of the time.

@phanan

This comment has been minimized.

Show comment
Hide comment
@phanan

phanan Aug 10, 2016

Member

@miljan-aleksic There's a Patreon campaign wink wink.

Member

phanan commented Aug 10, 2016

@miljan-aleksic There's a Patreon campaign wink wink.

@miljan-aleksic

This comment has been minimized.

Show comment
Hide comment
@miljan-aleksic

miljan-aleksic Aug 10, 2016

You know what @phanan, you are totally right. I have started supporting Evan personally and as soon as the company products start giving results will make sure the support becomes more noticeable.

miljan-aleksic commented Aug 10, 2016

You know what @phanan, you are totally right. I have started supporting Evan personally and as soon as the company products start giving results will make sure the support becomes more noticeable.

@GlurG

This comment has been minimized.

Show comment
Hide comment
@GlurG

GlurG Aug 10, 2016

The ready lifecycle hook is deprecated in favor of mounted; but according to the changelog there is no guarantee that the component will be rendered before mounted is called. This causes sporadic errors when I want to initialize certain jquery components (like selectize) after the component has initialized. Which lifecycle hook should I use instead? Can the "ready" hook be emulated like this:

function mounted() {
  Vue.nextTick(() => {
    //...
  });
}

GlurG commented Aug 10, 2016

The ready lifecycle hook is deprecated in favor of mounted; but according to the changelog there is no guarantee that the component will be rendered before mounted is called. This causes sporadic errors when I want to initialize certain jquery components (like selectize) after the component has initialized. Which lifecycle hook should I use instead? Can the "ready" hook be emulated like this:

function mounted() {
  Vue.nextTick(() => {
    //...
  });
}
@LinusBorg

This comment has been minimized.

Show comment
Hide comment
@LinusBorg

LinusBorg Aug 10, 2016

Member

@GlurG Yes, that will work. And by the way, that was also nessessariy with ready'() in 1.0 in many cases.

Member

LinusBorg commented Aug 10, 2016

@GlurG Yes, that will work. And by the way, that was also nessessariy with ready'() in 1.0 in many cases.

@blocka

This comment has been minimized.

Show comment
Hide comment
@blocka

blocka Aug 10, 2016

Is there any reason there can't be a hook for this regardless? I've also
across this...even in 1.0, and resorted to things like looping with raf to
check if its in the dom, etc.
On Aug 10, 2016 6:26 PM, "Thorsten Lünborg" notifications@github.com
wrote:

@GlurG https://github.com/GlurG Yes, that will work. And by the way,
that was also nessessariy with ready'() in 1.0 in many cases.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#2873 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AACounAoI8p65soUUrbdaiwteDXKgMGJks5qee25gaJpZM4IedHC
.

blocka commented Aug 10, 2016

Is there any reason there can't be a hook for this regardless? I've also
across this...even in 1.0, and resorted to things like looping with raf to
check if its in the dom, etc.
On Aug 10, 2016 6:26 PM, "Thorsten Lünborg" notifications@github.com
wrote:

@GlurG https://github.com/GlurG Yes, that will work. And by the way,
that was also nessessariy with ready'() in 1.0 in many cases.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#2873 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AACounAoI8p65soUUrbdaiwteDXKgMGJks5qee25gaJpZM4IedHC
.

@miljan-aleksic

This comment has been minimized.

Show comment
Hide comment
@miljan-aleksic

miljan-aleksic Aug 10, 2016

When using the render functions the core directives are ignored, which is reasonable. But some are not so easy to reproduce using plain js, as the v-model which has workarounds for IE9 and probably solves other edge case issues.

It makes you reconsider using a template instead, but thats not possible or the best option in some situations. The docs could definitely offer more guidance on this topic and besides it could be a good idea to have some helper when working with render functions which would help solving these common situations and make no one miss a template.

miljan-aleksic commented Aug 10, 2016

When using the render functions the core directives are ignored, which is reasonable. But some are not so easy to reproduce using plain js, as the v-model which has workarounds for IE9 and probably solves other edge case issues.

It makes you reconsider using a template instead, but thats not possible or the best option in some situations. The docs could definitely offer more guidance on this topic and besides it could be a good idea to have some helper when working with render functions which would help solving these common situations and make no one miss a template.

@sqal

This comment has been minimized.

Show comment
Hide comment
@sqal

sqal Aug 10, 2016

@miljan-aleksic sorry, i deleted my comment because i noticed it's only works for v-show or custom directives, and yeah, as you said in case of v-model, it's required to add input/change listener and update our data manually

sqal commented Aug 10, 2016

@miljan-aleksic sorry, i deleted my comment because i noticed it's only works for v-show or custom directives, and yeah, as you said in case of v-model, it's required to add input/change listener and update our data manually

@wprater

This comment has been minimized.

Show comment
Hide comment
@wprater

wprater Aug 11, 2016

Contributor

is the new activated hook supposed to be called when a route is fired that activates/mounts a router-view? Im not seeing this behavior currently.

Contributor

wprater commented Aug 11, 2016

is the new activated hook supposed to be called when a route is fired that activates/mounts a router-view? Im not seeing this behavior currently.

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 Aug 11, 2016

Member

@wprater no, it's solely related to <keep-alive> and nothing else.

Member

yyx990803 commented Aug 11, 2016

@wprater no, it's solely related to <keep-alive> and nothing else.

@wprater

This comment has been minimized.

Show comment
Hide comment
@wprater

wprater Aug 11, 2016

Contributor

@yyx990803 Im wrapping my router-view in a keep-alive, but I cannot seem to find a hook for when I route back to the pervious view. mounted nor activated are called. I need to be certain the dom is rendered.

Contributor

wprater commented Aug 11, 2016

@yyx990803 Im wrapping my router-view in a keep-alive, but I cannot seem to find a hook for when I route back to the pervious view. mounted nor activated are called. I need to be certain the dom is rendered.

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 Aug 11, 2016

Member

@wprater please avoid using this thread for unrelated questions. If there's a bug, file issue at corresponding repo with reproduction.

Member

yyx990803 commented Aug 11, 2016

@wprater please avoid using this thread for unrelated questions. If there's a bug, file issue at corresponding repo with reproduction.

@dorayx

This comment has been minimized.

Show comment
Hide comment
@dorayx

dorayx Aug 11, 2016

Does Vue JSX support the object spread operator ? I've tried it but it doesn't work.

dorayx commented Aug 11, 2016

Does Vue JSX support the object spread operator ? I've tried it but it doesn't work.

@blocka

This comment has been minimized.

Show comment
Hide comment
@blocka

blocka Aug 11, 2016

It does and @yyx990803 put in a lot of effort to get it working.

I'm doing this <Component {...{ props } }></Component> and it works as documented.

blocka commented Aug 11, 2016

It does and @yyx990803 put in a lot of effort to get it working.

I'm doing this <Component {...{ props } }></Component> and it works as documented.

@dorayx

This comment has been minimized.

Show comment
Hide comment
@dorayx

dorayx Aug 11, 2016

@blocka Thanks ! I thought the property name props was not needed 😂

dorayx commented Aug 11, 2016

@blocka Thanks ! I thought the property name props was not needed 😂

@QingWei-Li

This comment has been minimized.

Show comment
Hide comment
@QingWei-Li

QingWei-Li Aug 12, 2016

Contributor

@yyx990803
components options don't support array type, but it is work in 1.x.

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?

Contributor

QingWei-Li commented Aug 12, 2016

@yyx990803
components options don't support array type, but it is work in 1.x.

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?

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 Aug 12, 2016

Member

@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 components: { Parent, Child }.

Member

yyx990803 commented Aug 12, 2016

@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 components: { Parent, Child }.

@yyx990803 yyx990803 closed this Aug 12, 2016

@yyx990803 yyx990803 reopened this Aug 12, 2016

@ctf0

This comment has been minimized.

Show comment
Hide comment
@ctf0

ctf0 Aug 13, 2016

just a small suggestion,
is there any chance for the normal array iteration we use v-foreach and for range we use v-for.

which will make more sense for users coming from php and even consistent with .each in JQ or foreach in JS

ctf0 commented Aug 13, 2016

just a small suggestion,
is there any chance for the normal array iteration we use v-foreach and for range we use v-for.

which will make more sense for users coming from php and even consistent with .each in JQ or foreach in JS

@LinusBorg

This comment has been minimized.

Show comment
Hide comment
@LinusBorg

LinusBorg Aug 13, 2016

Member

@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 v-for="item in items" is significant enough to warrant that.

Member

LinusBorg commented Aug 13, 2016

@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 v-for="item in items" is significant enough to warrant that.

@shadowRR

This comment has been minimized.

Show comment
Hide comment
@shadowRR

shadowRR Aug 14, 2016

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

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

@p-adams

This comment has been minimized.

Show comment
Hide comment
@p-adams

p-adams Aug 14, 2016

@shadowRR would it be possible to see some code?

p-adams commented Aug 14, 2016

@shadowRR would it be possible to see some code?

@shadowRR

This comment has been minimized.

Show comment
Hide comment
@shadowRR

shadowRR Aug 14, 2016

@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).

Vue.filter( 'formatDate', {
        read( date ) {
            return date;
        },
        write( date ) {
            if( !date ) return null;
            return moment( date, 'D MMMM YYYY' ).format( 'YYYY-MM-DD' );
        }
    } );

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)

<div class="required field">
        <label>Start date</label>
         <div class="ui calendar">
                 <div class="ui input left icon">
                      <i class="calendar icon"></i>
                      <input v-model="section.start | formatDate" type="text">
                 </div>
         </div>
</div>

@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).

Vue.filter( 'formatDate', {
        read( date ) {
            return date;
        },
        write( date ) {
            if( !date ) return null;
            return moment( date, 'D MMMM YYYY' ).format( 'YYYY-MM-DD' );
        }
    } );

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)

<div class="required field">
        <label>Start date</label>
         <div class="ui calendar">
                 <div class="ui input left icon">
                      <i class="calendar icon"></i>
                      <input v-model="section.start | formatDate" type="text">
                 </div>
         </div>
</div>
@p-adams

This comment has been minimized.

Show comment
Hide comment
@p-adams

p-adams Aug 14, 2016

I'd recommend reading @yyx990803's post here: #2756 where he discusses two-way filters on v-model. Also, it may be better to ask questions such as this here: http://forum.vuejs.org/

p-adams commented Aug 14, 2016

I'd recommend reading @yyx990803's post here: #2756 where he discusses two-way filters on v-model. Also, it may be better to ask questions such as this here: http://forum.vuejs.org/

@shadowRR

This comment has been minimized.

Show comment
Hide comment
@shadowRR

shadowRR Aug 14, 2016

I missed the post you're talking about, gonna see that, thanks ;)

I missed the post you're talking about, gonna see that, thanks ;)

@f15gdsy

This comment has been minimized.

Show comment
Hide comment
@f15gdsy

f15gdsy Aug 15, 2016

Hi,
I have some doubts in new life cycle hooks.
If I want to register an event handler when mounted, and deregister it before unmount, how should I make it work? Add checks & logics in created & beforeDestroy hooks?
In Vue 1.x I would use attached & detached hooks.
But in 2.0 there is mounted hook but no unmount hook. Feels a bit not corresponding.
Is there any reason why no unmount hook is provided?

f15gdsy commented Aug 15, 2016

Hi,
I have some doubts in new life cycle hooks.
If I want to register an event handler when mounted, and deregister it before unmount, how should I make it work? Add checks & logics in created & beforeDestroy hooks?
In Vue 1.x I would use attached & detached hooks.
But in 2.0 there is mounted hook but no unmount hook. Feels a bit not corresponding.
Is there any reason why no unmount hook is provided?

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 Aug 15, 2016

Member

@f15gdsy mounted corresponds to destroyed. There's no attached/detatched counter parts in 2.0 - you need to do the in-dom check yourself. If your events don't care about in-dom/off-dom then mounted and beforeDestroy are the appropriate places to do that.

Member

yyx990803 commented Aug 15, 2016

@f15gdsy mounted corresponds to destroyed. There's no attached/detatched counter parts in 2.0 - you need to do the in-dom check yourself. If your events don't care about in-dom/off-dom then mounted and beforeDestroy are the appropriate places to do that.

@fnlctrl

This comment has been minimized.

Show comment
Hide comment
@fnlctrl

fnlctrl Aug 15, 2016

Member

When used on a custom component, v-on now only listens to custom events $emitted by that component. (no longer listens to DOM events)

I may have missed a few posts here, but what's the design decision behind this?
It would make binding simple click events on components very verbose..

1.0:

<foo @click="bar"></foo>

2.0:

<div @click=bar>
  <foo></foo>
<div>
Member

fnlctrl commented Aug 15, 2016

When used on a custom component, v-on now only listens to custom events $emitted by that component. (no longer listens to DOM events)

I may have missed a few posts here, but what's the design decision behind this?
It would make binding simple click events on components very verbose..

1.0:

<foo @click="bar"></foo>

2.0:

<div @click=bar>
  <foo></foo>
<div>
@miljan-aleksic

This comment has been minimized.

Show comment
Hide comment
@miljan-aleksic

miljan-aleksic Aug 15, 2016

@fnlctrl, use the native modifier: @click.native="bar".

@fnlctrl, use the native modifier: @click.native="bar".

@fnlctrl

This comment has been minimized.

Show comment
Hide comment
@fnlctrl

fnlctrl Aug 15, 2016

Member

@miljan-aleksic Thank you very much! I think this modifier should be added to Directives -> v-on -> modifiers in this issue

Member

fnlctrl commented Aug 15, 2016

@miljan-aleksic Thank you very much! I think this modifier should be added to Directives -> v-on -> modifiers in this issue

@Ruy-Zhou

This comment has been minimized.

Show comment
Hide comment
@Ruy-Zhou

Ruy-Zhou Aug 16, 2016

Could I use Koa(1.x or 2.x) as the server? Is there any problem on vue-server-renderer with Koa?

Could I use Koa(1.x or 2.x) as the server? Is there any problem on vue-server-renderer with Koa?

@fundon

This comment has been minimized.

Show comment
Hide comment
@fundon

fundon Aug 16, 2016

@yyx990803

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 commented Aug 16, 2016

@yyx990803

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?

@posva

This comment has been minimized.

Show comment
Hide comment
@posva

posva Aug 16, 2016

Member

@fundon You should ask the question on the forums or the gitter chat

Member

posva commented Aug 16, 2016

@fundon You should ask the question on the forums or the gitter chat

@vuejs vuejs locked and limited conversation to collaborators Aug 16, 2016

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 Aug 16, 2016

Member

Locking this thread because:

  1. We are now in API freeze in RC so this document will no longer be updated.
  2. Too many people are using this as a general FAQ thread, which is not what it is for.

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.

Member

yyx990803 commented Aug 16, 2016

Locking this thread because:

  1. We are now in API freeze in RC so this document will no longer be updated.
  2. Too many people are using this as a general FAQ thread, which is not what it is for.

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.

@yyx990803 yyx990803 closed this Aug 16, 2016

@yyx990803 yyx990803 reopened this Aug 16, 2016

@yyx990803 yyx990803 closed this Sep 17, 2016

@chrisvfritz

This comment has been minimized.

Show comment
Hide comment
@chrisvfritz

chrisvfritz Sep 21, 2016

Member

Update: For a more definitive and detailed list of changes in 2.0, see the new migration guide.

Member

chrisvfritz commented Sep 21, 2016

Update: For a more definitive and detailed list of changes in 2.0, see the new migration guide.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.