ã¯ããã« ç®æš åææ¡ä»¶ éåœ¢äœæ APIã¢ãã¯äœæ Vuexå°å
¥ ã³ã³ããŒãã³ãäœæ ã¢ã€ãã è¿œå æ©èœäœæ ãããã« ã¯ããã« ããã«ã¡ã¯ãæ°åïŒå¹Žç®ã®rksmskã§ããæ¬èšäºã¯Vue.jsãåŠã³å§ããã°ããã§å®éã«æãåãããŠç°¡åãªã¢ããªã±ãŒã·ã§ã³ãäœæããŠã¿ããæ¹ã®ããã®ãã³ãºãªã³ ãã¥ãŒããªã¢ã« ãšãªã£ãŠãããŸãã æ¯éæãåãããªããæ¬èšäºããèªã¿ãã ããããªããæ¬èšäºã¯Vue3ã§ã³ãŒããèšè¿°ããŠããŸããVue.jsã¯Vue2ãšVue3ã§èšè¿°æ¹æ³ã倧ããç°ãªãããããçæãã ããã ç®æš Vue.jsã䜿ã£ãŠTodoListã®è¡šç€ºãšè¿œå ãåºæ¥ãç°¡åãªTodoListã¢ããªã±ãŒã·ã§ã³ãäœããããã«ãªãããšã åææ¡ä»¶ Node.jsãã€ã³ã¹ããŒã«ãããŠããããš(Node.jsã®èª¬æãã€ã³ã¹ããŒã«æ¹æ³ã«ã€ããŠã¯ä»¥äžã®èšäºã«è©³ããèšèŒãããŠããŸã) éåœ¢äœæ ãŸããVueã®ç°å¢ãäœæããŠé圢ã®ç»é¢ã衚瀺ããŸãã TodoListäœæ¥çš ãã£ã¬ã¯ã ãªãäœæããŸãã ããããã¯ã¿ãŒããã«äžã§äœæ¥ãè¡ããŸããTodoListäœæ¥çš ãã£ã¬ã¯ã ãªäžã§ã¿ãŒããã«ãã npm install -g @vue/cli@next ãå®è¡ããVueãã€ã³ã¹ããŒã«ããŸã(ã€ã³ã¹ããŒã«ãäžæããããªãå Žåã«ã¯Node.jsã®ããŒãžã§ã³çãã確èªãã ãã)ã vue create todo-list ãå®è¡ããVueã®ç°å¢ãäœæããŸãããã®éã«Vueã®ããŒãžã§ã³ã確èªãããã®ã§ãVue3ãéžæããŸããããã±ãŒãžãããŒãžã£ã¯npmãéžæããŸãã ç°å¢äœæãå®äºããŸãããã cd todo-list ãå®è¡ããŠVueã®ç°å¢ã«ç§»ã£ãåŸã npm run serve ãå®è¡ããŠããŒã«ã«ã®ãã¹ããµãŒããèµ·åããŸãã ç«ã¡äžãã£ããµãŒãã«ãã©ãŠã¶ããã¢ã¯ã»ã¹ããŸããåºæ¬çã«ã¯ http://localhost:8080/ ã«ãµãŒããç«ã¡äžãããŸãã äžèšã®ãããªé圢ã®ç»é¢ã衚瀺ãããããšã確èªããŸãã é圢ç»é¢ ããã§é圢ç»é¢ã®äœæãå®äºããŸããã API ã¢ãã¯äœæ ç¶ããŠãTodoListã®ã¢ã€ãã ãäœæããŸããä»å㯠JSON Serverã䜿çšã㊠API ã¢ãã¯ãäœæããäœæãã API ã¢ãã¯ãéããŠã¢ã€ãã ã® CRUD (CreateãReadãUpdateãDelete)æäœãè¡ããŸãã ããããã¯ã¿ãŒããã«äžã§äœæ¥ãè¡ããŸãã npm i json-server ãå®è¡ãã json -serverãã€ã³ã¹ããŒã«ããŸãã mkdir webapi ãå®è¡ã *1 ãwebapi ãã£ã¬ã¯ã ãªãäœæããŸãã cd ./webapi ãå®è¡ããåŸã touch db.json ãå®è¡ã *2 ãdb. json ãã¡ã€ã«ãäœæããŸãã db. json ãã¡ã€ã«ã«ä»¥äžãèšå
¥ããŸãã { " todos ": [ { " id ": 1 , " text ": " åã ", " categoryId ": 1 } , { " id ": 2 , " text ": " å¯ã ", " categoryId ": 1 } , { " id ": 3 , " text ": " èµ·ãã ", " categoryId ": 2 } ] , " categories ": [ { " id ": 1 , " title ": " ããããš " } , { " id ": 2 , " title ": " ãã£ãããš " } ] } webapiäžã§ npx json-server --watch db.json ãå®è¡ãã API ã¢ãã¯ãµãŒããŒãèµ·åããŸãã ç«ã¡äžãã£ããµãŒãã«ã¢ã¯ã»ã¹ããŸããåºæ¬çã«ã¯ http://localhost:3000/ ã«ãµãŒããç«ã¡äžãããŸãã äžèšã®ãã㪠JSON Serverã®èµ·åç»é¢ã衚瀺ãããããšã確èªããŸãã JSON Serverèµ·åç»é¢ ããã§ API ã¢ãã¯ã®èµ·åãå®äºããŸããã Vuexå°å
¥ ãããŸã§ã§ãé圢ç»é¢ã®äœæãš API ã¢ãã¯ã®èµ·åãå®äºããŸãããã§ãã®ã§ããããã㯠API ã¢ãã¯ãéããŠTodoListãååŸããé圢ç»é¢ã«è¡šç€ºããããšãè¡ããŸãããã®éã«ãåŸã
ç¶æ
管çãè¡ãäžã§äŸ¿å©ã«ãªããããVuexãå°å
¥ããããšæããŸããVuexã¯å
±æç¶æ
ã®ç®¡çãè¡ãã©ã€ãã©ãªã§ãç°ãªã ã³ã³ããŒãã³ã éã§åäžã®ããŒã¿ãå
±æããéã«éå®ããŸãã ããããã¯ã¿ãŒããã«äžã§äœæ¥ãè¡ããŸããçŸåšã® ãã£ã¬ã¯ã ãªãtodo-listã«å€æŽããåŸã npm install vuex@next --save ãå®è¡ããVuexã©ã€ãã©ãªãã€ã³ã¹ããŒã«ããŸãã cd ./src ãå®è¡ããåŸã mkdir store ãå®è¡ããtodo-list/src ãã£ã¬ã¯ã ãªäžã«store ãã£ã¬ã¯ã ãªãäœæããŸãã touch store.js ãå®è¡ããstore.jsãã¡ã€ã«ãäœæããŸããæ¬ãã¡ã€ã«ãVuexã§å
±æç¶æ
ã管çããã³ãŒããèšè¿°ãããã¡ã€ã«ãšãªããŸãã store.jsã以äžã®ããã«æžãæããŸãã import { createStore } from "vuex" ; export default createStore( { state() { return { categoryList: [] , cardList: [] } } , mutations: { setCategoryList(state, categoryList) { state.categoryList = categoryList; } , setCardList(state, cardList) { state.cardList = cardList; } } , actions: { async fetchCategoryList(context) { const categoryList = await fetchItems( "http://localhost:3000/categories" ); context.commit( "setCategoryList" , categoryList); } , async fetchCardList(context) { const cardList = await fetchItems( "http://localhost:3000/todos" ); context.commit( "setCardList" , cardList); } , } } ); actionsã«èšèŒãããŠããfetchXXXã¡ãœããã§ã¯ API ããæ
å ±ãååŸããååŸããæ
å ±ãåŒæ°ã«mutationsã®ã¡ãœãããåŒã³åºããŠããŸããmutationsã§ã¯stateã®å€æŽãè¡ã£ãŠããŸãã ããã§æ³šæãããããšãšããŠãmutationsã§ã¯éåæåŠçãè¡ããªãããšãactionsã§ã¯stateã®æŽæ°ãçŽæ¥è¡ããªãããšã§ãããããã®æ³šæç¹ã®è©³ãã説æã¯ä»¥äžã®èšäºã«è©³ããèšèŒãããŠããããããã¡ãã䜵ããŠã芧ãã ããã Vuexã®èšå®ãã¢ããªã±ãŒã·ã§ã³ã«åæ ããããããmain.jsãã¡ã€ã«ã以äžã®ããã«æžãæããŸãã import { createApp } from 'vue' import Store from './store/store.js' ; import App from './App.vue' createApp(App).use(Store).mount( '#app' ) ããã§Vuexã§TodoListã®ç¶æ
管çãããä»çµã¿ãåºæ¥ããããåŸã¯ API ããããŒã¿ãååŸããfetchXXXã¡ãœãããäœæããé圢ç»é¢ã«è¡šç€ºãããŸãã çŸåšã® ãã£ã¬ã¯ã ãªãtodo-listã«å€æŽããåŸã mkdir utils ãå®è¡ããtodo-listäžã«utils ãã£ã¬ã¯ã ãªãäœæããŸãã *3 cd ./utils ãå®è¡ããåŸã touch http.js ãå®è¡ããtodo-list/utils ãã£ã¬ã¯ã ãªäžã«http.jsãã¡ã€ã«ãäœæããŸãã http.jsã以äžã®ããã«æžãæããŸãã export const fetchItems = async (url) => { try { // APIéä¿¡ã§ããŒã¿ãååŸãã const response = await fetch(url); // ååŸããããŒã¿ãjson圢åŒã§è¿ã return await response.json(); } catch (error) { // APIéä¿¡ã§ããŒã¿ãäžæãååŸã§ããªãã£ãå Žåãã³ã³ãœãŒã«ã«ãšã©ãŒã衚瀺 console.error( "ããŒã¿ãååŸåºæ¥ãŸããã§ãã" ); console.error(error); } } ; store.jsã«http.jsãã€ã³ããŒããããããstore.jsã®äºè¡ç®ã«ä»¥äžã远å ããŸãã import { fetchItems } from "../../utils/http" ; App.vueã以äžã®ããã«æžãæããŸãã <template> <div> ã«ãŒãäžèŠ§ïŒ {{ cardList }} <br /> ã«ããŽãªäžèŠ§ïŒ {{ categoryList }} </div> </template> <script> import { computed, onMounted } from "vue" ; import { useStore } from "vuex" ; export default { name: "App" , components: {} , setup() { // Vuexã䜿ãèšå® const store = useStore(); // ã³ã³ããŒãã³ããããŠã³ããããæã«categoryListãšcardListãAPIããååŸ onMounted(store.dispatch( "fetchCategoryList" )); onMounted(store.dispatch( "fetchCardList" )); return { cardList: computed(() => store.state.cardList), categoryList: computed(() => store.state.categoryList) } ; } } ; </script> <style></style> äžèšã®èšæ³ã¯åäžãã¡ã€ã« ã³ã³ããŒãã³ã ãšåŒã°ããèšè¿°æ¹æ³ã§ã templateã¿ã°å
ã«ç»é¢ã«è¡šç€ºããHTMLãèšè¿°ããã scriptã¿ã°å
ã«ããŒã¿ã®å®çŸ©ãåŠçãèšè¿°ããã styleã¿ã°å
ã« css ã§ã¹ã¿ã€ã«ãèšè¿°ããã ãšãã£ãããã«HTMLã JavaScript ã CSS ã®åŠçããŸãšããŠäžã€ã®ãã¡ã€ã«ã«èšè¿°ããããšãåºæ¥ãŸããããã«ãããäžã€äžã€ã® ã³ã³ããŒãã³ã ã®ä¿å®ããæããªã£ãŠããŸãã ããŒã«ã«ã®ãã¹ããµãŒããåèµ·åããäžèšã®ãããªããŒã¿ãç»é¢ã«è¡šç€ºãããããšã確èªããŸãã ã«ãŒãäžèЧïŒ[ { "id": 1, "text": "åã", "categoryId": 1 }, { "id": 2, "text": "å¯ã", "categoryId": 1 }, { "id": 3, "text": "èµ·ãã", "categoryId": 2 } ] ã«ããŽãªäžèЧïŒ[ { "id": 1, "title": "ããããš" }, { "id": 2, "title": "ãã£ãããš" } ] ããã§TodoListã®è¡šç€ºãå®äºããŸããã ã³ã³ããŒãã³ã äœæ ãããŸã§ã§TodoListã®è¡šç€ºã¯åºæ¥ãŸããããçŸç¶ã¯ããŒã¿ããã®ãŸãŸè¡šç€ºãããŠããã ãã§ãéåžžã«èŠã¥ããã§ãã ã§ãã®ã§ãããããã¯TodoListãã«ãŒã圢åŒã§è¡šç€ºããããã«å€æŽããŠãããããšæããŸãããã®éã«ãVueã«åãã£ãŠããäžã€äžã€ã®éšåã ã³ã³ããŒãã³ã ãšããŠåãåºãããšã§ç®¡çãæãããæ©èœãå©çšããŸãã ä»åã® ã³ã³ããŒãã³ã ã¯ä»¥äžã®ããã«ããŒãããªã¹ããã«ãŒãã§åå²ãè¡ããŸãã ã³ã³ããŒãã³ã åå²äŸ componentsäžã®HelloWorld.vueãåé€ããŸãã componentsäžã«Board.vueãList.vueãCard.vueãäœæããŸãã App.vueã以äžã®ããã«æžãæããŸãã <template> <div> <board></board> </div> </template> <script> import Board from "./components/Board.vue" ; export default { name: "App" , components: { Board } } ; </script> <style></style> å°ãã ãVue2ãšVue3ã®éãã説æãããšãVue2ã§ã¯å€ã¯dataããããã£ã«ã颿°ã¯methodsã«ãšãã£ãããã«ããããã£æ¯ã«åœ¹å²ãåããŠããŸããããVue3ã§ã¯æ°ãã远å ãããComposition API ã®æ©èœã«ãã£ãŠsetup颿°ã«ãããã®åŠçããŸãšããŠèšè¿°ããããšãåºæ¥ãŸãã ãã®setup颿°å
ã§ã¯Vuexã§å®çŸ©ããactionså
ã®ã¡ãœãããstore.dispatch("ã¡ãœããå")ã«ãã£ãŠåŒã³åºããŸãããã®çµæãVuexã®cardListãšcategoryListã®ç¶æ
ãå€åããããããã®ç¶æ
å€åãcomputed颿°ã«ãã£ãŠæ€ç¥ããããŒã¿ã®åæ ãè¡ã£ãŠããŸãã Board.vueã以äžã®ããã«æžãæããŸãã <template> <div class = "board-style" > <list v- for = "category in categoryList" :key= "category.id" :category= "category" ></list> </div> </template> <script> import { computed, onMounted } from "vue" ; import { useStore } from "vuex" ; import List from "./List.vue" ; export default { components: { List } , setup() { const store = useStore(); onMounted(store.dispatch( "fetchCategoryList" )); return { categoryList: computed(() => store.state.categoryList) } ; } } ; </script> <style scoped> .board-style { display: flex; gap: 10px; } </style> Board.vueã§ã¯v-forãã£ã¬ã¯ãã£ãã«ãã£ãŠã«ããŽãªæ¯ã«List ã³ã³ããŒãã³ã ãçæããŠããŸãããã®éã«List ã³ã³ããŒãã³ã ã«ã¯ã«ããŽãªã®æ
å ±ãæž¡ããŠããŸãã List.vueã以äžã®ããã«æžãæããŸãã <template> <div class = "list-style" > {{ category.title }} <card v- for = "card in cardList" :key= "card.id" :card= "card" ></card> </div> </template> <script> import { computed, onMounted } from "vue" ; import { useStore } from "vuex" ; import Card from "./Card.vue" ; export default { components: { Card } , props: { category: Object } , setup(props) { const store = useStore(); onMounted(store.dispatch( "fetchCardList" )); const cardList = computed(() => store.state.cardList.filter(card => card.categoryId === props.category.id) ); return { cardList, } ; } } ; </script> <style scoped> .list-style { display: inline-flex; flex-direction: column; text-align: center; background-color: silver; min-width: 200px; min-height: 400px; } </style> List ã³ã³ããŒãã³ã ã¯Board ã³ã³ããŒãã³ã ããæž¡ã£ãŠããã«ããŽãªã®æ
å ±ãããšã«ãã«ããŽãªIDãšäžèŽããã«ãŒããArrayãªããžã§ã¯ãã®æšæºã©ã€ãã©ãªã§ããfilterãçšããŠæœåºããv-forãã£ã¬ã¯ãã£ãã«ãã£ãŠæœåºããã«ãŒãæ¯ã«Card ã³ã³ããŒãã³ã ãçæããŠããŸãã Card.vueã以äžã®ããã«æžãæããŸãã <template> <div class = "card-style" > {{ card.text }} </div> </template> <script> export default { props: { card: Object , } } ; </script> <style scoped> .card-style { display: flex; flex-direction: column; background-color: yellowgreen; margin: 10px; height: 10vh; align-items: center; justify-content: center; border-radius: 10px; } </style> Card ã³ã³ããŒãã³ã ã¯List ã³ã³ããŒãã³ã ããæž¡ã£ãŠããã«ãŒãã®ããã¹ãã衚瀺ããŠããŸãã ããŒã«ã«ã®ãã¹ããµãŒããåèµ·åããäžèšã®ãããªå®æç»é¢ã衚瀺ãããããšã確èªããŸãã 宿ç»é¢ ããã§ã ã³ã³ããŒãã³ã åå²ãå®äºããTodoListãèŠããããªããŸããã ã¢ã€ãã è¿œå æ©èœäœæ çŸç¶ãã¢ã€ãã ã®è¿œå ã¯webapiäžã®db. json ããšãã£ã¿çã§çŽæ¥æžãæããããPOSTã¡ãœããã§HttpRequestãéãå¿
èŠããããå°ã
æéãããããŸãã ããã§ã空ã®ã«ãŒããçšæãããã®ã«ãŒãã«ããã¹ããå
¥åããŠè¿œå ãã¿ã³ãæŒãããæ°ããã«ãŒãã远å ãããããã«ããŠå©äŸ¿æ§ãäžããããšæããŸãã http.jsã以äžã®ããã«æžãæããŸãã export const fetchItems = async (url) => { try { // APIéä¿¡ã§ããŒã¿ãååŸãã const response = await fetch(url); // ååŸããããŒã¿ãjson圢åŒã§è¿ã return await response.json(); } catch (error) { // APIéä¿¡ã§ããŒã¿ãäžæãååŸã§ããªãã£ãå Žåãã³ã³ãœãŒã«ã«ãšã©ãŒã衚瀺 console.error("ããŒã¿ãååŸåºæ¥ãŸããã§ãã"); console.error(error); } }; +export const insertItems = async (url, data) => { + const response = await fetch(url, { + // json圢åŒã§POSTã§ããŒã¿ãéã + method: 'POST', + headers: { + 'Content-Type': 'application/json;charset=utf-8' + }, + body: JSON.stringify(data) + }).catch(() => { + // äžæããããªãã£ãå Žåãã³ã³ãœãŒã«ã«ãšã©ãŒã衚瀺 + console.error(response.json()) + return; + }) +}; store.jsã以äžã®ããã«æžãæããŸãã import { createStore } from "vuex"; -import { fetchItems } from "../../utils/http"; +import { fetchItems, insertItems } from "../../utils/http"; export default createStore({ state() { return { categoryList: [], cardList: [] } }, mutations: { setCategoryList(state, categoryList) { state.categoryList = categoryList; }, setCardList(state, cardList) { state.cardList = cardList; }, }, actions: { async fetchCategoryList(context) { const categoryList = await fetchItems("http://localhost:3000/categories"); context.commit("setCategoryList", categoryList); }, async fetchCardList(context) { const cardList = await fetchItems("http://localhost:3000/todos"); context.commit("setCardList", cardList); }, + async addCard(context, data) { + await insertItems("http://localhost:3000/todos", data); + } } }); List.vueã以äžã®ããã«æžãæããŸãã <template> <div class="list-style"> {{ category.title }} - <card v-for="card in cardList" :key="card.id" :card="card"></card> + <card + v-for="card in cardList" + :key="card.id" + :card="card" + :isNew="false" + ></card> + <card :card="newCard" :isNew="true"></card> </div> </template> <script> import { computed, onMounted } from "vue"; import { useStore } from "vuex"; import Card from "./Card.vue"; export default { components: { Card }, props: { category: Object }, setup(props) { const store = useStore(); onMounted(store.dispatch("fetchCardList")); const cardList = computed(() => store.state.cardList.filter(card => card.categoryId === props.category.id) ); + const newCard = { + id: -1, + text: "", + categoryId: props.category.id + }; return { cardList, + newCard }; } }; </script> <style scoped> .list-style { display: inline-flex; flex-direction: column; text-align: center; background-color: silver; min-width: 200px; min-height: 400px; } </style> List ã³ã³ããŒãã³ã ã§ã¯ãæ°ãã远å ããã«ãŒãã®é圢ãªããžã§ã¯ãã§ããnewCardãå®çŸ©ããCard ã³ã³ããŒãã³ã ã«æž¡ããŠããŸãããŸããCard ã³ã³ããŒãã³ã ã«ã¯å¯Ÿè±¡ã®ã«ãŒããæ°ãã远å ããã«ãŒããªã®ãåŠããèå¥ã§ããããã«booleanåã®å€æ°isNewãæž¡ããŠããŸãã Card.vueã以äžã®ããã«æžãæããŸãã <template> <div class="card-style"> + <input type="text" v-if="isNew" v-model="text" /> + <button @click="addCard" v-if="isNew">远å </button> + <span v-else> {{ card.text }} + </span> </div> </template> <script> +import { ref } from "@vue/reactivity"; +import { useStore } from "vuex"; export default { props: { card: Object, + isNew: Boolean + }, + setup(props) { + const store = useStore(); + let text = ref(""); + const addCard = async () => { + const data = { + text: text.value, + categoryId: props.card.categoryId + }; + await store.dispatch("addCard", data); + await store.dispatch("fetchCardList"); + text.value = ""; + }; + return { + text, + addCard + }; } }; </script> <style scoped> .card-style { display: flex; flex-direction: column; background-color: yellowgreen; margin: 10px; height: 10vh; align-items: center; justify-content: center; border-radius: 10px; } </style> Card ã³ã³ããŒãã³ã ã®templateã¿ã°å
ã§ã¯ãisNewãTrueã®å Žåã«ã远å ããã¿ã³ã衚瀺ãããããã«ããŠããŸãã scriptã¿ã°å
ã§ã¯ãã远å ããã¿ã³ãæŒãããå Žåã«addCardã¡ãœãããå®è¡ããåŠçãèšè¿°ããŠããŸããaddCardã¡ãœããã§ã¯ã«ãŒãã®æ
å ±ãdataãªããžã§ã¯ãã«æ ŒçŽããVuexã®actionsãdisptach颿°ã«ãã£ãŠåŒã³åºããŠããŸãã ãªããdataãªããžã§ã¯ãã®idããããã£ã«ã€ããŠã¯ã json -serverã§ã¯èªåã§å²ãæ¯ãããããã«ãªã£ãŠãããã远å ããŠããŸããã ããŒã«ã«ã®ãã¹ããµãŒããåèµ·åããäžèšã®ããã«æ°ããã«ãŒãã®è¿œå ãåºæ¥ãããšã確èªããŸãã *4 ã«ãŒã远å å ã«ãŒã远å åŸ ããã§ãã«ãŒãã®è¿œå æ©èœã宿ããŸããã ãããã« ä»åã¯Vue.jsã䜿ã£ãTodoList ãã¥ãŒããªã¢ã« ã玹ä»ããŸãããæ¬èšäºã§ã¯TodoListã®è¡šç€ºãšã¢ã€ãã ã®è¿œå ãšããåºæ¬æ©èœã ãã§ãããããã®ä»ã«ã ã«ãŒãã®æŽæ°ãå逿©èœ ã«ããŽãªè¿œå æ©èœ ã«ãŒãã API ãéããŠèªã¿èŸŒãŸãããŸã§ã®éã®ããŒãç»é¢ ã«ãŒãç§»åæ©èœ( ãã©ãã°&ãããã å¯èœã ãšããè¯ããšæããŸã) ã¿ã€ãã«ã®è²å€æŽæ©èœ ãã¶ã€ã³å€æŽ(Vuetifyçã® ãããªã¢ã«ãã¶ã€ã³ ãã¬ãŒã ã¯ãŒã¯ ãå©çšããã ãã§ããªããã«ãªããŸã) çã
æ§ã
ãªæ¡åŒµãå¯èœã ãšæãã®ã§ãæ¯éæ¡åŒµããŠã¿ãŠãã ããã ãšã³ãžã㢠äžéæ¡çš ãµã€ã ã©ã¯ ã¹ã§ã¯ããšã³ãžãã¢ã»ãã¶ã€ããŒã® äžéæ¡çš ãç©æ¥µçã«è¡ã£ãŠãããŸãïŒ ãèå³ãããŸãããæ¯éã確èªããé¡ãããŸãã https://career-recruit.rakus.co.jp/career_engineer/ ã«ãžã¥ã¢ã«é¢è«ãç³èŸŒã¿ãã©ãŒã ã©ã®è·çš®ã«å¿åããã°è¯ããããããªããšããæ¹ã¯ãã«ãžã¥ã¢ã«é¢è«ãéæè¡ã£ãŠãããŸãã 以äžãã©ãŒã ãããç³èŸŒã¿ãã ããã rakus.hubspotpagebuilder.com ã©ã¯ ã¹Developersç»é²ãã©ãŒã https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/ ã€ãã³ãæ
å ± äŒç€Ÿã®é°å²æ°ãç¥ãããæ¹ã¯ãæ¯é±éå¬ããŠããã€ãã³ãã«ãåå ãã ããïŒ âTECH PLAY techplay.jp âconnpass rakus.connpass.com *1 : ãã£ã¬ã¯ã ãªãäœæåºæ¥ãã°mkdirã³ãã³ãã§ãªããŠãåé¡ãããŸããã *2 : ãã¡ã€ã«ãäœæåºæ¥ãã°touchã³ãã³ãã§ãªããŠãåé¡ãããŸããã *3 : API éä¿¡ã®ãããªæ±çšçã«äœ¿ãããã¡ãœããã¯utils ãã£ã¬ã¯ã ãªäžã«é
眮ããããšãå€ãã§ãã *4 : Board.vueã«ã¯å€æŽã¯ãããŸããã