Skip to content

Commit 5badee9

Browse files
authored
feat: todomvc (#103)
1 parent df61e66 commit 5badee9

File tree

18 files changed

+590
-0
lines changed

18 files changed

+590
-0
lines changed

todomvc/.autod.conf.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use strict';
2+
3+
module.exports = {
4+
write: true,
5+
prefix: '^',
6+
plugin: 'autod-egg',
7+
test: [
8+
'test',
9+
'benchmark',
10+
],
11+
dep: [
12+
'egg',
13+
'egg-scripts',
14+
],
15+
devdep: [
16+
'egg-ci',
17+
'egg-bin',
18+
'egg-mock',
19+
'autod',
20+
'autod-egg',
21+
'eslint',
22+
'eslint-config-egg',
23+
'webstorm-disable-index',
24+
],
25+
exclude: [
26+
'./test/fixtures',
27+
'./dist',
28+
],
29+
};
30+

todomvc/.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
coverage

todomvc/.eslintrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "eslint-config-egg"
3+
}

todomvc/.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
logs/
2+
npm-debug.log
3+
yarn-error.log
4+
node_modules/
5+
package-lock.json
6+
yarn.lock
7+
coverage/
8+
.idea/
9+
run/
10+
.DS_Store
11+
*.sw*
12+
*.un~
13+
typings/
14+
.nyc_output/

todomvc/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# TodoMVC powered by Egg
2+
3+
- [TodoMVC](http://todomvc.com/)
4+
- [Egg](egg)
5+
6+
![](./todomvc.png)
7+
8+
### QuickStart
9+
10+
```bash
11+
$ npm i
12+
$ npm run dev
13+
$ open http://localhost:7001/
14+
```
15+
16+
[egg]: https://eggjs.org

todomvc/app/controller/home.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
'use strict';
2+
3+
const { Controller } = require('egg');
4+
5+
class HomeController extends Controller {
6+
async index() {
7+
const { ctx } = this;
8+
await ctx.render('home.tpl');
9+
}
10+
}
11+
12+
module.exports = HomeController;

todomvc/app/controller/todo.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use strict';
2+
3+
const { Controller } = require('egg');
4+
5+
class TodoController extends Controller {
6+
// list todos, suport filter, `GET /api/todo?completed=true`
7+
async index() {
8+
const { ctx, service } = this;
9+
10+
// query value is string, should convert types.
11+
let { completed } = ctx.query;
12+
if (ctx.query.completed !== undefined) completed = completed === 'true';
13+
14+
ctx.status = 200;
15+
ctx.body = await service.todo.list({ completed });
16+
}
17+
18+
async create() {
19+
const { ctx, service } = this;
20+
21+
// params validate
22+
ctx.validate({ title: { type: 'string' } });
23+
24+
ctx.status = 201;
25+
ctx.body = await service.todo.create(ctx.request.body);
26+
}
27+
28+
async update() {
29+
const { ctx, service } = this;
30+
31+
ctx.validate({ title: { type: 'string' } });
32+
33+
ctx.status = 204;
34+
ctx.type = 'json';
35+
ctx.body = await service.todo.update(ctx.params.id, ctx.request.body);
36+
}
37+
38+
async destroy() {
39+
const { ctx, service } = this;
40+
const id = ctx.params.id;
41+
ctx.status = 204;
42+
ctx.type = 'json';
43+
await service.todo.destroy(id);
44+
}
45+
}
46+
47+
module.exports = TodoController;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'use strict';
2+
3+
module.exports = options => {
4+
return async function responseTime(ctx, next) {
5+
const start = Date.now();
6+
await next();
7+
const cost = Date.now() - start;
8+
ctx.set(options.headerKey, `${cost}ms`);
9+
};
10+
};

todomvc/app/public/main.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'use strict';
2+
/* global Vue:false, axios:false, Cookies: false */
3+
/* eslint object-shorthand: 0 */
4+
5+
axios.defaults.headers.common['x-csrf-token'] = Cookies.get('csrfToken');
6+
axios.defaults.headers.post['Content-Type'] = 'application/json';
7+
8+
new Vue({
9+
el: '#app',
10+
data: {
11+
todoList: [],
12+
newTodo: '',
13+
completed: 'all',
14+
},
15+
methods: {
16+
listData: function(completed) {
17+
// just for showcase, ignore error handler and loading tip
18+
axios.get('/api/todo', { params: { completed } })
19+
.then(res => {
20+
this.todoList = res.data;
21+
});
22+
},
23+
24+
addTodo: function() {
25+
const value = this.newTodo && this.newTodo.trim();
26+
if (!value) return;
27+
28+
const item = {
29+
title: value,
30+
completed: false,
31+
};
32+
33+
axios.post('/api/todo', item)
34+
.then(res => {
35+
this.todoList.push(res.data);
36+
this.newTodo = '';
37+
});
38+
},
39+
40+
completeTodo: function(todo) {
41+
todo.completed = !todo.completed;
42+
axios.put(`/api/todo/${todo.id}`, todo)
43+
.then(() => {
44+
this.newTodo = '';
45+
});
46+
},
47+
48+
removeTodo: function(todo) {
49+
axios.delete(`/api/todo/${todo.id}`)
50+
.then(() => {
51+
const index = this.todoList.findIndex(x => x.id === todo.id);
52+
this.todoList.splice(index, 1);
53+
});
54+
},
55+
},
56+
57+
mounted() {
58+
this.listData();
59+
},
60+
});

todomvc/app/router.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict';
2+
3+
/**
4+
* @param {Egg.Application} app - egg application
5+
*/
6+
module.exports = app => {
7+
const { router, controller } = app;
8+
9+
router.get('/', controller.home.index);
10+
router.resources('/api/todo', controller.todo);
11+
};

0 commit comments

Comments
 (0)