Vue.js 从 Vue 1.x 迁移
從 Vue 1.x 遷移
FAQ
哇,非常長(zhǎng)的一頁(yè)!是否意味著 Vue 2.0 已經(jīng)完全不同了呢,是否需要從頭學(xué)起呢,Vue 1.0 的項(xiàng)目是不是沒(méi)法遷移了?
非常開心地告訴你,并不是!幾乎 90% 的 API 和核心概念都沒(méi)有變。因?yàn)楸竟?jié)包含了很多詳盡的闡述以及許多遷移的例子,所以顯得有點(diǎn)長(zhǎng)。不用擔(dān)心,你不必從頭到尾把本節(jié)讀一遍!
我該從哪里開始項(xiàng)目遷移呢?
首先,在當(dāng)前項(xiàng)目下運(yùn)行遷移工具。我們非常謹(jǐn)慎地把高級(jí) Vue 升級(jí)過(guò)程簡(jiǎn)化為使用一個(gè)簡(jiǎn)單的命令行工具。當(dāng)工具識(shí)別出舊有的特性后,就會(huì)告知你并給出建議,同時(shí)附上關(guān)于詳細(xì)信息的鏈接。
然后,瀏覽本頁(yè)面的側(cè)邊欄列出的內(nèi)容。如果發(fā)現(xiàn)有的標(biāo)題對(duì)你的項(xiàng)目有影響,但是遷移工具沒(méi)有給出提示,請(qǐng)檢查自己的項(xiàng)目。
如果你的項(xiàng)目有測(cè)試代碼,運(yùn)行并查看仍然失敗的地方。如果沒(méi)有測(cè)試代碼,在瀏覽器中打開你的程序,通過(guò)導(dǎo)航環(huán)顧并留意那些報(bào)錯(cuò)或警告信息。
現(xiàn)在,你的應(yīng)用程序應(yīng)該已徹底完成遷移。如果你渴望了解更多,可以閱讀本頁(yè)面剩余部分 - 或者從介紹部分,從頭開始深入新的文檔和改進(jìn)過(guò)的指南。由于你已經(jīng)熟悉一些核心概念,所以許多部分已經(jīng)被刪除掉。
將 Vue 1.x 版本的應(yīng)用程序遷移到 2.0 要花多長(zhǎng)時(shí)間?
這取決于幾個(gè)因素:
-
取決于你應(yīng)用程序的規(guī)模 (中小型的基本上一天內(nèi)就可以搞定)。
-
取決于你分心和開始 2.0 最酷的新功能的次數(shù)。? ?無(wú)法判斷時(shí)間,我們構(gòu)建 2.0 應(yīng)用的時(shí)候也經(jīng)常發(fā)生這種事!
-
取決于你使用了哪些舊有的特性。大部分可以通過(guò)查找和替換 (find-and-replace) 來(lái)實(shí)現(xiàn)升級(jí),但有一些可能還是要花點(diǎn)時(shí)間。如果你沒(méi)有遵循最佳實(shí)踐,Vue 2.0 會(huì)盡力強(qiáng)迫你去遵循。這有利于項(xiàng)目的長(zhǎng)期運(yùn)行,但也可能意味著重大重構(gòu) (盡管有些需要重構(gòu)的部分可能已經(jīng)過(guò)時(shí))。
如果我升級(jí)到到 Vue 2 ,我還必須同時(shí)升級(jí) Vuex 和 Vue Router?
只有 Vue Router 2 與 Vue 2 保持兼容,所以 Vue Router 是需要升級(jí)的,你必須遵循?Vue Router 遷移方式來(lái)處理。幸運(yùn)的是,大多數(shù)應(yīng)用沒(méi)有很多 router 相關(guān)代碼,所以遷移可能不會(huì)超過(guò)一個(gè)小時(shí)。
對(duì)于 Vuex ,版本 0.8+ 與 Vue 2 保持兼容,所以部分不必強(qiáng)制升級(jí)。可以促使你立即升級(jí)的唯一理由,是你想要使用那些 Vuex 2 中新的高級(jí)特性,比如模塊 (modules) 和減少的樣板文件 (reduced boilerplate)。
模板
片段實(shí)例?移除
每個(gè)組件必須只有一個(gè)根元素。不再允許片段實(shí)例,如果你有這樣的模板:
| <p>foo</p> <p>bar</p> |
最好把整個(gè)內(nèi)容都簡(jiǎn)單包裹到一個(gè)新的元素里,如下所示:
| <div><p>foo</p><p>bar</p> </div> |
升級(jí)方式
升級(jí)后運(yùn)行端到端測(cè)試套件 (end-to-end test suite) 或運(yùn)行應(yīng)用程序,并查看控制臺(tái)警告 (console warnings)?來(lái)找出那些模板中有多個(gè)根元素的地方。
生命周期鉤子函數(shù)
beforeCompile?移除
使用?created?鉤子函數(shù)替代。
升級(jí)方式
在代碼庫(kù)中運(yùn)行遷移工具來(lái)找出所有使用此鉤子函數(shù)的示例。
compiled?替換
使用?mounted?鉤子函數(shù)替代。
升級(jí)方式
在代碼庫(kù)中運(yùn)行遷移工具來(lái)找出所有使用此鉤子函數(shù)的示例。
attached?移除
使用其他鉤子函數(shù)內(nèi)置的 DOM 檢測(cè) (DOM check) 方法。例如,替換如下:
| attached: function () {doSomething() } |
可以這樣使用:
| mounted: function () {this.$nextTick(function () {doSomething()}) } |
升級(jí)方式
在代碼庫(kù)中運(yùn)行遷移工具來(lái)找出所有使用此鉤子函數(shù)的示例。
detached?移除
使用其他鉤子函數(shù)內(nèi)的 DOM 檢測(cè) (DOM check) 方法。例如,替換如下:
| detached: function () {doSomething() } |
可以這樣使用:
| destroyed: function () {this.$nextTick(function () {doSomething()}) } |
升級(jí)方式
在代碼庫(kù)中運(yùn)行遷移工具來(lái)找出所有使用此鉤子函數(shù)的示例。
init?重新命名
使用新的?beforeCreate?鉤子函數(shù)替代,本質(zhì)上 beforeCreate 和 init 完全相同。init 被重新命名是為了和其他的生命周期方法的命名方式保持一致。
升級(jí)方式
在代碼庫(kù)中運(yùn)行遷移工具來(lái)找出所有使用此鉤子函數(shù)的示例。
ready?替換
使用新的?mounted?鉤子函數(shù)替代。應(yīng)該注意的是,使用?mounted?并不能保證鉤子函數(shù)中的 this.$el 在 document 中。為此還應(yīng)該引入?Vue.nextTick/vm.$nextTick。例如:
| mounted: function () {this.$nextTick(function () {// 代碼保證 this.$el 在 document 中}) } |
升級(jí)方式
在代碼庫(kù)中運(yùn)行遷移工具來(lái)找出所有使用此鉤子函數(shù)的示例。
v-for
v-for?遍歷數(shù)組時(shí)的參數(shù)順序?變更
當(dāng)包含?index?時(shí),之前遍歷數(shù)組時(shí)的參數(shù)順序是?(index, value)。現(xiàn)在是?(value, index)?,來(lái)和 JavaScript 的原生數(shù)組方法 (例如?forEach?和?map) 保持一致。
升級(jí)方式
在代碼庫(kù)中運(yùn)行遷移工具來(lái)找出那些使用舊有參數(shù)順序的示例。注意,如果你將你的 index 參數(shù)命名為一些不通用的名字 (例如?position?或?num),遷移工具將不會(huì)把它們標(biāo)記出來(lái)。
v-for?遍歷對(duì)象時(shí)的參數(shù)順序?變更
當(dāng)包含?key?時(shí),之前遍歷對(duì)象的參數(shù)順序是?(key, value)。現(xiàn)在是?(value, key),來(lái)和常見的對(duì)象迭代器 (例如 lodash) 保持一致。
升級(jí)方式
在代碼庫(kù)中運(yùn)行遷移工具來(lái)找出那些使用舊有參數(shù)順序的示例。注意,如果你將你的 key 參數(shù)命名為一些不通用的名字 (例如?name?或?property),遷移工具將不會(huì)把它們標(biāo)記出來(lái)。
$index?and?$key?移除
已經(jīng)移除了?$index?和?$key?這兩個(gè)隱式聲明變量,以便在?v-for?中顯式定義。這可以使沒(méi)有太多 Vue 開發(fā)經(jīng)驗(yàn)的開發(fā)者更好地閱讀代碼,并且在處理嵌套循環(huán)時(shí)也能產(chǎn)生更清晰的行為。
升級(jí)方式
在代碼庫(kù)中運(yùn)行遷移工具來(lái)找出使用這些移除變量的示例。如果你沒(méi)有找到,也可以在控制臺(tái)錯(cuò)誤中查找 (例如?Uncaught ReferenceError: $index is not defined)。
?
track-by?替換
track-by?已經(jīng)替換為?key,它的工作方式與其他屬性一樣,沒(méi)有?v-bind?或者?:前綴,它會(huì)被作為一個(gè)字符串處理。多數(shù)情況下,你需要使用具有完整表達(dá)式的動(dòng)態(tài)綁定 (dynamic binding) 來(lái)替換靜態(tài)的 key。例如,替換:
| <div v-for="item in items" track-by="id"> |
你現(xiàn)在應(yīng)該寫為:
| <div v-for="item in items" v-bind:key="item.id"> |
升級(jí)方式
在代碼庫(kù)中運(yùn)行遷移工具來(lái)找出那些使用track-by的示例。
v-for?范圍值?變更
之前,v-for="number in 10"?的?number?從 0 開始到 9 結(jié)束,現(xiàn)在從 1 開始,到 10 結(jié)束。
升級(jí)方式
在代碼庫(kù)中使用正則?/\w+ in \d+/搜索。當(dāng)出現(xiàn)在?v-for?中,請(qǐng)檢查是否受到影響。
Props
coerce?Prop 的參數(shù)?移除
如果需要檢查 prop 的值,創(chuàng)建一個(gè)內(nèi)部的 computed 值,而不再在 props 內(nèi)部去定義,例如:
| props: {username: {type: String,coerce: function (value) {return value.toLowerCase().replace(/\s+/, '-')}} } |
現(xiàn)在應(yīng)該寫為:
| props: {username: String, }, computed: {normalizedUsername: function () {return this.username.toLowerCase().replace(/\s+/, '-')} } |
這樣有一些好處:
- 你可以對(duì)保持原始 prop 值的操作權(quán)限。
- 通過(guò)給予驗(yàn)證后的值一個(gè)不同的命名,強(qiáng)制開發(fā)者使用顯式申明。
升級(jí)方式
運(yùn)行遷移工具找出包含?coerce?選項(xiàng)的實(shí)例。
twoWay?Prop 的參數(shù)?移除
Props 現(xiàn)在只能單向傳遞。為了對(duì)父組件產(chǎn)生反向影響,子組件需要顯式地傳遞一個(gè)事件而不是依賴于隱式地雙向綁定。詳見:
- 自定義組件事件
- 自定義輸入組件?(使用組件事件)
- 全局狀態(tài)管理
升級(jí)方式
運(yùn)行?遷移工具,找出含有?twoWay?參數(shù)的實(shí)例。
v-bind?的?.once和.sync?修飾符?移除
Props 現(xiàn)在只能單向傳遞。為了對(duì)父組件產(chǎn)生反向影響,子組件需要顯式地傳遞一個(gè)事件而不是依賴于隱式地雙向綁定。詳見:
- 自定義組件事件
- 自定義輸入組件?(使用組件事件)
- 全局狀態(tài)管理
升級(jí)方式
運(yùn)行遷移工具找到使用?.once?和?.sync?修飾符的實(shí)例。
修改 Props?棄用
組件內(nèi)修改 prop 是反模式 (不推薦的) 的。比如,先聲明一個(gè) prop ,然后在組件中通過(guò)?this.myProp = 'someOtherValue'?改變 prop 的值。根據(jù)渲染機(jī)制,當(dāng)父組件重新渲染時(shí),子組件的內(nèi)部 prop 值也將被覆蓋。
大多數(shù)情況下,改變 prop 值可以用以下選項(xiàng)替代:
- 通過(guò) data 屬性,用 prop 去設(shè)置一個(gè) data 屬性的默認(rèn)值。
- 通過(guò) computed 屬性。
升級(jí)方式
運(yùn)行端對(duì)端測(cè)試,查看關(guān)于 prop 修改的控制臺(tái)警告信息。
根實(shí)例的 Props?替換
對(duì)于一個(gè)根實(shí)例來(lái)說(shuō) (比如:用?new Vue({ ... })?創(chuàng)建的實(shí)例),只能用?propsData?而不是?props?。
升級(jí)方式
運(yùn)行端對(duì)端測(cè)試,將會(huì)彈出?failed tests?來(lái)通知你使用?props?的根實(shí)例已經(jīng)失效。
計(jì)算屬性
cache: false?棄用
在 Vue 未來(lái)的大版本中,計(jì)算屬性的緩存驗(yàn)證將會(huì)被移除。把不緩存的計(jì)算屬性轉(zhuǎn)換為方法可以得到和之前相同的結(jié)果。
示例:
| template: '<p>message: {{ timeMessage }}</p>', computed: {timeMessage: {cache: false,get: function () {return Date.now() + this.message}} } |
或者使用組件方法:
| template: '<p>message: {{ getTimeMessage() }}</p>', methods: {getTimeMessage: function () {return Date.now() + this.message} } |
升級(jí)方式
運(yùn)行遷移工具找到?cache: false?的選項(xiàng)。
Built-In 指令
v-bind?真/假值?變更
在2.0中使用?v-bind?時(shí),只有?null,?undefined,和?false?被看作是假。這意味著,0?和空字符串將被作為真值渲染。比如?v-bind:draggable="''"?將被渲染為?draggable="true"。
對(duì)于枚舉屬性,除了以上假值之外,字符串?"false"?也會(huì)被渲染為?attr="false"。
注意,對(duì)于其它鉤子函數(shù) (如?v-if?和?v-show),他們依然遵循 js 對(duì)真假值判斷的一般規(guī)則。
升級(jí)方式
運(yùn)行端到端測(cè)試,如果你 app 的任何部分有可能被這個(gè)升級(jí)影響到,將會(huì)彈出failed tests
用?v-on?監(jiān)聽原生事件?變更
現(xiàn)在在組件上使用?v-on?只會(huì)監(jiān)聽自定義事件 (組件用?$emit?觸發(fā)的事件)。如果要監(jiān)聽根元素的原生事件,可以使用?.native?修飾符,比如:
| <my-component v-on:click.native="doSomething"></my-component> |
升級(jí)方式
運(yùn)行端對(duì)端測(cè)試,如果你 app 的任何部分有可能被這個(gè)升級(jí)影響到,將會(huì)彈出failed tests
帶有?debounce?的?v-model移除
Debouncing 曾經(jīng)被用來(lái)控制 Ajax 請(qǐng)求及其它高耗任務(wù)的頻率。Vue 中v-model的?debounce?屬性參數(shù)使得在一些簡(jiǎn)單情況下非常容易實(shí)現(xiàn)這種控制。但實(shí)際上,這是控制了狀態(tài)更新的頻率,而不是控制高耗時(shí)任務(wù)本身。這是個(gè)微小的差別,但是會(huì)隨著應(yīng)用增長(zhǎng)而顯現(xiàn)出局限性。
例如在設(shè)計(jì)一個(gè)搜索提示時(shí)的局限性:
?? Done
使用?debounce?參數(shù),便無(wú)法觀察 “Typing” 的狀態(tài)。因?yàn)闊o(wú)法對(duì)輸入狀態(tài)進(jìn)行實(shí)時(shí)檢測(cè)。然而,通過(guò)將?debounce?與 Vue 解耦,可以僅僅只延遲我們想要控制的操作,從而避開這些局限性:
| <!-- 通過(guò)使用 lodash 或者其它庫(kù)的 debounce 函數(shù), 我們相信 debounce 實(shí)現(xiàn)是一流的, 并且可以隨處使用它,不僅僅是在模板中。 --> <script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.js"></script> <div id="debounce-search-demo"><input v-model="searchQuery" placeholder="Type something"><strong>{{ searchIndicator }}</strong> </div> |
| new Vue({el: '#debounce-search-demo',data: {searchQuery: '',searchQueryIsDirty: false,isCalculating: false},computed: {searchIndicator: function () {if (this.isCalculating) {return '? Fetching new results'} else if (this.searchQueryIsDirty) {return '... Typing'} else {return '? Done'}}},watch: {searchQuery: function () {this.searchQueryIsDirty = truethis.expensiveOperation()}},methods: {// 這是 debounce 實(shí)現(xiàn)的地方。expensiveOperation: _.debounce(function () {this.isCalculating = truesetTimeout(function () {this.isCalculating = falsethis.searchQueryIsDirty = false}.bind(this), 1000)}, 500)} }) |
這種方式的另外一個(gè)優(yōu)點(diǎn)是:當(dāng)包裹函數(shù)執(zhí)行時(shí)間與延時(shí)時(shí)間相當(dāng)時(shí),將會(huì)等待較長(zhǎng)時(shí)間。比如,當(dāng)給出搜索建議時(shí),要等待用戶輸入停止一段時(shí)間后才給出建議,這個(gè)體驗(yàn)非常差。其實(shí),這時(shí)候更適合用?throttling?函數(shù)。因?yàn)楝F(xiàn)在你可以自由的使用類似 lodash 之類的庫(kù),所以很快就可以用 throttling 重構(gòu)項(xiàng)目。
Upgrade Path
運(yùn)行遷移工具找出使用?debounce?參數(shù)的 實(shí)例。
使用?lazy?或者?number?參數(shù)的?v-model?。替換
lazy?和?number?參數(shù)現(xiàn)在以修飾符的形式使用,這樣看起來(lái)更加清晰,而不是這樣:
| <input v-model="name" lazy> <input v-model="age" type="number" number> |
現(xiàn)在寫成這樣:
| <input v-model.lazy="name"> <input v-model.number="age" type="number"> |
升級(jí)方式
運(yùn)行?遷移工具找到這些棄用參數(shù)。
使用內(nèi)聯(lián)?value的v-model?移除
v-model?不再以內(nèi)聯(lián)?value?方式初始化的初值了,顯然他將以實(shí)例的 data 相應(yīng)的屬性作為真正的初值。
這意味著以下元素:
| <input v-model="text" value="foo"> |
在 data 選項(xiàng)中有下面寫法的:
| data: {text: 'bar' } |
將渲染 model 為 ‘bar’ 而不是 ‘foo’ 。同樣,對(duì)?<textarea>?已有的值來(lái)說(shuō):
| <textarea v-model="text">hello world </textarea> |
必須保證?text?初值為 “hello world”
升級(jí)方式
升級(jí)后運(yùn)行端對(duì)端測(cè)試,注意關(guān)于v-model內(nèi)聯(lián)參數(shù)的?console warnings
v-model?with?v-for?Iterated Primitive Values?移除
像這樣的寫法將失效:
| <input v-for="str in strings" v-model="str"> |
因?yàn)?<input>?將被編譯成類似下面的 js 代碼:
| strings.map(function (str) {return createElement('input', ...) }) |
這樣,v-model?的雙向綁定在這里就失效了。把?str?賦值給迭代器里的另一個(gè)值也沒(méi)有用,因?yàn)樗鼉H僅是函數(shù)內(nèi)部的一個(gè)變量。
替代方案是,你可以使用對(duì)象數(shù)組,這樣v-model?就可以同步更新對(duì)象里面的字段了,例如:
| <input v-for="obj in objects" v-model="obj.str"> |
升級(jí)方式
運(yùn)行測(cè)試,如果你的 app 有地方被這個(gè)更新影響到的話將會(huì)彈出failed tests提示。
帶有?!important?的v-bind:style?移除
這樣寫將失效:
| <p v-bind:style="{ color: myColor + ' !important' }">hello</p> |
如果確實(shí)需要覆蓋其它的?!important,最好用字符串形式去寫:
| <p v-bind:style="'color: ' + myColor + ' !important'">hello</p> |
升級(jí)方式
運(yùn)行?遷移幫助工具。找到含有?!important?的 style 綁定對(duì)象。
v-el?和v-ref?替換
簡(jiǎn)單起見,v-el?和?v-ref?合并為一個(gè)?ref?屬性了,可以在組件實(shí)例中通過(guò)?$refs?來(lái)調(diào)用。這意味著?v-el:my-element?將寫成這樣:ref="myElement",v-ref:my-component?變成了這樣:ref="myComponent"。綁定在一般元素上時(shí),ref?指 DOM 元素,綁定在組件上時(shí),ref?為一組件實(shí)例。
因?yàn)?v-ref?不再是一個(gè)指令了而是一個(gè)特殊的屬性,它也可以被動(dòng)態(tài)定義了。這樣在和v-for?結(jié)合的時(shí)候是很有用的:
| <p v-for="item in items" v-bind:ref="'item' + item.id"></p> |
以前?v-el/v-ref?和?v-for?一起使用將產(chǎn)生一個(gè) DOM 數(shù)組或者組件數(shù)組,因?yàn)闆](méi)法給每個(gè)元素一個(gè)特定名字。現(xiàn)在你還仍然可以這樣做,給每個(gè)元素一個(gè)同樣的ref:
| <p v-for="item in items" ref="items"></p> |
和 1.x 中不同,$refs?不是響應(yīng)的,因?yàn)樗鼈冊(cè)阡秩具^(guò)程中注冊(cè)/更新。只有監(jiān)聽變化并重復(fù)渲染才能使它們響應(yīng)。
另一方面,設(shè)計(jì)$refs主要是提供給 js 程序訪問(wèn)的,并不建議在模板中過(guò)度依賴使用它。因?yàn)檫@意味著在實(shí)例之外去訪問(wèn)實(shí)例狀態(tài),違背了 Vue 數(shù)據(jù)驅(qū)動(dòng)的思想。
升級(jí)方式
?
運(yùn)行遷移工具找出實(shí)例中的?v-el?和?v-ref?。
v-show后面使用v-else?移除
v-else?不能再跟在?v-show后面使用。請(qǐng)?jiān)趘-if的否定分支中使用v-show來(lái)替代。例如:
| <p v-if="foo">Foo</p> <p v-else v-show="bar">Not foo, but bar</p> |
現(xiàn)在應(yīng)該寫出這樣:
| <p v-if="foo">Foo</p> <p v-if="!foo && bar">Not foo, but bar</p> |
升級(jí)方式
運(yùn)行遷移工具找出實(shí)例中存在的?v-else?以及?v-show。
自定義指令?簡(jiǎn)化
在新版中,指令的使用范圍已經(jīng)大大減小了:現(xiàn)在指令僅僅被用于低級(jí)的 DOM 操作。大多數(shù)情況下,最好是使用組件作為代碼復(fù)用的抽象層。
顯要的改變有如下幾點(diǎn):
- 指令不再擁有實(shí)例。意思是,在指令的鉤子函數(shù)中不再擁有實(shí)例的?this?。替代的是,你可以在參數(shù)中接受你需要的任何數(shù)據(jù)。如果確實(shí)需要,可以通過(guò)?el?來(lái)訪問(wèn)實(shí)例。
- 類似?acceptStatement?,deep?,priority?等都已被棄用。為了替換雙向指令,見?示例。
- 現(xiàn)在有些鉤子的意義和以前不一樣了,并且多了兩個(gè)鉤子函數(shù)。
幸運(yùn)的是,新鉤子更加簡(jiǎn)單,更加容易掌握。詳見?自定義指令指南。
升級(jí)方式
運(yùn)行遷移工具找到定義指令的地方。在 helper 工具會(huì)把這些地方標(biāo)記出來(lái),因?yàn)楹苡锌赡苓@些地方需要重構(gòu)。
指令?.literal?修飾符?移除
.literal?修飾符已經(jīng)被移除,為了獲取一樣的功能,可以簡(jiǎn)單地提供字符串修飾符作為值。
示例,如下更改:
| <p v-my-directive.literal="foo bar baz"></p> |
只是:
| <p v-my-directive="'foo bar baz'"></p> |
升級(jí)方式
?
運(yùn)行遷移工具找到實(shí)例中使用 `.literal` 修飾符的地方。
過(guò)渡
transition?參數(shù)?替換
Vue 的過(guò)渡系統(tǒng)有了徹底的改變,現(xiàn)在通過(guò)使用?<transition>?和?<transition-group>?來(lái)包裹元素實(shí)現(xiàn)過(guò)渡效果,而不再使用?transition?屬性。詳見?Transitions guide。
升級(jí)方式
運(yùn)行遷移工具找到使用?transition?屬性的地方。
可復(fù)用的過(guò)渡?Vue.transition?替換
在新的過(guò)渡系統(tǒng)中,可以通過(guò)模板復(fù)用過(guò)渡效果。
升級(jí)方式
運(yùn)行遷移工具找到使用?transition?屬性的地方。
過(guò)渡的?stagger?參數(shù)?移除
如果希望在列表渲染中使用漸近過(guò)渡,可以通過(guò)設(shè)置元素的?data-index?(或類似屬性) 來(lái)控制時(shí)間。請(qǐng)參考這個(gè)例子。
升級(jí)方式
運(yùn)行遷移工具找到使用?transition?屬性的地方。升級(jí)期間,你可以“過(guò)渡”到新的過(guò)渡策略。
事件
events?選項(xiàng)?移除
events?選項(xiàng)被棄用。事件處理器現(xiàn)在在?created?鉤子中被注冊(cè)。參考詳細(xì)示例?$dispatch?and?$broadcast?遷移指南
Vue.directive('on').keyCodes?替換
新的簡(jiǎn)明配置?keyCodes?的方式是通過(guò)?Vue.config.keyCodes例如:
| // v-on:keyup.f1 不可用 Vue.config.keyCodes.f1 = 112 |
升級(jí)方式
運(yùn)行遷移工具找到過(guò)時(shí)的?keyCode?配置
$dispatch?和?$broadcast?替換
$dispatch?和?$broadcast?已經(jīng)被棄用。請(qǐng)使用更多簡(jiǎn)明清晰的組件間通信和更好的狀態(tài)管理方案,如:Vuex。
因?yàn)榛诮M件樹結(jié)構(gòu)的事件流方式實(shí)在是讓人難以理解,并且在組件結(jié)構(gòu)擴(kuò)展的過(guò)程中會(huì)變得越來(lái)越脆弱。這種事件方式確實(shí)不太好,我們也不希望在以后讓開發(fā)者們太痛苦。并且$dispatch?和?$broadcast?也沒(méi)有解決兄弟組件間的通信問(wèn)題。
對(duì)于$dispatch?和?$broadcast最簡(jiǎn)單的升級(jí)方式就是:通過(guò)使用事件中心,允許組件自由交流,無(wú)論組件處于組件樹的哪一層。由于 Vue 實(shí)例實(shí)現(xiàn)了一個(gè)事件分發(fā)接口,你可以通過(guò)實(shí)例化一個(gè)空的 Vue 實(shí)例來(lái)實(shí)現(xiàn)這個(gè)目的。
這些方法的最常見用途之一是父子組件的相互通信。在這些情況下,你可以使用?v-on監(jiān)聽子組件上 $emit 的變化。這可以允許你很方便的添加事件顯性。
然而,如果是跨多層父子組件通信的話,$emit?并沒(méi)有什么用。相反,用集中式的事件中間件可以做到簡(jiǎn)單的升級(jí)。這會(huì)讓組件之間的通信非常順利,即使是兄弟組件。因?yàn)?Vue 通過(guò)事件發(fā)射器接口執(zhí)行實(shí)例,實(shí)際上你可以使用一個(gè)空的 Vue 實(shí)例。
比如,假設(shè)我們有個(gè) todo 的應(yīng)用結(jié)構(gòu)如下:
| Todos ├─ NewTodoInput └─ Todo└─ DeleteTodoButton |
可以通過(guò)單獨(dú)的事件中心管理組件間的通信:
| // 將在各處使用該事件中心 // 組件通過(guò)它來(lái)通信 var eventHub = new Vue() |
然后在組件中,可以使用?$emit,?$on,?$off?分別來(lái)分發(fā)、監(jiān)聽、取消監(jiān)聽事件:
| // NewTodoInput // ... methods: {addTodo: function () {eventHub.$emit('add-todo', { text: this.newTodoText })this.newTodoText = ''} } |
| // DeleteTodoButton // ... methods: {deleteTodo: function (id) {eventHub.$emit('delete-todo', id)} } |
| // Todos // ... created: function () {eventHub.$on('add-todo', this.addTodo)eventHub.$on('delete-todo', this.deleteTodo) }, // 最好在組件銷毀前 // 清除事件監(jiān)聽 beforeDestroy: function () {eventHub.$off('add-todo', this.addTodo)eventHub.$off('delete-todo', this.deleteTodo) }, methods: {addTodo: function (newTodo) {this.todos.push(newTodo)},deleteTodo: function (todoId) {this.todos = this.todos.filter(function (todo) {return todo.id !== todoId})} } |
在簡(jiǎn)單的情況下這樣做可以替代?$dispatch?和?$broadcast,但是對(duì)于大多數(shù)復(fù)雜情況,更推薦使用一個(gè)專用的狀態(tài)管理層如:Vuex。
升級(jí)方式
運(yùn)行遷移工具找出使用?$dispatch?和?$broadcast的實(shí)例。
過(guò)濾器
插入文本之外的過(guò)濾器?移除
現(xiàn)在過(guò)濾器只能用在插入文本中 ({{ }}?tags)。我們發(fā)現(xiàn)在指令 (如:v-model,v-on等) 中使用過(guò)濾器使事情變得更復(fù)雜。像v-for?這樣的列表過(guò)濾器最好把處理邏輯作為一個(gè)計(jì)算屬性放在 js 里面,這樣就可以在整個(gè)模板中復(fù)用。
總之,能在原生 js 中實(shí)現(xiàn)的東西,我們盡量避免引入一個(gè)新的符號(hào)去重復(fù)處理同樣的問(wèn)題。下面是如何替換 Vue 內(nèi)置過(guò)濾器:
替換?debounce?過(guò)濾器
不再這樣寫
| <input v-on:keyup="doStuff | debounce 500"> |
| methods: {doStuff: function () {// ...} } |
請(qǐng)使用?lodash’s?debounce?(也有可能是?throttle) 來(lái)直接控制高耗任務(wù)。可以這樣來(lái)實(shí)現(xiàn)上面的功能:
| <input v-on:keyup="doStuff"> |
| methods: {doStuff: _.debounce(function () {// ...}, 500) } |
這種寫法的更多優(yōu)點(diǎn)詳見:v-model?示例。
替換?limitBy?過(guò)濾器
不再這樣寫:
| <p v-for="item in items | limitBy 10">{{ item }}</p> |
在 computed 屬性中使用 js 內(nèi)置方法:.slice?method:
| <p v-for="item in filteredItems">{{ item }}</p> |
| computed: {filteredItems: function () {return this.items.slice(0, 10)} } |
替換?filterBy?過(guò)濾器
不再這樣寫:
| <p v-for="user in users | filterBy searchQuery in 'name'">{{ user.name }}</p> |
在 computed 屬性中使用 js 內(nèi)置方法?.filter?method:
| <p v-for="user in filteredUsers">{{ user.name }}</p> |
| computed: {filteredUsers: function () {var self = thisreturn self.users.filter(function (user) {return user.name.indexOf(self.searchQuery) !== -1})} } |
js 原生的?.filter?同樣能實(shí)現(xiàn)很多復(fù)雜的過(guò)濾器操作,因?yàn)榭梢栽谟?jì)算 computed 屬性中使用所有 js 方法。比如,想要通過(guò)匹配用戶名字和電子郵箱地址 (不區(qū)分大小寫) 找到用戶:
| var self = this self.users.filter(function (user) {var searchRegex = new RegExp(self.searchQuery, 'i')return user.isActive && (searchRegex.test(user.name) ||searchRegex.test(user.email)) }) |
替換?orderBy?過(guò)濾器
不這樣寫:
| <p v-for="user in users | orderBy 'name'">{{ user.name }}</p> |
而是在 computed 屬性中使用?lodash’s?orderBy?(或者可能是?sortBy):
| <p v-for="user in orderedUsers">{{ user.name }}</p> |
| computed: {orderedUsers: function () {return _.orderBy(this.users, 'name')} } |
甚至可以字段排序:
| _.orderBy(this.users, ['name', 'last_login'], ['asc', 'desc']) |
升級(jí)方式
?
運(yùn)行遷移工具找到指令中使用的過(guò)濾器。如果有些沒(méi)找到,看看控制臺(tái)錯(cuò)誤信息。
過(guò)濾器參數(shù)符號(hào)?變更
現(xiàn)在過(guò)濾器參數(shù)形式可以更好地與 js 函數(shù)調(diào)用方式一致,因此不用再用空格分隔參數(shù):
| <p>{{ date | formatDate 'YY-MM-DD' timeZone }}</p> |
現(xiàn)在用圓括號(hào)括起來(lái)并用逗號(hào)分隔:
| <p>{{ date | formatDate('YY-MM-DD', timeZone) }}</p> |
升級(jí)方式
?
運(yùn)行遷移工具找到老式的調(diào)用符號(hào),如果有遺漏,請(qǐng)看控制臺(tái)錯(cuò)誤信息。
內(nèi)置文本過(guò)濾器?移除
盡管插入文本內(nèi)部的過(guò)濾器依然有效,但是所有內(nèi)置過(guò)濾器已經(jīng)移除了。取代的是,推薦在每個(gè)區(qū)域使用更專業(yè)的庫(kù)來(lái)解決。(比如用?date-fns?來(lái)格式化日期,用?accounting?來(lái)格式化貨幣)。
對(duì)于每個(gè)內(nèi)置過(guò)濾器,我們大概總結(jié)了下該怎么替換。代碼示例可能寫在自定義 helper 函數(shù),方法或計(jì)算屬性中。
替換?json?過(guò)濾器
不用一個(gè)個(gè)改,因?yàn)?Vue 已經(jīng)幫你自動(dòng)格式化好了,無(wú)論是字符串,數(shù)字還是數(shù)組,對(duì)象。如果想用 js 的?JSON.stringify?功能去實(shí)現(xiàn),你也可以把它寫在方法或者計(jì)算屬性里面。
替換?capitalize?過(guò)濾器
| text[0].toUpperCase() + text.slice(1) |
替換?uppercase?過(guò)濾器
| text.toUpperCase() |
替換?lowercase?過(guò)濾器
| text.toLowerCase() |
替換?pluralize?過(guò)濾器
NPM 上的?pluralize?庫(kù)可以很好的實(shí)現(xiàn)這個(gè)功能。如果僅僅想將特定的詞格式化成復(fù)數(shù)形式或者想給特定的值 (‘0’) 指定特定的輸出,也可以很容易地自定義復(fù)數(shù)格式化過(guò)濾器:
| function pluralizeKnife (count) {if (count === 0) {return 'no knives'} else if (count === 1) {return '1 knife'} else {return count + 'knives'} } |
Replacing the?currency?Filter
對(duì)于簡(jiǎn)單的問(wèn)題,可以這樣做:
| '$' + price.toFixed(2) |
大多數(shù)情況下,仍然會(huì)有奇怪的現(xiàn)象 (比如?0.035.toFixed(2)?向上取舍得到?0.04,但是?0.045?向下取舍卻也得到?0.04)。解決這些問(wèn)題可以使用?accounting?庫(kù)來(lái)實(shí)現(xiàn)更多可靠的貨幣格式化。
升級(jí)方式
運(yùn)行遷移工具找到舍棄的過(guò)濾器。如果有些遺漏,請(qǐng)參考控制臺(tái)錯(cuò)誤信息。
雙向過(guò)濾器?替換
有些用戶已經(jīng)樂(lè)于通過(guò)?v-model?使用雙向過(guò)濾器,以很少的代碼創(chuàng)建有趣的輸入。盡管表面上很簡(jiǎn)單,雙向過(guò)濾器也會(huì)暗藏一些巨大的復(fù)雜性——甚至促使?fàn)顟B(tài)更新變得遲鈍影響用戶體驗(yàn)。推薦用包裹一個(gè)輸入的組件取而代之,這樣以更顯性且功能更豐富的方式創(chuàng)建自定義的輸入。
我們現(xiàn)在做一次雙向匯率過(guò)濾器的遷移作為示范:
它基本工作良好,但是拖延的狀態(tài)更新會(huì)導(dǎo)致奇怪的行為。比如,點(diǎn)擊?Result?標(biāo)簽,試著在其中一個(gè)輸入框中輸入?9.999。當(dāng)輸入框失去焦點(diǎn)的時(shí)候,其值將會(huì)更新到?$10.00。然而當(dāng)我們從整個(gè)計(jì)算器的角度看時(shí),你會(huì)發(fā)現(xiàn)存儲(chǔ)的數(shù)據(jù)是?9.999。用戶看到的已經(jīng)不是真實(shí)的同步了!
為了過(guò)渡到一個(gè)更加健壯的 Vue 2.0 的方案,讓我們首先在一個(gè)新的?<currency-input>?組件中包裹這個(gè)過(guò)濾器:
它允許我們添加獨(dú)立過(guò)濾器無(wú)法封裝的行為,比如選擇輸入框聚焦的內(nèi)容。下一步我們從過(guò)濾器中提取業(yè)務(wù)邏輯。接下來(lái)是我們把所有的東西放到一個(gè)外部的?currencyValidator?對(duì)象中:
這會(huì)更加模塊化,不只是更容易的遷移到 Vue 2,同時(shí)也允許匯率間隙和格式化:
- 從你的 Vue 代碼中獨(dú)立出來(lái)進(jìn)行單元測(cè)試
- 在你的應(yīng)用程序的別的部分中使用,比如驗(yàn)證驗(yàn)證一個(gè) API 端的負(fù)荷
把這個(gè)驗(yàn)證器提取出來(lái)之后,我們也可以更舒適的把它構(gòu)建到更健壯的解決方案中。那些古怪的狀態(tài)也消除了,用戶不再可能會(huì)輸入錯(cuò)誤,就像瀏覽器原生的數(shù)字輸入框一樣。
然而在 Vue 1.0 的過(guò)濾器中,我們?nèi)匀皇鞘芟薜?#xff0c;所以還是完全升級(jí)到 Vue 2.0 吧:
你可能注意到了:
- 我們的輸入框的各方面都更顯性,使用生命周期鉤子和 DOM 事件以替代雙向過(guò)濾器的隱藏行為。
- 我們現(xiàn)在可以在自定義輸入框中直接使用?v-model,其不只是固定配合正常的輸入框來(lái)使用,這也意味著我們的組件是對(duì) Vuex 友好的。
- 因?yàn)槲覀円呀?jīng)不再要求過(guò)濾器選項(xiàng)必須要有一個(gè)返回值,所以實(shí)際上我們的匯率工作可以異步完成。這意味著如果我們有很多應(yīng)用需要和匯率打交道,我們可以輕松的提煉這個(gè)邏輯并成為一個(gè)共享的微服務(wù)。
升級(jí)方式
運(yùn)行遷移工具找到在例如?v-model?的指令中使用過(guò)濾器的例子。如果你錯(cuò)過(guò)了,則應(yīng)該會(huì)收到命令行報(bào)錯(cuò)。
插槽
重名的插槽?移除
同一模板中的重名?<slot>?已經(jīng)棄用。當(dāng)一個(gè)插槽已經(jīng)被渲染過(guò)了,那么就不能在同一模板其它地方被再次渲染了。如果要在不同位置渲染同一內(nèi)容,可以用 prop 來(lái)傳遞。
升級(jí)方式
更新后運(yùn)行測(cè)試,查看控制臺(tái)警告信息?關(guān)于重名 slots 的提示?v-model。
slot?樣式參數(shù)?移除
通過(guò)具名?<slot>?插入的片段不再保持?slot?的參數(shù)。請(qǐng)用一個(gè)包裹元素來(lái)控制樣式。或者用更高級(jí)方法:通過(guò)編程方式修改內(nèi)容 :render functions。
升級(jí)方式
?
運(yùn)行遷移工具找到選擇 slots 標(biāo)簽 CSS 選擇器 (例如:[slot="my-slot-name"])。
特殊屬性
keep-alive?屬性?替換
keep-alive?不再是一個(gè)特殊屬性而是一個(gè)包裹組件,類似于?<transition>比如:
| <keep-alive><component v-bind:is="view"></component> </keep-alive> |
這樣可以在含多種狀態(tài)子組件中使用?<keep-alive>?:
| <keep-alive><todo-list v-if="todos.length > 0"></todo-list><no-todos-gif v-else></no-todos-gif> </keep-alive> |
當(dāng)?<keep-alive>?含有不同子組件時(shí),應(yīng)該分別影響到每一個(gè)子組件。不僅是第一個(gè)而是所有的子組件都將被忽略。
和?<transition>一起使用時(shí),確保把內(nèi)容包裹在內(nèi):
| <transition><keep-alive><component v-bind:is="view"></component></keep-alive> </transition> |
升級(jí)方式
運(yùn)行遷移工具找到keep-alive?屬性。
計(jì)算插值
屬性內(nèi)部的計(jì)算插值?移除
屬性內(nèi)部的計(jì)算插值已經(jīng)不能再使用了:
| <button class="btn btn-{{ size }}"></button> |
應(yīng)該寫成行內(nèi)表達(dá)式:
| <button v-bind:class="'btn btn-' + size"></button> |
或者計(jì)算屬性:
| <button v-bind:class="buttonClasses"></button> |
| computed: {buttonClasses: function () {return 'btn btn-' + size} } |
升級(jí)方式
運(yùn)行遷移工具找到屬性內(nèi)部的計(jì)算插值
HTML 計(jì)算插值?移除
HTML 的計(jì)算插值 ({{{ foo }}}) 已經(jīng)移除,取代的是?v-html?指令。
升級(jí)方式
運(yùn)行遷移工具找到 HTML 計(jì)算插值。
單次綁定替換
單次綁定 ({{* foo }}) 已經(jīng)被新的?v-once?directive?取代。
升級(jí)方式
運(yùn)行?遷移工具找到單次綁定使用位置。
響應(yīng)
vm.$watch?changed
通過(guò)?vm.$watch創(chuàng)建的觀察器現(xiàn)在將在組件渲染時(shí)被激活。這樣可以讓你在組件渲染前更新狀態(tài),不用做不必要的更新。比如可以通過(guò)觀察組件的 prop 變化來(lái)更新組件本身的值。
如果以前通過(guò)?vm.$watch?在組件更新后與 DOM 交互,現(xiàn)在就可以通過(guò)updated生命周期鉤子來(lái)做這些。
升級(jí)方式
運(yùn)行測(cè)試,如果有依賴于老方法的觀察器將彈出?failed tests。
vm.$set?變更
vm.$set?只是?Vue.set?的別名。
升級(jí)方式
運(yùn)行遷移工具找到過(guò)時(shí)的用法
vm.$delete?變更
vm.$delete?現(xiàn)在只是:Vue.delete?別名。
升級(jí)方式
運(yùn)行遷移工具找到過(guò)時(shí)的用法
Array.prototype.$set?棄用
用?Vue.set?替代
升級(jí)方式
運(yùn)行遷移工具找到數(shù)組上的.$set。如有遺漏請(qǐng)參考控制臺(tái)錯(cuò)誤信息。
Array.prototype.$remove?移除
用?Array.prototype.splice?替代,例如:
| methods: {removeTodo: function (todo) {var index = this.todos.indexOf(todo)this.todos.splice(index, 1)} } |
或者更好的方法,直接給除去的方法一個(gè) index 參數(shù):
| methods: {removeTodo: function (index) {this.todos.splice(index, 1)} } |
升級(jí)方式
運(yùn)行遷移工具找到數(shù)組上的.$remove。如有遺漏請(qǐng)參考控制臺(tái)錯(cuò)誤信息
Vue 實(shí)例上的Vue.set?和?Vue.delete移除
Vue.set?和?Vue.delete?在實(shí)例上將不再起作用。現(xiàn)在都強(qiáng)制在實(shí)例的 data 選項(xiàng)中聲明所有頂級(jí)響應(yīng)值。如果刪除實(shí)例屬性或?qū)嵗?data上的某個(gè)值,直接將它設(shè)置為 null 即可。
升級(jí)方式
?
運(yùn)行遷移工具找到實(shí)例中的?Vue.set?或?Vue.delete?。如有遺漏請(qǐng)參考控制臺(tái)錯(cuò)誤信息。
替換?vm.$data?移除
現(xiàn)在禁止替換實(shí)例的 $data。這樣防止了響應(yīng)系統(tǒng)的一些極端情況并且讓組件狀態(tài)更加可控可預(yù)測(cè) (特別是對(duì)于存在類型檢查的系統(tǒng))。
升級(jí)方式
運(yùn)行遷移工具找到覆蓋?vm.$data的位置。如有遺漏請(qǐng)參考控制臺(tái)警告信息。
vm.$get?移除
可以直接取回響應(yīng)數(shù)據(jù)。
升級(jí)方式
運(yùn)行?遷移工具找到?vm.$get?的位置。如有遺漏請(qǐng)參考?控制臺(tái)錯(cuò)誤信息。
圍繞 DOM 的實(shí)例方法
vm.$appendTo?移除
使用 DOM 原生方法:
| myElement.appendChild(vm.$el) |
升級(jí)方式
運(yùn)行遷移工具找到?vm.$appendTo?的位置。如果有遺漏可以參考控制臺(tái)錯(cuò)誤信息。
vm.$before?移除
使用 DOM 原生方法:
| myElement.parentNode.insertBefore(vm.$el, myElement) |
升級(jí)方式
運(yùn)行?遷移工具找到?vm.$before。如有遺漏,請(qǐng)參考?控制臺(tái)錯(cuò)誤信息。
vm.$after?移除
使用 DOM 原生方法:
| myElement.parentNode.insertBefore(vm.$el, myElement.nextSibling) |
如果?myElement?是最后一個(gè)節(jié)點(diǎn)也可以這樣寫:
| myElement.parentNode.appendChild(vm.$el) |
升級(jí)方式
?
運(yùn)行遷移工具找到?vm.$after?的位置。如有遺漏,請(qǐng)參考控制臺(tái)錯(cuò)誤信息。
vm.$remove?移除
使用 DOM 原生方法:
| vm.$el.remove() |
升級(jí)方式
運(yùn)行?遷移工具找到vm.$remove。如有遺漏,請(qǐng)參考控制臺(tái)錯(cuò)誤信息。
底層實(shí)例方法
vm.$eval?移除
盡量不要使用,如果必須使用該功能并且不肯定如何使用請(qǐng)參考?the forum。
升級(jí)方式
?
運(yùn)行遷移工具找到使用?vm.$eval?的位置。如有遺漏請(qǐng)參考控制臺(tái)錯(cuò)誤信息。
vm.$interpolate?移除
盡量不要使用,如果必須使用該功能并且不肯定如何使用請(qǐng)參考?the forum。
升級(jí)方式
運(yùn)行遷移工具找到vm.$interpolate。如有遺漏請(qǐng)參考控制臺(tái)錯(cuò)誤信息.
vm.$log?移除
請(qǐng)使用?Vue Devtools?感受最佳 debug 體驗(yàn)。
升級(jí)方式
運(yùn)行遷移工具找到?vm.$log。如有遺漏請(qǐng)參考控制臺(tái)錯(cuò)誤信息.
實(shí)例 DOM 選項(xiàng)
replace: false?移除
現(xiàn)在組件總是會(huì)替換掉他們被綁定的元素。為了模仿replace: false的行為,可以用一個(gè)和將要替換元素類似的元素將根組件包裹起來(lái):
| new Vue({el: '#app',template: '<div id="app"> ... </div>' }) |
或者使用渲染函數(shù):
| new Vue({el: '#app',render: function (h) {h('div', {attrs: {id: 'app',}}, /* ... */)} }) |
升級(jí)方式
運(yùn)行遷移工具找到?replace: false使用的位置。
全局配置
Vue.config.debug?移除
不再需要,因?yàn)榫嫘畔⒛J(rèn)在堆棧信息里輸出。
升級(jí)方式
運(yùn)行遷移工具找到包含Vue.config.debug的地方。
Vue.config.async?移除
異步操作現(xiàn)在需要渲染性能的支持。
升級(jí)方式
運(yùn)行?遷移工具找到使用Vue.config.async的實(shí)例。
Vue.config.delimiters?替換
以模板選項(xiàng)的方式使用。這樣可以在使用自定義分隔符時(shí)避免影響第三方模板。
升級(jí)方式
運(yùn)行遷移工具找到使用Vue.config.delimiters的實(shí)例。
Vue.config.unsafeDelimiters?移除
HTML 插值替換為?v-html。
升級(jí)方式
運(yùn)行遷移工具找到?Vue.config.unsafeDelimiters。然后 helper 工具也會(huì)找到 HTML 插入的實(shí)例,可以用`v-html`來(lái)替換。
全局 API
帶?el?的?Vue.extend?移除
el 選項(xiàng)不再在?Vue.extend中使用。僅在實(shí)例創(chuàng)建參數(shù)中可用。
升級(jí)方式
更新后運(yùn)行測(cè)試在控制臺(tái)警告信息中找到關(guān)于帶有Vue.extend的el。
Vue.elementDirective?移除
用組件來(lái)替代
升級(jí)方式
運(yùn)行遷移工具找到包含Vue.elementDirective的實(shí)例。
Vue.partial?移除
Partials 已被移除,取而代之的是更明確的組件之間的數(shù)據(jù)流–props。除非你正在使用一個(gè)部分性能關(guān)鍵型區(qū)域,否則建議只使用一個(gè)?normal component?來(lái)代替。如果你是動(dòng)態(tài)綁定部分的?name,您可以使用?dynamic component。
如果你碰巧在你的應(yīng)用程序的性能關(guān)鍵部分使用 partials,那么你應(yīng)該升級(jí)到函數(shù)式組件。它們必須在純 JS / JSX 文件中 (而不是在?.vue?文件中),并且是無(wú)狀態(tài)的和無(wú)實(shí)例的,就像 partials。這使得渲染極快。
函數(shù)式組件相對(duì)于 partials 一個(gè)好處是它們可以更具動(dòng)態(tài)性,因?yàn)樗鼈冊(cè)试S您訪問(wèn) JavaScript 的全部功能。然而,這是有成本的。如果你從來(lái)沒(méi)有使用過(guò)渲染式的組件框架,你可能需要花費(fèi)更長(zhǎng)的時(shí)間來(lái)學(xué)習(xí)它們。
from:https://cn.vuejs.org/v2/guide/migration.html?
總結(jié)
以上是生活随笔為你收集整理的Vue.js 从 Vue 1.x 迁移的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Vue.js 深入响应式原理
- 下一篇: Vue.js 从 Vue Router