v-kansai#11、京都Devかふぇ#7での登壇資料です!!
Deep Dive IntoVue Composition APIv-kansai Vue.js/Nuxt.js meetup #10@Daikids2
View Slide
খౡ େج / Daiki Kojima@Daikids2@jiko21ژେӃใֶݚڀՊM2 (20ଔ)ΠϯϑϥҎ֎͍͍ͩͨͳΜͰVue fes JPࢀՃ͠·͢!!
ͤΜͰΜ!• KFUG 2019Ͱొஃ͠·͢!
Posted on …IUUQCJUMZ*[E#-4
Today’s Topic• What is Composition API?• How to write…• ͪΐͬͱߴͳLogicͷ࠶ར༻
αϯϓϧίʔυ• GitHub: bit.ly/2Mgwy77• Demo: bit.ly/2OmiuLQ
What is Composition API?
What is Composition API?• Vue 3Ͱొ༧ఆ?ͷAPI• چ໊: function-apihttps://github.com/vuejs/rfcs/pull/78
Motivation of Composition API• ϩδοΫ࠶ར༻ͨ͠Γίʔυͷߏ·ΘΓ• ࠓͷAPIͩͱoptionͬͯΔ͔Βηϯε͕ཁΔ• ܕਪ• thisʹґଘͯͯ͠ܕ͕ͭΒ͍• IDEͱ͔ͷॿ͚͕ಘΒΕʹ͍͘…https://vue-composition-api-rfc.netlify.com/#motivation
Μ?
ܕपΓͳΒ
Class Style API͕ ͋Δ͡ΌΜ?
Vue3ʹ࠾༻͞Ε·ͤΜ…https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121
Why Class Style API is dropped?• Vueࣗମɺ৭ΜͳͷΛthisʹͻͬ͘ΔΊͯΔ…• propsΛѻ͏ࡍʹσίϨʔλΛ͏ඞཁ͕͋Γɺ ෆ࣮֬ੑ͕ଟ͍(TC39ͱͷ݉Ͷ߹͍)• TSXαϙʔτͱ߹Θͳ͍…https://vue-composition-api-rfc.netlify.com/#motivation
How to write…
४උ• ҎԼͷίϚϯυͰύοέʔδΛΠϯετʔϧ • main.ts(js)ʹҎԼͷΑ͏ʹॻ͚OKnpm install @vue/composition-api --saveimport Vue from "vue";import VueCompositionApi from '@vue/composition-api';Vue.use(VueCompositionApi);
ྫ͑…• ୯७ͳTodoΞϓϦΛ ߟ͑Δ• Root ComponentTodo.vue
ྫ͑…• TodoՃ༻ͷϑΥʔϜTodoForm.vue
ྫ͑…• Todoදࣔ༻ͷ ListTodoList.vue
TodoForm.vueΛݟͯΈΔAdd
ྫ͑…• ϑπʔʹॻ͘ͱ ͜Μͳ͔Μ͡?import Vue, {PropType} from 'vue';export default Vue.extend({name: 'TodoForm',props: {onSubmit: {type: Function as PropType<(text: string) => void>,required: true,},},data() {return {text: '',};},computed: {isValid(): boolean {return this.text.length > 0;},},methods: {submit() {this.onSubmit(this.text);this.text = '';},},});
ྫ͑…• ͜͏ͳΔimport {computed, createComponent, PropType, reactive} from '@vue/composition-api';const TodoForm = createComponent({props: {onSubmit: {type: Object as PropType<(text: string) => void>,required: true,},},setup(props) {const state = reactive({text: '',});const isValid = computed(() => state.text.length > 0);const submit = () => {props.onSubmit(state.text);state.text = '';};return {state,submit,isValid};}});
ίϯϙʔωϯτͷ࡞Γํ• createComponentͰίϯϙʔωϯτΛ࡞ (jsͰॻ͘ͳΒexport default {}ͰOK)import {createComponent, PropType, reactive} from '@vue/composition-api';const TodoForm = createComponent({...});
ίϯϙʔωϯτͷ࡞Γํ• props͍ͭͷΑ͏ʹॻ͚·͢…import {createComponent, PropType, reactive} from '@vue/composition-api';const TodoForm = createComponent({props: {onSubmit: {type: Object as PropType<(text: string) => void>,required: true,},},});
ίϯϙʔωϯτͷ࡞Γํ• setupؔʹ৭ʑॻ͍͍ͯ͘…• reactive: Vue.observableͷ͜ͱ dataͷΑ͏ʹ͏͜ͱ͕ଟ͍͔• computed: ؔͷΑ͏ʹॻ͘setup(props) {const state = reactive({text: '',});const isValid = computed(() => state.text.length > 0);...
ίϯϙʔωϯτͷ࡞Γํ• setupؔʹ৭ʑॻ͍͍ͯ͘…• methods: ؔΛͦͷ··ఆٛ• propsprops.Ͱ͏• ࠷ޙʹreturnͰఆٛͨ͠ͷΛ ฦ͢setup(props) {...const submit = () => {props.onSubmit(state.text);state.text = '';};return {state,submit,isValid};}});
σϞ
ͪΐͬͱߴͳLogicͷ࠶ར༻
Logic Extraction and Reuse• ίϯϙʔωϯτͷछྨҧ͑Ͳɺڞ௨͍͍ͯͨ͠ ϩδοΫΛநग़ͯ͠࠶ར༻Ͱ͖Δɻ• ݱߦͷmixinͳͲͱಉ͡Α͏ͳ͜ͱ͕Ͱ͖Δ…https://vue-composition-api-rfc.netlify.com/#logic-extraction-and-reuse
HOW TO• Component͔Βɺ Stateͱɺmethods͚ͩΛ Ҿ͖ണ͕ͯؔ͠Ͱฦ͢• ref: reactiveͰՄม(mutable)ͳ dataimport {reactive, ref} from "@vue/composition-api";const useTodos = () => {const todos = ref([] as string[]);const addTodo = (todo: string) => {todos.value.push(todo);};const deleteTodo = (position: number) => {todos.value.splice(position, 1);};return {todos,addTodo,deleteTodo,};};export default useTodos;
HOW TO• ͍͍ͨComponentͰ ӈهͷΑ͏ʹ༻͢Δimport {createComponent, reactive} from '@vue/composition-api';import TodoList from '@/components/normal/TodoList.vue';import TodoForm from '@/components/normal/TodoForm.vue';import useTodos from './Store';const Todo = createComponent({components: {TodoList,TodoForm,},setup() {const {todos, deleteTodo, addTodo} = useTodos();return {todos,deleteTodo,addTodo,};},});
ΑΓߴͳ͜ͱ…
࣮ɺ• ͜ͷComposition APIΛ ͍͜ͳͤ ͳΜͪΌͬͯঢ়ଶཧ͕ Ͱ͖·͍ͭ͢͜Έ͍ͨͳͭͰ͢https://vuex.vuejs.org/ja/ ʹ͋ΔVu○xͷֆ
Ͳ͏Δͷ?• todosΛؔͷ֎ʹग़͢ -> 1ճ͚ͩੜ͞ΕΔ!import {reactive, ref} from "@vue/composition-api";const todos = ref([] as string[]);const useTodos = () => {const addTodo = (todo: string) => {todos.value.push(todo);};const deleteTodo = (position: number) => {todos.value.splice(position, 1);};return {todos,addTodo,deleteTodo,};};export default useTodos;
·ͱΊ• Composition APIܕਪͳͲͷվળΛਤͬͨ ͜Ε·ͰͱҰຯҧ͏ΦτφͷVue.js• ϩδοΫͷ࠶ར༻͕Ͱ͖ɺͳΜͪΌͬͯঢ়ଶཧ Ͱ͖ͪΌ͏!!• ϓϩμΫτʹ͏ͷ(·ͩ)࣌ظঘૣ?
Reference?• Vue-function-api rfc https://vue-composition-api-rfc.netlify.com• API Document https://vue-composition-api-rfc.netlify.com/api.html• GitHub https://github.com/vuejs/composition-api