Vue 3 要以 props.name
形式讀取 prop,但這種方式不方便 Point-free,Vue3-fp 提供了 Curry Function 版本的 mark
。
Version
Vue 3.2
Vue3-fp 0.3.2
Composition API
將 prop 傳給 state,按下 +
將對 state 遞增。
App.vue
<template>
<MyCounter :start="outerCount"/>
</template>
<script setup>
import MyCounter from '/src/components/MyCounter.vue'
let outerCount = $ref (3)
</script>
第 6 行
import MyCounter from '/src/components/MyCounter.vue'
引用 MyCounter
component。
第 8 行
let outerCount = $ref (3)
定義 outerCount
state 的初始值為 3
。
MyCounter.vue
<template>
<span>{{ innerCount }}</span>
<button @click="onClick">+</button>
</template>
<script setup>
let innerCount = $ref (0)
let props = defineProps ({ start: Number })
innerCount = props.start
let onClick = _ => innerCount++
</script>
第 8 行
let props = defineProps ({ start: Number })
使用 defineProps
定義 start
prop。
第 7 行
let innerCount = $ref (0)
定義 innerCount
state 的初始值為 0
。
10 行
innerCount = props.start
將 start
prop 值寫入 innerCount
state。
Vue 3 要求我們以
props.name
形式讀取 prop
11 行
let onClick = _ => innerCount++
當按下 +
button 將對 innerCount
state 遞增。
Point-free
結果不變,但使用 Point-free 改寫。
App.vue
<template>
<MyCounter :start="outerCount"/>
</template>
<script setup>
import MyCounter from '/src/components/MyCounter.vue'
let outerCount = $ref (3)
</script>
App.vue
沒有改變。
MyCounter.vue
<template>
<span>{{ innerCount }}</span>
<button @click="onClick">+</button>
</template>
<script setup>
import { ref } from 'vue'
import { read, write } from 'vue3-fp'
import { pipe, inc, thunkify, prop } from 'ramda'
let mark = thunkify (prop)
let innerCount = ref(0)
let props = defineProps ({ start: Number })
let onClick = pipe (
read (innerCount),
inc,
write (innerCount)
)
pipe (
mark ('start') (props),
write (innerCount)
) ()
</script>
22 行
pipe (
mark ('start') (props),
write (innerCount)
) ()
使用 pipe
組合 IIFE:
mark ('start') (props)
:讀取start
propwrite (innerCount)
:寫入innerCount
state
11 行
let mark = thunkify (prop)
Vue 3 需以 props.name
形式讀取 prop,但這種方式並不適合 Point-free。
其實 prop 讀取方式很類似 Ramda 的 prop
,因此以 prop()
為基礎加以 thunkify
成 mark
就很適合 Function Pipeline。
16 行
let onClick = pipe (
read (innerCount),
inc,
write (innerCount)
)
使用 pipe
組合 onClick
:
read (innerCount)
:讀取innerCount
stateinc
:對值遞增write (innerCount)
:寫入innerCount
state
Vue3-fp
結果不變,但使用 Vue3-fp 改寫。
App.vue
<template>
<MyCounter :start="outerCount"/>
</template>
<script setup>
import MyCounter from '/src/components/MyCounter.vue'
let outerCount = $ref (3)
</script>
App.vue
沒有改變。
MyCounter.vue
<template>
<span>{{ innerCount }}</span>
<button @click="onClick">+</button>
</template>
<script setup>
import { ref } from 'vue'
import { read, write, mark } from 'vue3-fp'
import { pipe, inc } from 'ramda'
let innerCount = ref(0)
let props = defineProps ({ start: Number })
let onClick = pipe (
read (innerCount),
inc,
write (innerCount)
)
pipe (
mark ('start') (props),
write (innerCount)
) ()
</script>
第 8 行
import { read, write, mark } from 'vue3-fp'
Vue3-fp 已經提供 mark
可直接使用。
mark :: String -> Data -> () -> a
由 props 讀取指定 prop
String
:傳入指定 prop
Data
:傳入 props
() -> a
:回傳 Thunk
Conclusion
- 為了 Point-free 常將 function 加以
thunkify
,如read
也是thunkify (unref)