[VueJS] 眼藥水 2.0

這年頭好像 2.0 比較夯,隔壁棚的 ng 也出了 2.0(而且聽說要重來,React 表示:


推薦

當然要先敗讀一下 Kuro 的大作,

V1 與 V2 元件實體之差異

官方文件 Render Function

實際操作所遇到的狀況

你如果在獨立元件當中,不使用 Render Function 的話,官方會建議你去改 webpack 的設定(因為預設是使用 vue.common.js 來作為渲染引擎,如果你的獨立元件使用了 template 的話,官方會建議你改成 vue.min.js

主要是會引發這樣的警告:

[Vue warn]: You are using the runtime-only build of Vue where the template option is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

差異在於,如果你不用,那就無法使用 2.0 的 Server-Side-Render 的功能。

所以原本自己寫的元件,就必須改由 render 去接手。

Props 的差異

由於 2.0 的 props 已經強迫改為 one-way 的方式,所以原有的 twoWay, .sync 基本上就沒有了(被移除。所以,當你原先使用雙向的溝通方式,就得改由 Vuex 或是事件的方式來做。

另外,如果你在過程中直接操作(或是修改 props 的值,也會拿到一些警告,不礙事,但是基本上就是沒辦法改(請用事件或是 Vuex 之類的東西做。

Vuex 的改變

跟 Vue 比起來,這大概是改最多的。Store 的結構沒什麼太大的轉變,有改變的是 Actions, Getters 取用的方式不一樣了,

// Vue 1.x
import { myAction } from '../vuex/actions'
import { myGetter } from '../vuex/getters'

export default {
  vuex: {
    actions: {
      myAction
    },
    getters: {
      myGetter
    }
  }
}
// Vue 2.0
import { mapActions, mapGetters } from 'vuex'

export default {
  methods: mapActions({
    myAction: 'myAction'
  }),
  computed: mapGetters({
    myGetter: 'myGetter'
  })
}

是的,他佔用了 methodscomputed 這兩個方法,如果你有額外的方法在這裡面,你可以考慮用 Objact.asset 來做簡易的擴充。

另外,Vuex 裡面現在可以更方便使用 async/await 的新方法,原本的 dispatch 則拆分為 dispatchcommit 兩種,簡單的例子像是這樣,

actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    // wait for actionA to finish
    await dispatch('actionA')
    commit('gotOtherData', await getOtherData())
  }
}

然後 middleware 沒有了,換成 plugins,另外 logger 也換了位置,

import Vue from 'vue'
import createLogger from 'vuex/dist/logger'
import myModule from './vuex/my-module'

Vue.use(Vuex)

const debug = process.env.NODE_ENV === 'development'

export default new Vuex.Store({
  modules: {
    myModule
  },
  strict: debug,
  plugins: debug ? [createLogger()] : []
})

Vue-router 2.x 結構轉變

設定變的比較簡單,不過原本的 Nested Route 寫法改成一大串的陣列。另外,在元件裡面的寫法也略有改變,

const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // called before the route that renders this component is confirmed.
    // does NOT have access to `this` component instance,
    // because it has not been created yet when this guard is called!
  },
  beforeRouteLeave (to, from, next) {
    // called when the route that renders this component is about to
    // be navigated away from.
    // has access to `this` component instance.
  }
}

好吧,不能說略有,應該說只剩 beforeRouteEnterbeforeRouteLeave 可以用而已。至於原本的 $router$route 則不受影響,可以繼續使用。

小結

嘗試著把一些東西改寫成 2.0,實際使用 devtools 測試,畫面的產出速度可以再縮減 1~2 秒左右(不考慮 AJAX 拉資料回來的時間差,實際上差不到 100ms

Hina Chen
偏執與強迫症的患者,算不上是無可救藥,只是我已經遇上我的良醫了。
Taipei