Browse By

Vuejs v2.0.0-alpha.1 released

ViewJS 2.0

First release of Viewjs 2.0 is available for download. Many improvements over the previous but also quite a few breaking changes. Quite exciting time to be a javascript developer with all these changes in popular frameworks if you ask me.  Keeps your mind busy! Have a look below for more info (from github)

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

Other Breaking Changes

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 – you can persist directive state on el if you absolutely need to):

// example directive
export default {
  bind (el, binding, vnode) {
    // the binding object exposes value, oldValue, arg and modifiers.
    // the context Vue instance can be accessed as vnode.context.
  },
  update (el, binding, vnode, oldVnode) { ... },

  // postupdate 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.
  postupdate (el, binding, vnode, oldVNode) { ... },

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

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

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

elementDirective and directive params are 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 change: 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)
  • leaveCancelled callback 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.
  • enter and leave hooks renamed to onEnter and onLeave, respectively.

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.

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.

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

Misc

  • track-by has been replaced with key. 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:
    <!-- 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.
  • 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.
  • 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.

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', function (id) {
  // ...
})

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’sdebounce 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!

Leave a Reply

Your email address will not be published. Required fields are marked *