[譯] Vue 2.0 的變化(二)之其餘重大更改

v-for迭代語法變化

  • 丟棄$index$keyjavascript

  • 新數組語法css

    • value in arrhtml

    • (value, index) in arrvue

  • 新對象語法java

    • value in objnode

    • (value, key) in objgit

    • (value, key, index) in objgithub

指令接口的改變

大致來講,2.0版本中指令大範圍的下降功能,它們僅用於低層次的直接dom操做。在多數狀況下,你更應該使用組件做爲主要的代碼重構抽象。vuex

指令再也不有實例,這意味着指令中將不存在this,而且bind, updateunbind目前將接受任何數據做爲參數。express

請注意,綁定對象是不可變的。設置binding.value沒有任何效果。而且在它上面添加屬性不會持久,若是你真的很是須要能夠在el配置上添加指令狀態。

<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) { ... }
}

若是你只關心值可使用解構:

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

除此以外,update鉤子有一些變化:

  • bind以後將再也不自動調用

  • 當組件從新渲染時總能響應,不管被綁定的值是否發生改變。你能夠經過binding.value === binding.oldValue比較跳過沒必要要的更新,但也會有狀況下,你但願應用始終更新。例如,當指令綁定到對象那可能但願是變化而不是替代。

elementDirective, 指令參數和指令配置,例如acceptStatement, deep等等
均被刪除。

過濾器用法和語法變化

在vue 2.0,filter有了一系列的變化:

  • filter如今只能用於文本插入({{}}標籤)。在以前咱們在指令中使用filter,例如v-modelv-on等等,致使使用的複雜性,而且在v-for上的列表過濾,它更適合遷移到計算性能的js中。

  • vue 2.0不提供任何內置過濾器。建議使用獨立的方法解決特定域的問題,例如moment.js用於格式化時間,accounting.js用於格式化金融貨幣。也歡迎你來建立本身的過濾器,並與社區分享吧!

  • filter語法更改成內嵌的js函數調用,而不是採起空格分割的參數。

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

過渡組件

過渡CSS的變化

  • v-enter:在元素插入前應用,1秒後刪除。(開始於進入狀態)

  • v-enter-active:在元素插入前應用,當transition/animation結束時移除。

  • v-leave:當離開的transition觸發時正確應用,一秒後刪除。(開始於離開狀態)

  • v-leave-active:當離開的transition觸發時正確應用,當transition/animation結束時移除。

