Vue.js 2.0 がリリース
prismrismと申します。唐突な初投稿は Vue.js についてです。
この1年半ほど Vue.js 1.x と遊び続けていたのですが、先日 Vue.js 2.0 がリリースされました。まだ α 版なので確定していないことも多いようですが、2.0にはまだリファレンスに相当するものが無いので自己満足のために「新機能の情報が知りたいけど英語読みたくない…」という方々の助力となるべくMarkdown記法の練習も兼ねて和訳を書いてみようと思い至りました。
2.0 でどのような変更があったのかは公式 Github ページの issues に記載されています。今回は一番情報がまとまっている Features の投稿を訳していきたいと思います。~~ちょうど 6/13 に alpha.2のリリースに併せて編集した旨が書いているのでホットな情報ですね。~~この記事投稿して数時間後にあっさりalpha.3が出てますね…。相変わらずの開発速度に脱帽です。
逐語訳で日本語が崩壊してしまうのが好きじゃないのでところどころ意訳していますが、生まれてこの方まるっと日本人なので英語が得意なわけでもないですし、プログラマーとしてはひよっこなので用語を適切に使用している自信もありません。
Qiitaの作法も存じ上げていないのですが、なにかあればツッコミを頂ければと思います。
正直なに書いてるかわからないところがチラホラ
※この翻訳の初版は 2016/06/15 に作成されました。
※投稿して6時間くらいにalpha.3が出てしまったので、今後は気付いたら随時更新します。
以下、翻訳
>これは随時更新される文書です。最終更新日: 2016/08/17 最新版 2.0.0-rc.2
注意事項
- チェックが付された項目はver 2.0 の開発ブランチに実装されていることを表します
- 開発中は Features のトップ( subject )を随時更新します
- 破壊的な変更のリストアップについて、開発中はその決定を保証するものではありません
- 更新に関するヒントが末尾にあります
主要な変更点
-
テンプレートの構文解析が DOM に依存しなくなりました(テンプレートとして実体 DOM を使用していない場合)。文字列型のテンプレート(
<script type="text/xtemplate>
タグ、埋め込まれたJavaScript文字列、あるいは単一ファイルのコンポーネントを通じてコンパイルされたテンプレート)を使用している限り、1.x のテンプレートの構文解析における制約を受けることはありません。しかしながら、(el
オプションを用いて)現存しているコンテンツをテンプレートとして要素にマウントしている場合、引き続きこれらの制約に従わなければなりません。 -
コンパイラ(テンプレートとなる文字列をレンダー関数に置換する部分)とランタイムは分轄が可能となりました。2つの異なるビルドが提供されます。
- 独立ビルド:コンパイラ及びランタイムの両方を含みます。これらは基本的には Vue 1.x とほぼ同様に機能します。
- ランタイム単体ビルド:こちらはコンパイラを含まないため、コンパイル時にプリコンパイルされたテンプレートか自作のレンダー関数が必要です。npm から Vue を扱っている場合、
vueify
かvue-loader
がテンプレートのプリコンパイルを行うような(Browserify か Webpack による)コンパイル手順を踏んでいるはずなので、npm パッケージはこちらのビルドをデフォルトで出力するようになっています。
グローバル設定
- Vue.config.silent
- Vue.config.optionMergeStrategies
- Vue.config.devtools
-
Vue.config.errorHandler 新規 : コンポーネントのレンダーとウォッチャの間で補足できなかったエラーを扱うグローバルフックです( デフォルトでは
エラースタックを記録します所定の場所でスローします) -
Vue.config.keyCodes 新規 :
v-on
でのキー入力に対応するカスタムエイリアスを設定します -
Vue.config.debug非推奨 : デフォルトで スタックトレースに警告を表示するため実用性を失いました -
Vue.config.async非推奨 : レンダリング処理には非同期であることが必須です -
Vue.config.delimitersコンポーネントのオプションとして作り直されました -
Vue.config.unsafeDelimiters非推奨 : v-html を使用してください
グローバル API
- Vue.extend
- Vue.nextTick
- Vue.set
- Vue.delete
- Vue.directive
- Vue.component
- Vue.use
- Vue.mixin
- Vue.compile 新規 (独立ビルドのみ)
-
Vue.transition
-
stagger非推奨 : 代わりにel
へdata-index属性値を設定し、アクセスしてください
-
- Vue.filter
-
Vue.elementDirective非推奨 : コンポーネントを使用してください -
Vue.partial非推奨 : 関数コンポーネント(functional components)を使用してください
オプション
##data
- data
-
props
- prop validation
- default value
-
coerce非推奨 : Propを変換したい場合、それを用いたローカルの算出プロパティを作成してください -
prop binding modes非推奨(コンポーネントに対してv-modelが使用できます)
- propsData 新規:インスタンス作成時のみ
- computed
- methods
- watch
DOM
- el
- template
- render 新規
-
replace非推奨 : コンポーネントはただ1つのルート要素が__必須__となりました
ライフサイクルフック
-
initbeforeCreate - created
- beforeDestroy
- destroyed
- beforeMound 新規
- mounted 新規
- beforeUpdate 新規
- updated 新規
- activated 新規( keep-alive 用)
- deactivated 新規( keep-alive 用)
-
ready非推奨 : mounted を使用してください(document内での存在を保証できません) -
activate非推奨 : vue-router へ移行されました -
beforeCompile非推奨 : created を使用してください -
compiled非推奨 : mounted を使用してください -
attached非推奨 : 他のフックに DOM 内部での存在チェックを自作してください -
detached非推奨 : 同上
##アセット
- directives
- components
- transitions
- filters
-
partials非推奨 -
elementDirectives非推奨
##その他
- parent
- mixins
- name
- extends
- delimiters 新規 : 元のグローバル設定から置換されました。独立ビルドでのみ有効です
- functional 新規 : コンポーネントをステートレスおよびインスタンスレスにします(仮想ノードを返すだけの単なるレンダー関数です)
-
events非推奨 : イベント伝播が起こらなくなりました
#インスタンスプロパティ
- vm.$data
- vm.$el
- vm.$options
- vm.$parent
- vm.$root
- vm.$children
- vm.$refs
-
vm.$els非推奨 : $refs に統合されました
#インスタンスメソッド
##data
- vm.$watch
-
vm.$get非推奨 : 値を直接取得してください -
vm.$set非推奨 : Vue.set を使用してください -
vm.$delete非推奨 : Vue.delete を使用してください -
vm.$eval非推奨 : 実用性がありません -
vm.$interpolate非推奨 : 実用性がありません -
vm.$log非推奨 : デベロッパーツールを使用してください
##events
- vm.$on
- vm.$once
- vm.$off
- vm.$emit
-
vm.$dispatch非推奨 : グローバルなイベントバスか Vuex を使用してください(後述) -
vm.$broadcast非推奨 : 同上
##DOM
- vm.$nextTick
-
vm.$appendTo非推奨 : vm.$elからDOM API を直接使用してください -
vm.$before非推奨 -
vm.$after非推奨 -
vm.$remove非推奨
##ライフサイクル
- vm.$mount
- vm.$destroy
#ディレクティブ
- v-text
-
v-html
{{{}}}
による省略記法は非推奨となりました - v-if
- v-show
- v-else
-
v-for
- key ( track-by から変更)
- オブジェクトによる v-for
- 範囲による v-for
-
引数の順序を変更:
(value, index) in arr
,(value, key, index) in obj
-
$index と $key非推奨
-
v-on
- 修飾子の利用
- 子コンポーネントでの使用
-
カスタムキーコード(
Vue.directive('on').keyCodes
ではなくVue.config.keyCodes
で設定します)
-
v-bind
- prop での使用
- xlink
- オブジェクトのバインド
-
v-bind:style
- ベンダープレフィックスの検出 (prefix sniffing)
- v-bind:class
-
v-model
- lazy (修飾子)
- number (修飾子)
- コンポーネント構造におけるイベント(compositon events)を無視
-
debounce非推奨 : v-on:input とサードパーティ製のデバウンス関数を使用してください
- v-cloak
- v-pre
- v-once 新規
-
v-ref特別な属性値ref
として使用してください -
v-el非推奨 ( ref に統合されました)
#特別な要素
-
<component>
- :is
- 非同期コンポーネント
- インラインテンプレート
-
<transition>
-
<transition-group>
-
<keep-alive>
-
<slot>
-
partial非推奨
#特別な属性値
- key
- ref
- slot
#サーバーサイドレンダリング
- renderToString
- renderToStream
- クライアント側での配列変換 ( client-side hydration )
その他の破壊的な変更点
##v-for
反復構文の変更
-
$index
と$key
の非推奨化
名前付きのインデックスとキーをより明確にするのが良いため、この両方が非推奨となりました。この構文は入れ子になったループ内では少々把握が難しいものであり、制約があります。おまけとして、初心者が学習する構文が2つ少なくて済みます。 -
新たな配列構文
value in arr
-
(value, index) in arr
(JavaScriptのforEach
とmap
を用いて引数の順番をより一貫したものに切り替えます)
-
新たなオブジェクト構文
value in obj
-
(value, key) in obj
( lodash のような多くの一般的なオブジェクトイテレータにより、引数の順番をある程度一貫性を持たせたものへ切り替えます) -
(value, key, index) in obj
(表のストライプ表示のような外観上の目的として、オブジェクトの反復にインデックスが使用できるようになりました)
ディレクティブインターフェイスの変更
概して、2.0ではディレクティブの責任範囲が大きく削減されています。ディレクティブは低レベルで直接的なDOM操作に対して使用されるようになりました。多くの場合、コードを再利用するための抽象化にはコンポーネントを使用する方が適切です。
ディレクティブはインスタンスを持たなくなりました。これは即ち、ディレクティブのフック内でのthis
がこれまでのように機能しなくなり、bind
、update
、unbind
があらゆるものを引数として受け取るようになったことを意味します。( binding
オブジェクトはイミュータブルであることに注意してください。どうしても必要なのであれば el
によってディレクティブの状態を維持することができます。)
<div v-example:arg.modifier="a.b"></div>
// ディレクティブの例
export default {
bind (el, binding, vnode) {
// binding オブジェクトはvalue, oldValue, arg および modifiers を吐き出します。
binding.expression // "a.b"
binding.arg // "arg"
binding.modifiers // { modifier: true }
// コンテキストとなる Vue インスタンスへは vnode.context からアクセスすることができます。
},
// update は少し変更があります。以下をご覧ください。
update (el, binding, vnode, oldVnode) { ... },
// componentUpdated は全体のコンポーネントが現在の更新サイクルを完了した"後"で呼び出される新たなフックです。
// 即ち、このフックを呼び出された時点で全てのDOMは最新の状態であることを意味します。
// また、このフックはディレクティブの値が変更されたか否かに関わらず必ず呼び出されます。
componentUpdated (el, binding, vnode, oldVNode) { ... },
unbind (el, binding, vnode) { ... }
}
値を考慮するだけの場合は分割代入が使用できます。
export default {
bind (el, { value }) {
// ...
}
}
さらに、update
フックに少し変更が加わりました。
-
bind
の後に自動で呼び出されなくなりました。 - バインドされている値が変更されたかに関わらずコンポーネントが再レンダリングされた時必ず呼び出されるようになりました。不必要な更新をスキップするために
binding.value === binding.oldValue
の比較を利用することが出来ますが、常に更新を適用したい場合もあります。例えば置換( replace )ではなく変更( mutation )が行われた Object がディレクティブにバインドされている場合です。
elementDirective
とディレクティブのパラメータは非推奨となりました。
フィルターの用法と構文の変更
Vue 2.0ではフィルターシステムがいくつか変更されています。
-
フィルターはテキスト展開(
{{}}
タグ)の内部でのみ使用可能となりました。以前、v-model
やv-on
などのディレクティブへフィルターが使用されていると、便利ではなくむしろ複雑になってしまうことに気付きました。また、v-for
におけるリストのフィルタリングでは算出プロパティとしてJavaScriptへ処理を移行するのがより適切です。 -
Vue 2.0 は内蔵フィルタを一切持ちません。特定領域の問題解決を目的とした、独立ライブラリーの使用を推奨します。例えば書式を日付型に変換する moment.js や通貨型に変換する accounting.js などです。自作のフィルターパックを作成してコミュニティで共有することも歓迎します!
-
フィルター構文は、スペース区切りの引数によるものから、JavaScriptの関数実行に近いものに変更されました。
{{ date | formatDate('YY-MM-DD') }}
##トランジションシステム
トランジションのCSSクラスを変更
常に適用されていたv-transition
クラスは追加されなくなり、また Vue では Angular や ReactのCSSTransitionGroup と同じクラス名を使用することになりました。
-
v-enter
:要素が挿入される前に適用され、1チック後に除去されます。(enter の開始時) -
v-enter-active
:要素が挿入される前に適用され、トランジションまたはアニメーションが終了した時に削除されます。(enter の実行中および終了時) -
v-leave
:leave トランジションが発火したのと同時に適用され、1チック後に除去されます。(leave の開始時) -
v-leave-active
:leaveトランジションが発火したのと同時に適用され、トランジションまたはアニメーションが終了した時に除去されます。(leave の実行中および終了時)v-enter-active
とv-leave-active
は enter/leave でそれぞれ異なるイージングカーブの設定を可能にします。ほとんどの場合更新は単に今あるv-leave
をv-leave-active
との入れ替えを意味します。( CSS アニメーションではv-enter-active
とv-leave-active
を使用してください)
v-enter-active
とv-leave-active
があれば enter / leave トランジションに異なるイージングカーブを明示できるようになります。更新するには、大抵は現在使用しているv-leave
をv-leave-active
に書き換えるだけです。
トランジション API の変更
-
<transition>
コンポーネント
全ての単一要素へ適用するトランジション効果は、対象となる要素およびコンポーネントを組み込みのコンポーネントである<transition>
でラップすることによって適用します。これは抽象コンポーネントであり、追加のDOM要素をレンダリングすることもなければ検出されたコンポーネント階層の中に現れることもないことを意味します。単にラップした内側にある要素のトランジションにおける振る舞いを適用するだけです。
簡単な用例:<transition> <div v-if="ok">toggled content</div> </transition>
コンポーネントは以前のトランジションオプション定義に直接対応する、いくつかの props と events を定義します。
Props
- name: String
CSS クラス名を自動出力する際に使用します。例えば`name: 'fade'`とすると`.fade-enter`、`fade-enter-active`などに自動で拡張されます。デフォルトは`"v"`です。
- appear: Boolean
初期レンダーにトランジションを適用するかを設定します。デフォルトは`false`です。
- css: Boolean
CSS トランジションクラスを適用するかを設定します。デフォルトは`true`です。`false`に設定した場合、コンポーネントイベント経由で登録された JavaScript フックのみが発火されます。
- type: String
トランジションの終了タイミングを決定するために、トランジションイベントのタイプを特定します。使用可能な値は`"transition"`と`"animation"`です。デフォルトでは継続時間がより長い方のタイプを自動で検出します。
- mode: String
leaving/entering トランジションのシーケンスタイミングを操作します。使用可能な値は`"out-in"`と`"in-out"`です。デフォルトは同時に起こります。
- enterClass, leaveClass, enterActiveClass, leaveActiveClass, appearClass, appearActiveClass: String
個別にトランジション CSS クラス名を指定できます。
動的コンポーネントにトランジションを適用した例です。
```html
<transition name="fade" mode="out-in" appear>
<component :is="view"></component>
</transition>
```
Events
1.x API で使用可能であった JavaScript フックと対応しています。
- before-enter
- enter
- after-enter
- before-leave
- leave
- after-leave
- before-appear
- appear
- after-apper
例:
```html
<transition @after-enter="transitionComplete">
<div v-show="ok">toggled content</div>
<transition>
```
entering トランジションが完了した時、トランジションした DOM 要素を引数としてコンポーネントのtransitionComplete
メソッドが呼び出されます。
#### 注意
- leave-cancelled
は挿入や削除に使用できなくなりました。一度 leave トランジションが開始するとキャンセルできません。しかしながら、v-show
でのトランジションにおいては引き続き有効です。
- 1.0 のように、enter
とleave
フックにおいて、第二引数のcb
存在は、ユーザーがトランジションの終了タイミングを明示的に操作可能なことを示しています。
-
<transition-group>
コンポーネント
全ての複数要素に対するトランジション効果は、要素を組み込みコンポーネントの<transition-group>
でラップすることによって適用します。<transition>
が提供するものと同じ props と events を提供しますが、違いは以下の通りです。-
<transition>
とは異なり、<transition-group>
は実体DOMをレンダリングします。デフォルトでは 単一の<span>
ですが、<tag>
プロパティでどの要素をレンダリングするか設定できます。また、<ul is="transition-group">
のようにis
属性値も使用可能です。 -
<transition-group>
はmode
プロパティをサポートしません。 -
<transition-group>
の内部にある全ての子は__ユニークな key__ を持たなければなりません。
例:
<transition-group tag="ul" name="slide"> <li v-for="item in items" :key="item.id"> {{ item.text }} </li> </transition>
-
移動トランジション
<transition-group>
は CSS の transform によって__移動トランジション__をサポートします。更新後に子のスクリーン上での位置が変更されている場合、移動 CSS クラス ( name
プロパティから自動生成されたものか、moveClass
プロパティで指定したもの) が適用されます。移動 CSS クラスが適用された時に CSS のtransform
プロパティが "トランジション可能"であるならば、要素は FLIP technique を用いて目標の位置へと滑らかにアニメーション動作を行います。
実際の動作例を確認してみてください。
- __再利用可能なトランジションの作成__ トランジションはコンポーネントを通じて適用されるようになり、アセットタイプと見なされなくなったため、グローバルの`Vue.transiton()`メソッドと`transition`オプションの両方が非推奨となりました。コンポーネントの props と events をインラインで書き込むことでトランジションの設定が可能です。しかし再利用性のあるトランジション効果を作るには、特にカスタム JavaScript フックを用いたものである場合に、一体どのようにすればよいのでしょう。その答えは、自身でトランジションコンポーネントを作成することです( とりわけ関数コンポーネントが適しています )。
Vue.component('fade', {
functionl: true,
render (createElement, { children }) {
const data = {
props: {
name: 'fade'
},
on: {
beforeEnter () { /* ... */ }, // 注意: フックは JavaScript ではキャメルケースを用いて下さい( 1.x 系と同様 )。
afterEnter () { /* ... */ }
}
}
return createElement('transition', data, children)
}
})
そうするとこのように再利用ができるようになります。
<fade>
<div v-if="ok"> toggled content</div>
</fade>
v-model の変更
-
lazy
とnumber
パラメータは修飾子になりました。<input v-model.lazy="text">
-
.trim
の追加 - その名の通り、入力値を切り取ります。 -
debaounce
パラメータは非推奨となりました。(後述の更新に関するヒントを参照してください) -
v-model
はvalue
属性による初期値を無視するようになりました。常にVue インスタンスが持つ data を信頼できる情報源として取り扱います。これは以下の例で値が2ではなくて1を表示することを意味します。data: { val: 1 }
<input v-model="val" value="2">
既存のコンテントを持つ
<textarea>
も同様に振る舞います。以下ではなく、<textarea v-model="val">hello world</textarea>
以下のようにしてください。
data () { return { val: 'hello world' } }
<textarea v-model="val"></textarea>
テンプレートではなくJS側が信頼できる情報源となるべきである、というのが主な考え方です。
-
v-model
はv-for
によって反復されたプリミティブな値に対して使用することができなくなりました。<input v-for="str in strings" v-model="str">
これは以下の JavaScript 処理に相当するため機能しません。
strings.map(function (str) { return createElement('input', ...) })
お分かりの通り、
str
は関数スコープの内部においては単なるローカル変数であるため反復関数内で別の値に代入しても何も起きません。その代わり、v-model
がオブジェクト上のフィールドを更新できるようオブジェクトの配列を使用すべきです。<input v-for="obj in objects" v-model="obj.str">
##Prop の振る舞い
-
.once
と.sync
は非推奨です。Prop は単一方向バインディングとなりました。親のスコープにおける副作用を引き起こすため、コンポーネントは暗黙的なバインディグに頼らずに明示的なイベント発火を必要とします。 -
局所的な Prop の変更はアンチパターンと見なされるようになりました。例えば、
a
というPropを宣言した後にコンポーネント内でthis.a = someOtherValue
と代入するような手順です。新たなレンダリング機構により、親コンポーネントが再レンダリングされるとき、必ず子コンポーネントでのローカルな変更は上書きされます。概して、2.0においてはPropをイミュータブルとして扱ってください。Propの変更に関する用例のほとんどは、data プロパティか算出プロパティのいずれかで置き換えることができます。
keep-alive
keep-alive
は特別な属性値ではなくなり、<transition>
に似たラッパーコンポーネントとなりました。
<keep-alive>
<component :is="view"></component>
</keep-alive>
<transition>
と併用する場合には、確実に内側に入れて下さい。
<transition>
<keep-alive>
<component :is="view"></component>
</keep-alive>
</transition>
スロット
- 同名、同テンプレートの重複した
<slot>
はサポートされなくなりました。スロットがレンダリングされたとき、それは"使い切り"であり、同一レンダリングツリー内のどの位置にもレンダリングされません。 - 名前付きの
<slot>
で挿入されたコンテンツはslot
属性値を保持しません。それらの体裁を整えるにはラッパー要素を使用するか、より応用的な事例としては、レンダー関数を用いて挿入されたコンテンツをプログラム的に修正してください。
Refs
-
v-ref
はディレクティブではなく、key
やtransition
のような特別な属性値となりました。<!-- before --> <comp v-ref:foo></comp> <!-- after --> <comp ref="foo></comp>
また、動的な ref バインディングがサポートされました。
<comp :ref="dynamivRef"></comp>
-
vm.$els
とvm.$refs
は統合されました。通常の要素に対して使用している場合は ref は DOM 要素を、コンポーネントに対して使用している場合はコンポーネントのインスタンスとなります。 -
vm.$refs
はレンダープロセスの間に登録 / 更新されるためリアクティブではなくなりました。これらをりアクティブにすると、毎回の変更で重複したレンダリングを行うことになります。一方で、
$refs
は JavaScript からのプログラム的なアクセスを第一として設計されています。必然的にインスタンスそれ自体には属さない状態を参照しているため、テンプレート内で$refs
に依存するのは推奨されません。
##その他
-
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">
-
属性値バインディングの挙動が変更されました。
null
、undefined
、およびfalse
のみがバインディングされた属性においてfalseとして評価されます。これは、0
や空文字列がそのままレンダリングされることを意味します。列挙属性の場合も同じです(For enumerated attributes)。:draggable="''"
はdraggable="true"
としてレンダリングされることになります。
また、列挙属性においては上記のfalse 判定値に加えて、文字列値 "false" も attr="false" としてレンダリングされます。 -
カスタムコンポーネントに対して使用している場合、
v-on
はそのコンポーネントの $emit によって発火されたカスタムイベントのみを受け取ります(DOM のイベント通知を受け取りません)。 -
v-else
はv-show
と併用できません。単に否定表現を使用してください。 -
ワンタイムバインディング(
{{* foo}}
)は非推奨です。代わりにv-once
を使用してください。 -
Array.prototype.$set/$remove は非推奨となりました(Vue.set か Array.prototype.splice を使用してください)。
-
:style
は埋め込みの!important
をサポートしません。 -
ルートインスタンスはテンプレートのPropを使用できません(
propsData
を使用してください)。 -
el
オプションはVue.extend
で使用できません。インスタンス作成時のオプションでのみ使用可能です。 -
Vue.set
とVue.delete
はVueインスタンス上で動作しません。最上位のリアクティブなプロパティはdata
オプションにおいて適切に宣言されることが必須となりました。 -
また、コンポーネントインスタンスがもつルートの
$data
を置換することは禁止されました。これはリアクティブシステムで起こるいくつかのエッジケースを防止し、(特に型チェックシステムと共に使用する際に)コンポーネントの状態をより予測可能なものにします。 -
vm.$watch
から作成されたユーザー定義の監視は、関連するコンポーネントの再レンダリングの前に発火するようになりました。これによりユーザーはコンポーネントが再レンダリングする前に他の状態を更新する機会が得られ、不必要な更新を回避することができます。例えば、コンポーネントの prop を監視し、prop に変更があった場合にコンポーネント自身の data を更新することができます。コンポーネント更新後にDOMに関与する操作を行いたい場合は、単にupdated ライフサイクルフックを使用して下さい。
更新に関するヒント
$dispatch
と $broadcast
の非推奨化への対処
$distpatch
と $broadcast
を非推奨とした理由は、コンポーネントのツリー構造に依存したイベントフローは、ツリー構造が巨大になった場合に把握が困難になってしまうことです(簡単に言えば、大規模アプリでの影響の大きさは見通せません(doesn't scale well)し、皆さんを後々痛い目に遭わせてしまうような真似はしたくないのです)。また、$dispatch
と$broadcast
は兄弟コンポーネントとの通信を解決することができません。その代わりにNode.js における EventEmitter パターンに似た手法を取り入れられます。これは互いがコンポーネントツリー構造内のどの位置にあっても、コンポーネント間の通信を可能にする中央集権的なイベントの中枢となります。 Vue インスタンスはイベントエミッターのインターフェイスとして用を満たすので、実際に空の Vue インスタンスを使用して実装することが出来ます。
var bus = new Vue()
// コンポーネントAのメソッド
bus.$emit('id-selected', 1)
// コンポーネントBでの created フック
bus.$on('id-selected', function (id) {
// ...
})
このパターンは単純なシナリオによって$dispatch
と$broadcast
の代役を果たします。しかし、より複雑なケースでは Vuex による専用のステート管理層を導入することをお勧めします。
##配列フィルタの非推奨化への対処
v-for
におけるリストのフィルタリング(フィルターの最もありふれた用法の1つ)では、元の配列を成形したコピーを返す算出プロパティの使用を推奨します(詳細はupdated data grid exampleを参照)。これにはフィルタが持つ恣意的な構文/APIの制約を受けない利点があります。算出プロパティであれば通常のJavaScriptですし、当然ながらフィルタリングの結果にアクセスすることもできるのです。
[こちらの議論スレッド](https://github.com/vuejs/vue/issues/2756 ”[Suggestion] Vue 2.0 - Bring back filters please”)もご覧ください。
##v-model
におけるdebounce
の非推奨化への対処
以前までデバウンスは Ajax リクエストやその他高コストな処理の実行回数を制限をしていました。 Vue のv-model
に用意されたdebouce
属性パラメータはこれを容易に可能にしていましたが、高コストな処理そのものよりもむしろステート更新に対してデバウンスをしており、これが制限を生んでいます。
これらの制限は、検索状態表示 を設計する際に明白になります。例をご覧ください。これまで、debounce
属性を使用していると input のリアルタイムな状態へのアクセスを失っているため、検索が始まる前では入力の逐一を検知する方法がありませんでした。 Vue からデバウンス関数を分離することで、制限したい処理だけをデバウンスすることができるようになります。
デバウンスが本当に適切なラッパー関数とならない別の場合があります。検索候補の API が行き当たるごくありふれた例では、ユーザーがキー入力を止めた後まで候補の表示を待つのは理想的な実装ではありません。その代わりに使用したいものはスロットリング関数でしょう。既に lodash のようなユーティリティライブラリをdebounce
に使用しているのですから、throttle
を使用したものへ修正するのに数分しかかかりません!