Vue 若要使用 OOP 風格開發,可以使用 Class Component,還可搭配 TypeScript,Vue CLI 預設已經整好環境。Vue 原本風格,介於 OOP 與 FP 之間,沒使用 class,但卻大量使用 this
,這仍是 OOP 產物,若要更具 FP 風格,可以參考本文方法。
Version
Vue 2.6.11
Vuex 3.1.2
Vue CLI 4.2.2
Ramda 0.27.0
Component
<template>
<div>
<ul>
<li v-for="(item, index) in todos" :key="index">
{{ item.id }} : {{ item.title }}
</li>
</ul>
</div>
</template>
<script>
import axios from 'axios'
let url = 'https://jsonplaceholder.typicode.com/todos'
let mounted = function() {
axios.get(url)
.then(x => x.data.slice(0, 3))
.then(x => this.todos = x)
}
export default {
name: 'HelloWorld',
data: () => ({
todos: [],
}),
mounted,
}
</script>
16 行
let mounted = function() {
axios.get(url)
.then(x => x.data.slice(0, 3))
.then(x => this.todos = x)
}
mounted()
傳統都會寫在 object 內,這屬於 OOP 風格,建議可將 computed
、watch
、method
、hooks
… 等都拉出來獨立寫成 function,這樣會更有 FP 感覺。
因為 mouted()
要使用 this.todos
,所以只能使用 function expression。
then()
之後可放心使用 arrow function,因為 arrow function 沒有自己的 this
,而是 parent scope 的 this
,也就是 mounted()
的 this
,因此沒有問題。
.then(x => x.data.slice(0, 3))
.then(x => this.todos = x)
Promise 的 then()
切記分開 pure function 與 unpure function:
- 若屬於資料處理部分,使用 pure function
- 寫入
data
屬於 side effect,集中在最後的then()
,不要在處理資料的 pure function 內有 side effect
若想在 Vue 在 component 寫法更 FP,應盡量使用 function,至於要使用 function expression 或 arrow function,取決於 3 個原則:
- 若該 function 要使用
this
存取 Vue 的data
、property
、computed
、method
等,要使用 function expression - 若該 function 沒用到
this
存取 Vue 的data
、property
、computed
、method
等,可使用 arrow function
也就是盡量使用 Arrow Function,除非要使用
this
Vuex
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
let url = 'https://jsonplaceholder.typicode.com/todos'
let setTodos = (state, payload) => state.todos = payload
let getTodos = ({ commit }) =>
axios.get(url)
.then(({ data }) => data.slice(0, 3))
.then(x => commit('setTodos', x))
export default new Vuex.Store({
state: {
todos: [],
},
mutations: {
setTodos,
},
actions: {
getTodos,
},
});
若 data 是放在 Vuex 的 store,則有另一番氣象。
第 9 行
let setTodos = (state, payload) => state.todos = payload
Mutation 因為完全沒用到 this
,可安心使用 arrow function。
13 行
let getTodos = ({ commit }) =>
axios.get(url)
.then(({ data }) => data.slice(0, 3))
.then(x => commit('setTodos', x))
Action 也因為完全沒用到 this
,可安心使用 arrow function。
Promise 的 then()
依然處理資料使用 pure function,在最後的 then()
使用 side effect。
在 Vuex 可大膽全部使用 arrow function,因為沒有
this
後顧之憂,並可搭配 object destructuring
Conclusion
- 若要更接近 FP 風格,Vue 可全部使用 function,無論是
computed
、method
、watch
…,其本質都是 function,應盡量使用 arrow function,唯若要存取 Vue Instance 的 property,也就是要使用this
時,才使用 function expression - Vuex 內可大膽完全使用 arrow function,還可搭配 object destructuring