Building Environment
- express
- connect-api-mocker
- axios
- VueX
- Impliment Todo App
1. express
Hello world example
$ npm install express
▼
$ mkdir api
$ touch api/index.js
▼
$ vim api/index.js
▼
// api/index.js
const express = require('express')
const app = express()
const port = 8080
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
module.exports = {
path: '/api',
handler: app
}
▼
$ vim nuxt.config.js
▼
// nuxt.config.js
export default {
// ...
serverMiddleware: ['../api']
}
2. connect-api-mocker
Using with Express
$ npm install connect-api-mocker --save-dev
▼
$ vim api/index.js
▼
// api/index.js
const express = require('express')
const apiMocker = require('connect-api-mocker')
const app = express()
app.use('/api', apiMocker('mocks/api'))
app.listen(8080)
module.exports = {
path: '/api',
handler: app
}
▼
Endpoint not found on mock files:
Resolution
$ mkdir -p __mock__/api/messages
$ touch __mock__/api/messages/GET.json
▼
$ vim __mock__/api/messages/GET.json
▼
{ "message": "hello, api" }
▼
$ vim api/index.js
▼
// api/index.js
// ...
app.use('/api', apiMocker('mocks/api', '__mock__/api'))
3. axios
Setup
$ yarn add @nuxtjs/axios
▼
$ vim nuxt.config.js
▼
// nuxt.config.js
export default {
// ...
modules: ['@nuxtjs/axios']
}
Usage
$ vim pages/index.vue
▼
// pages/index.vue
export default {
// ...
async asyncData({ $axios }) {
const ip = await $axios.$get('/messages')
console.log(ip)
return { ip }
}
}
▼
Uncaught (in promise) Error: Request failed with status code 404
Resolution
$ vim nuxt.config.js
▼
// nuxt.config.js
export default {
// ...
axios: {
prefix: '/api',
proxy: true
},
proxy: {
'/api/': 'http://localhost:8080'
}
}
4. VueX
モジュール
$ mkdir store
$ touch store/todos.js
▼
$ vim store/todos.js
▼
// store/todos.js
export const state = () => ({
list: []
})
export const mutations = {
add(state, text) {
state.list.push({
text,
done: false
})
},
remove(state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
toggle(state, todo) {
todo.done = !todo.done
}
}
▼
$ touch pages/todos.vue
▼
$ vim pages/todos.vue
▼
// pages/todos.vue
<template>
<ul>
<li v-for="todo in todos" :key="todo.text">
<input :checked="todo.done" @change="toggle(todo)" type="checkbox">
<span :class="{ done: todo.done }">{{ todo.text }}</span>
</li>
<li><input @keyup.enter="addTodo" placeholder="What needs to be done?"></li>
</ul>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
computed: {
todos () {
return this.$store.state.todos.list
}
},
methods: {
addTodo (e) {
this.$store.commit('todos/add', e.target.value)
e.target.value = ''
},
...mapMutations({
toggle: 'todos/toggle'
})
}
}
</script>
<style>
.done {
text-decoration: line-through;
}
</style>
5. Impliment Todo App
$ mkdir __mock__/api/todos
$ touch __mock__/api/todos/GET.json
▼
$ vim __mock__/api/todos/GET.json
▼
{ "todos":
[
{
"text": "aaa",
"done": true
},
{
"text": "bbb",
"done": false
}
]
}
▼
$ vim store/todos.js
▼
export const state = () => ({
list: []
})
export const mutations = {
add(state, data) {
const list = Array.isArray(data) ? data : [{
text: data,
done: false
}]
list.forEach(data => {
state.list.push(data)
})
},
remove(state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
toggle(state, todo) {
todo.done = !todo.done
}
}
export const actions = {
async fetch({ commit }) {
const path = `/todos`
const { todos } = await this.$axios.$get(path)
commit('add', todos)
}
}
▼
$ vim pages/todos.vue
▼
<template>
<div>
<ul>
<li v-for="todo in todos" :key="todo.text">
<v-checkbox
v-model="checkedList"
:class="{ done: todo.done }"
:label="todo.text"
:value="todo.text"
@change="toggle(todo)"
></v-checkbox>
</li>
<li>
<v-text-field @keyup.enter="addTodo" placeholder="What needs to be done?"></v-text-field>
</li>
</ul>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
async fetch({ store, params }) {
await store.dispatch('todos/fetch')
},
created() {
this.todos.forEach(todo => {
if (todo.done) this.checkedList.push(todo.text)
})
},
data() {
return {
checkedList: []
}
},
computed: {
...mapState ({
todos: state => state.todos.list
})
},
methods: {
addTodo (e) {
this.add(e.target.value)
e.target.value = ''
},
...mapMutations({
toggle: 'todos/toggle',
add: 'todos/add'
})
}
}
</script>
<style>
.done label {
text-decoration: line-through;
}
</style>