v-enter-activev-leave-active幫助你指定不一樣的曲線用於進入/離開動畫。在多數狀況下,升級只需將當前的v-leave替換爲v-leave-active。(對於css動畫,使用v-enter-activev-leave-active

過渡API的變化

  • <transition>組件

全部單元素的過分效果經過使用<transition>這個內置組件包裝目標元素或組件獲得相應的效果。這是一個抽象組件,意味着它不會渲染額外的DOM元素,也不會在組件層次結構中展現。它僅僅用於過渡行爲裏面的包裹內容。

最簡單的用法示例:

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

該組件定義了一些屬性和事件,直接映射到舊版的過渡定義選項。

屬性
  • name: String

    • 用於自動生成過渡CSS類名。例如,name: 'fade'將會自動生成 .fade-enter.fade-enter-active等等。默認是v

  • appear: Boolean

    • 是否在最初的渲染應用的過渡。(默認值false

  • css: Boolean

    • 是否應用css過分類,默認值true。若是設置爲false,只能經過觸發組件事件註冊的JavaScript鉤子。

  • type: String

    • 指定等待肯定過渡結束時轉變的事件類型。可用的值是transitionanimation。默認狀況下,它會自動檢測一個持續時間較長的類型。

  • mode: String

    • 控制離開/進入轉換的時序。可用的模式是in-outout-in,默認爲同步。

  • enterClass, leaveClass, enterActiveClass, leaveActiveClass, appearClass, appearActiveClass: String

    • 單獨配置的過渡css類

過渡到動態組件的示例:

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

對應的在1.x API中可用的js鉤子:

  • before-enter

  • enter

  • after-enter

  • before-leave

  • leave

  • after-leave

  • before-appear

  • appear

  • after-appear

例子:

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

當進入的過渡效果完成時,組件的transitionComplete方法將會在過渡DOM元素做爲參數被調用。

一些注意事項:

  • leave-cancelled在插入刪除中不可用。一旦離開的過渡效果開始,將不能被取消。可是仍然可用於v-show

  • 和1.0相似,對於enterleave鉤子,在cb做爲第二個參數的存在下表示使用者想要過渡結束時間的明確控制。

<transition-group>組件

全部的多元素過渡效果經過使用<transition-group>內置組件包裝元素應用。它暴露了和<transition>同樣的屬性和事件。不一樣之處在於:

  1. 不一樣於<transition>,<transition-group>渲染一個真實的DOM元素。默認是渲染一個<span>標籤,而且你能夠配置哪些元素應該經過標記的屬性呈現。你也可使用is特性,例如<ul is="transition-group">

  2. <transition-group>不支持mode屬性。

  3. <transition-group>下的子組件必須有惟一的key。

例子:

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

建立可重用的轉換

如今transitions可以經過組件應用,它們補在被視爲一種單獨類型,所以全局的Vue.transition()方法和transition配置都被丟棄。你能夠經過組件的屬性和方法配置內嵌的過渡。可是,咱們如今怎麼建立可重複使用的過渡效果,尤爲是那些自定義的js鉤子?答案是建立本身的過渡組件(它們特別適合做爲功能組件):

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

你能夠這麼使用:

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

v-model的變化

  • lazynumber參數如今是修飾符。

    <input v-model.lazy="text">
  • 新的修飾符:.trim-修整輸入,顧名思義

  • debounce參數被丟棄

  • v-model再也不關心初始值。它始終將data的數據做爲資源。這意味着數據將是以1呈現而不是2.

    data: {
    val: 1
    }
    <input v-model="val" value="2">
  • 當使用v-for時,v-model再也不生效。

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

Refs

  • v-ref如今再也不是一個指令,而是一個相似於key的屬性

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

    依然支持動態綁定:

    <comp :ref="dynamicRef"></comp>
  • vm.$elsvm.$refs合併了。在正常元素上使用是DOM元素,在組件上使用是組件實例。

雜項

  • track-by已經被key替代。對於綁定屬性它遵照相同的規則,沒有v-bind:或者:字頭,它被視爲普通字符串。大多數狀況下須要動態綁定,以下:

    <!-- 1.x -->
    <div v-for="item in items" track-by="id">
    
    <!-- 2.0 -->
    <div v-for="item in items" :key="item.id">
  • 內插值屬性已被棄用。

    <!-- 1.x -->
    <div id="{{ id }}">
    
    <!-- 2.0 -->
    <div :id="id">
  • 屬性綁定行爲變化:當綁定屬性時,只有nullundefinefalse被認爲是false。這意味着0和空字符串依舊呈現出原來的樣子。對於枚舉屬性,:draggable="''"將被渲染爲draggable="true"
    另外,對於枚舉屬性,除了上述false的值,false字符串也會被渲染爲attr="false"

  • 當使用一個自定義組件,v-on只聽自定義事件$emitted掛載在組件上。(再也不監聽DOM事件)

  • v-else再也不適用於v-show,請使用其餘的否認表達式。

  • 單次綁定({{* foo }})被移除,請使用v-once

  • Array.prototype.$set/$remove被丟棄(使用Vue.set或者Array.prototype.splice)。

  • :style再也不支持!import

  • root實例不能使用props(請使用propsData

  • Vue.extendel配置項不能被使用,它如今只能被用做一個實例建立選項。

  • 在vue的實例中不能使用Vue.setVue.delete

升級小提示

如何處理丟棄的$dispatch$broadcast

咱們棄用$dispatch$broadcast的緣由在於依賴組件樹結構的事件流,當組件樹變得很大時很難推理(簡單地說:它不能在大型應用很好地擴展,咱們不但願之後給你設置痛點)。$dispatch$broadcast不能解決同級組件之間的通訊。從而,你可使用和node中的EventEmitter相似的模式:一個容許組件通訊的集中事件樞紐,不管他們在組件樹的任何地方。由於vue的實例實現了事件發射接口,你可使用空的vue實例達到目的:

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)

而且不要忘記使用$off解綁事件:

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

這種模式在簡單的場景中能夠做爲$dispatch$broadcast的替代。可是在複雜的場景中,建議使用vuex創建一個專門的狀態管理層。

如何處理數組中filter的棄用?

對於使用v-for進行列表過濾-過濾器常見用法之一-如今建議使用computed屬性返回原始數組的一個副本(查閱更新數據例子)。好處在於你再也不受到filter語法的限制,如今它只是普通的javascript,而且你能夠正常訪問過濾結果,由於它只是一個計算的屬性。

如何處理在v-modeldebounce的丟棄?

debounce用於咱們多久執行異步請求和其餘操做,在v-model中使用十分容易,但這樣也延遲了狀態更新帶來了限制。
當在設計一個搜索功能時這個限制變得很明顯,看看這個例子,使用debounce屬性,在搜索以前無法檢測髒數據,由於咱們不能訪問輸入的實時狀態。

未完待續....


翻譯自2.0 Changes

相關文章
相關標籤/搜索