Skip to content

1.0 binding syntax (latest reference) #1325

@yyx990803

Description

@yyx990803

Quick Reference

If this is your first time here, read the Detailed Changes below first.

<!-- normal directive -->
<div v-if="ok"></div>

<!-- directive with argument -->
<button v-on:click="onClick"></button>

<!-- v-on with argument + key modifier -->
<input v-on:keyup.enter="handleEnter">

<!-- literal modifier: pass literal string to directive -->
<a v-link.literal="/a/b/c"></a>

<!-- binding an attribute with v-bind -->
<img v-bind:src="imgSrc">
<a v-bind:href="baseURL + '/path'">

<!-- shorthand: colon for v-bind -->
<img :src="imgSrc">
<a :href="baseURL + '/path'">

<!-- shorthand: @ for v-on -->
<input
  @click="onClick"
  @keyup.enter="handleEnter">

<!-- props -->
<my-comp
  v-bind:prop="defaultOneWay"
  v-bind:prop.sync="twoWay"
  v-bind:prop.once="oneTime">
</my-comp>

<!-- component with props and custom events, in shorthand -->
<item-list
  :items="items"
  :mode="active"
  @ready="onItemsReady"
  @update="onItemsUpdate">
</item-list>

<!-- v-el and v-ref now use dedicated syntax -->

<!-- registers vm.$refs.child -->
<comp v-ref:child></comp>

<!-- registers vm.$els.node -->
<div v-el:node></div>

Detailed Changes from 0.12

  1. Directive Arguments

    The concept of multiple clauses (multiple directives separated by comma in the same attribute) is deprecated, and directive arguments are moved into the attribute name:

    <!-- before: -->
    <div v-dirname="arg1: expression1, arg2: expression2">
    
    <!-- after: -->
    <div
      v-dirname:arg1="expression1"
      v-dirname:arg2="expression2">

    Using real directives as example:

    <!-- before: -->
    <div v-on="click: doThis, keyup: doThat">
    
    <!-- after: -->
    <div
      v-on:click="doThis"
      v-on:keyup="doThat">
  2. Literal Directives

    There is no longer "literal directives" from the implementation perspective. All directives are reactive by default, which makes it easy to know whether an attribute value is an expression or a literal string. If you wish to pass the directive a literal string, use the following syntax:

    <!-- before: no way to tell if this is a string or an expression! -->
    <div v-dirname="abc">
    
    <!-- after: explicitly denoting a literal string -->
    <div v-dirname.literal="abc">

    The ending .literal is called a Binding Modifier, which forces the directive to be bound in literal mode. We will see this concept used below for prop binding types as well. In literal mode, the directive's update function will be called once, with the literal string as the argument.

  3. Attribute Bindings

    Mustache tags can only appear inside native attributes. To dynamically bind a custom attribute or a prop, use the v-bind directive (which replaces v-attr):

    <!-- this is valid -->
    <a href="{{baseURL}}/abc"></a>
    
    <!-- these are no longer valid -->
    <component is="{{view}}"></component>
    <partial name="{{partialName}}"></partial>
    
    <!-- use v-bind for non-native attributes -->
    <component v-bind:is="view"></component>
    <partial v-bind:name="partialName"></partial>

    Vue will raise a warning whenever mustaches are used in non-native attributes.

    style and class enhancements

    In particular, since v-class and v-style are deprecated, bindings for class and style have some dedicated enhancements. You can pass in JavaScript Object or Array literals:

    <!-- toggle classes -->
    <div v-bind:class="{ 'class-a': true, 'class-b': false }"></div>
    <!-- apply a list of classes -->
    <div v-bind:class="[ dynamicClass, 'literal-class' ]"></div>
    
    <!-- apply style object (camelCase accepted) -->
    <div v-bind:style="{ fontSize: '14px', color: 'red' }"></div>
    <!-- apply multiple style objects -->
    <div v-bind:style="[ styleObjectA, styleObjectB ]"></div>
  4. Props

    Previously props use mustaches to indicate reactivity. Now they must use v-bind:

    <!-- before -->
    <my-comp
      prop="a literal string"
      prop="{{expression}}">
    <my-comp>
    
    <my-comp
      prop="a literal string"
      v-bind:prop="expression">
    </my-comp>

    Binding type indicators (@ and *) are now replaced by more explicit binding modifiers:

    <!-- before -->
    <my-comp
      prop="{{defaultOneWay}}"
      prop="{{@twoWay}}"
      prop="{{*oneTime}}">
    </my-comp>
    
    <!-- after -->
    <my-comp
      v-bind:prop="defaultOneWay"
      v-bind:prop.sync="twoWay"
      v-bind:prop.once="oneTime">
    </my-comp>
  5. Shorthands

    You may have noticed we will be using v-bind and v-on quite a lot. 1.0 will provide optional shorthand syntax for these two directives. v-bind: can be shortened to a single colon :, while v-on: can be shortened to a single @ symbol:

    <!-- attribute binding -->
    <img :src="imgSrc">
    
    <!-- event handlers -->
    <input @click="handleClick" @keyup="handleKeyup">
    
    <!-- props -->
    <my-comp
      :prop="expression"
      :prop.sync="twoWay"
      :prop.once="oneTime">
    </my-comp>
    
    <!-- special attributes -->
    <component :is="view"></component>
    <partial :name="partialName"></partial>

    If you are only using Vue as an enhancement on existing HTML pages, you may want to stick with the v- prefixed versions. The shorthand is designed to make the template more succinct when you are building large SPAs where Vue manages everything. Don't worry about it not looking like valid HTML - all browsers can parse it just fine, and Vue removes all the special stuff in the rendered HTML anyway.

  6. v-on on Child Component

    v-on will also listen to custom Vue events (emitted via vm.$emit) when it is used on a child component. The idea is that props and events should constitute the public API of a component:

    • props for passing data down;
    • events for handling actions up.

    A typical component would look like this:

    <item-list
      v-bind:items="items"
      v-bind:mode="active"
      v-on:ready="onItemsReady"
      v-on:update="onItemsUpdate">
    </item-list>

    With shorthand:

    <item-list
      :items="items"
      :mode="active"
      @ready="onItemsReady"
      @update="onItemsUpdate">
    </item-list>
  7. v-on modifiers

    v-on can now leverage a Key Modifier that replaces the old key filter (you can use all the old aliases usable in the key filter, or use a direct keyCode):

    <!-- before -->
    <input v-on="
      keyup: handleEnter | key 'enter',
      keyup: handleEsc | key 'esc'">
    
    <!-- after -->
    <input
      @keyup.enter="handleEnter"
      @keyup.esc="handleEsc">

    In addition, you can use the .stop and .prevent modifiers for calling stopPropagation() and preventDefault().

  8. New Syntax for v-el and v-ref

    v-el and v-ref were previously "literal" directives, but you just need to give them an argument. Also, to make things more explicit, vm.$ is now vm.$refs, and vm.$$ is now vm.$els.

    <!-- child component ref, registers vm.$refs.child -->
    <comp v-ref:child></comp>
    <!-- elsewhere... -->
    {{$refs.child.msg}}
    
    <!-- element ref, registers vm.$els.node -->
    <div v-el:node></div>

    Caveat: camelCase names are converted to all lowercase when the HTML is parsed:

    <comp v-ref:someThing></comp>

    Gets rendered as:

    <comp v-ref:something></comp>

    Thus, it is necessary to use the dash-case <-> camelCase mapping for refs too (similar to props):

    <comp v-ref:some-thing></comp>
    {{ $refs.someThing.msg }}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions