Notices of the Composition API
2019/11/23
v-kansai mokumoku #3
2019/12/16
v-okinawa #3
jiyuujin
- Vue/Nuxt/PHP/Scala/Java/Swift
- v-kansai/kansai.ts/..
- Web猫ブログ (webneko.dev)
Composition API
How do you write Vue/TS?
The more you go down,
it doesn't look like Vue
- Vue.extend
- Class component
- vue-property-decorator
- @vue/composition-api
Final RFC for Vue3!!!
You can also use the api,
in business projects
Install & Prepare
Install @vue/composition-api
Register as a plugin
import Vue from 'vue'
import CompositionApi from '@vue/composition-api'
Vue.use(CompositionApi)
Import a registered plugin
import '@/plugins/composition-api.ts'
That's all!
At first, we can do this!
Not much different as usual
- HTML, script, and style as usual
- Easier to use TS, also use TSX not dividing a template
- Caution to enlargement of base fn (setup)
HowTo Use in a Component
createComponent class
import { createComponent, SetupContext } from '@vue/composition-api'
export default createComponent({
//
})
Base fn - setup
import { createComponent, SetupContext } from '@vue/composition-api'
export default createComponent({
setup(props: {}, ctx: SetupContext) {
return (
//
)
}
})
setup fn - arguments
- props (Object type)
- ctx (SetupContext)
props (Object type)
Set the object type for props
import { createComponent, SetupContext } from '@vue/composition-api'
interface PropsType {
participants: number,
mealName: string
}
export default createComponent({
setup(props: PropsType, ctx: SetupContext) {
//
}
})
ctx (SetupContext)
Type definitions of SetupContext
interface Data {
[key: string]: unknown
}
interface SetupContext {
attrs: Data
slots: Slots
parent: ComponentInstance | null
root: ComponentInstance
emit: ((event: string, ...args: unknown[]) => void)
}
function setup(
props: Data,
context: SetupContext
): Data
To get route params, use ctx.root.$route
Get route parameters by SetupContext
import { createComponent, SetupContext } from '@vue/composition-api'
export default createComponent({
setup(props: {}, ctx: SetupContext) {
// Get Route Params
const param = ctx.root.$route.params;
}
})
In global managed, use ctx.root.$store
Get state by SetupContext
import { createComponent, SetupContext } from '@vue/composition-api'
export default createComponent({
setup(props: {}, ctx: SetupContext) {
// Get state
const userStatus = ctx.root.$store.state.product.userStatus
// Use computed api
const filteredUserStatus = computed(
() => ctx.root.$store.state.product.userStatus
)
}
})
others..
HowTo set instance variables
- (data)
- ref
- reactive
Use instance variables by data
import Vue from 'vue'
export default Vue.extend({
data() {
return {
participants: 12,
meals: ['hamburger', 'ramen', 'pizza']
}
}
})
Use reactive variables by ref
import { createComponent, SetupContext } from '@vue/composition-api'
export default createComponent({
setup(props: {}, ctx: SetupContext) {
const participants = ref(12)
const meals = ref(['hamburger', 'ramen', 'pizza'])
}
})
Set a single reactive dataset with refs
import { createComponent, SetupContext } from '@vue/composition-api'
export default createComponent({
setup(props: {}, ctx: SetupContext) {
const ReactiveData = reactive({
participants: 12,
meals: ['hamburger', 'ramen', 'pizza']
})
}
})
ref vs reactive
- Use object type in reactive
- Put higher related elements in reactive
- The other side, put the independence element in ref
One another..
Don't forget "return"
import { createComponent, SetupContext } from '@vue/composition-api'
export default createComponent({
setup(props: {}, ctx: SetupContext) {
return {
state
}
}
})
unless, you can't use variables in a template..😅
Wanna Prevent Enlargement
Directories in Vue CLI
- views
- components
- compositions
- repositories
views
import { createComponent, SetupContext } from '@vue/composition-api'
export default createComponent({
setup(props: {}, ctx: SetupContext) {
return (
//
)
}
})
Load other components
import { createComponent, SetupContext } from '@vue/composition-api'
const AtomsButton = () => import('@/components/AtomsButton.vue')
export default createComponent({
components: {
AtomsButton
},
setup(props: {}, ctx: SetupContext) {
return (
//
)
}
})
compositions
- Mainly use logic, not related to UI
- Inherent fn to the view
Several methods..👎
import Vue from 'vue'
export default Vue.extend({
methods: {
increment() {
//
},
decrement() {
//
}
}
})
Ummm, not bad..😕
import { createComponent, SetupContext } from '@vue/composition-api'
export default createComponent({
const increment = () => {
//
}
const decrement = () => {
//
}
setup(props: {}, ctx: SetupContext) {
return (
increment,
decrement
)
}
})
Easier to see..👍
import { createComponent, SetupContext } from '@vue/composition-api'
import { increment, decrement } from '@/compositions'
export default createComponent({
setup(props: {}, ctx: SetupContext) {
return (
increment,
decrement
)
}
})
repositories
- Use APIs
- Access to external resources
Mix in a component..👎
import Vue from 'vue'
export default Vue.extend({
methods: {
async fetchApi() {
await ..
}
}
})
Ummm, not bad..😕
import { createComponent, SetupContext, onMounted } from '@vue/composition-api'
export default createComponent({
const fetchApi = async () => {
await ..
}
onMounted(async () => {
await fetchApi()
})
setup(props: {}, ctx: SetupContext) {
return (
//
)
}
})
Easier to see..👍
import { createComponent, SetupContext } from '@vue/composition-api'
import { fetchApi } from '@/repositories'
export default createComponent({
setup(props: {}, ctx: SetupContext) {
return (
fetchApi
)
}
})
Wanna vuex store
This time, omitted..🙏
Really, is it necessary..?
- Do u think about the system design?
- Can you make use of props?
- Create a plugin from the perspective of DI
That aside.. 🤔
What something in trouble?
Something in trouble..
- No existed "asyncData" api
- Cannot use the "component" tag
- ..
Wanna use"asyncData" api in a component
- No existed.. 😱
- Use "fetch" api instead of the api
Route params before rendering
import { createComponent, SetupContext } from '@vue/composition-api'
export default createComponent({
fetch({ route }) {
console.log(route.params)
},
setup(props: {}, ctx: SetupContext) {
return (
//
)
}
})
Store actions before rendering
import { createComponent, SetupContext } from '@vue/composition-api'
export default createComponent({
fetch({ store }) {
store.dispatch('fetchAction')
},
setup(props: {}, ctx: SetupContext) {
return (
//
)
}
})
Can u use the "component" tag, in Vue/TSX
i don't know
Under investigating.. 🤔
Do u understand what it's..?
<template>
<component
:is="svg"
style="width: 16px;"
/>
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
props: {
name: {
type: String,
required: true
}
},
computed: {
svg() {
return () => import(`@/assets/img/${this.name}.svg`)
}
}
})
</script>
Not working in TSX.. 😭
import { createComponent, SetupContext } from '@vue/composition-api'
type SvgProps = {
name: string
}
export default createComponent({
props: {
name: {
type: String,
required: true
}
},
setup(props: SvgProps, ctx: SetupContext) {
const svg = () => import(`@/assets/img/${props.name}.svg`)
return () => (
<component is={svg} style="width: 16px;" />
)
}
})
Give up TSX, exchange to divide a template
Basically, we can use the composition api in Vue/TSX
Divide a template as usual
<template>
<component
:is="svg"
style="width: 16px;"
/>
</template>
<script lang="ts">
import { createComponent, SetupContext } from '@vue/composition-api'
type SvgProps = {
name: string
}
export default createComponent({
props: {
name: {
type: String,
required: true
}
},
setup(props: SvgProps, ctx: SetupContext) {
const svg = () => import(`@/assets/img/${props.name}.svg`)
return () => (
svg
)
}
})
</script>
Not yet, developing.. 🤔🤔🤔
Easier to write Vue/TS
Easier to use TSX in Vue..?
Vue Advent Calendar 2019
Also use Vue/TSX in 12/24..🎁
Thank you..🙇♀️
Notecis of the Composition API
By jiyuujin
Notecis of the Composition API
v-kansai もくもく会 #3 (with WeJS) 並びに v-okinawa #3 いずれもリモートLT用に作りました。
- 1,245