傳統 Vue Router 都以 this
使用,這使得 Extract Function 時還必須將 Vue Instance 傳進 Function,事實上 Vue Router 也能不使用 this
,直接 Import Router 使用,甚至更進一步 Point-free。
Version
Vue 2.6.11
Vue-router 3.2.0
Options API
<template>
<div id="app">
<div id="nav">
<a @click.prevent="onHomeClick" href="#">Home</a> |
<a @click.prevent="onAboutClick" href="#">About</a>
</div>
<router-view/>
</div>
</template>
<script>
let onHomeClick = function() {
this.$router.push('/')
}
let onAboutClick = function() {
this.$router.push('/about')
}
export default {
methods: {
onHomeClick,
onAboutClick,
}
}
</script>
12 行
let onHomeClick = function() {
this.$router.push('/')
}
若要使用 Vue Router 的 push()
,傳統必須使用 this.$router
,這使得 extract function 時必須考慮 this
將 Vue Instance 傳進 function。
Functional API
<template>
<div id="app">
<div id="nav">
<a @click.prevent="onHomeClick" href="#">Home</a> |
<a @click.prevent="onAboutClick" href="#">About</a>
</div>
<router-view/>
</div>
</template>
<script>
import router from '@/router/index'
let onHomeClick = () => router.push('/')
let onAboutClick = () => router.push('/about')
export default {
methods: {
onHomeClick,
onAboutClick,
}
}
</script>
12 行
import router from '@/router/index'
將實際 router 引入。
14 行
let onHomeClick = () => router.push('/')
直接以 router
使用 push()
,由於沒使用 this
,可直接使用 arrow function,extract function 時也不用再傳入 Vue Instance。
Point-free
<template>
<div id="app">
<div id="nav">
<a @click.prevent="onHomeClick" href="#">Home</a> |
<a @click.prevent="onAboutClick" href="#">About</a>
</div>
<router-view/>
</div>
</template>
<script>
import { pipe, always, bind } from 'ramda'
import router from '@/router/index'
let push = bind(router.push, router)
let onHomeClick = pipe(
always('/'),
push
)
let onAboutClick = pipe(
always('/about'),
push
)
export default {
methods: {
onHomeClick,
onAboutClick,
}
}
</script>
15 行
let push = bind(router.push, router)
使用 bind()
從 router
抽出 push()
free function。
17 行
let onHomeClick = pipe(
always('/'),
push
)
使用 pipe()
組合出 onHomeClick()
。
Conclusion
- Vue 有多種寫法,其實不見得什麼都要使用
this
,Vue Router 透過引用實際 router 可直接使用push()
,不用再擔心很難處理this
- 既然不必使用
this
,可使用bind()
抽出push()
,進一步使用 Function Pipeline 組合