├── src
├── store
│ ├── states.js
│ ├── getters.js
│ ├── mutations-types.js
│ ├── index.js
│ ├── mutations.js
│ └── actions.js
├── assets
│ └── logo.png
├── main.js
├── styles
│ └── reset.css
├── App.vue
└── components
│ ├── AppHeader.vue
│ ├── MemoApp.vue
│ ├── MemoForm.vue
│ └── Memo.vue
├── .babelrc
├── .travis.yml
├── .editorconfig
├── .gitignore
├── index.html
├── README.md
├── .eslintrc.js
├── package.json
└── webpack.config.js
/src/store/states.js:
--------------------------------------------------------------------------------
1 | export default {
2 | memos: [],
3 | editingId: 0
4 | };
5 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjpublic/memo-application/master/src/assets/logo.png
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", { "modules": false }],
4 | "stage-3"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "6"
4 | branches:
5 | only:
6 | - master
7 | script:
8 | - npm run build
9 |
--------------------------------------------------------------------------------
/src/store/getters.js:
--------------------------------------------------------------------------------
1 | export function getMemoCount (state) {
2 | return state.memos.length;
3 | }
4 |
5 | export default {
6 | getMemoCount
7 | };
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log
5 | yarn-error.log
6 |
7 | # Editor directories and files
8 | .idea
9 | *.suo
10 | *.ntvs*
11 | *.njsproj
12 | *.sln
13 | memo-db/
14 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from './App.vue';
3 | import store from './store';
4 |
5 | // eslint-disable-next-line no-new
6 | new Vue({
7 | el: '#app',
8 | store,
9 | render: h => h(App)
10 | });
11 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | memo-application
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/store/mutations-types.js:
--------------------------------------------------------------------------------
1 | export const FETCH_MEMOS = 'FETCH_MEMOS';
2 | export const ADD_MEMO = 'ADD_MEMO';
3 | export const DELETE_MEMO = 'DELETE_MEMO';
4 | export const EDIT_MEMO = 'EDIT_MEMO';
5 |
6 | export const SET_EDITING_ID = 'SET_EDITING_ID';
7 | export const RESET_EDITING_ID = 'RESET_EDITING_ID';
8 |
--------------------------------------------------------------------------------
/src/styles/reset.css:
--------------------------------------------------------------------------------
1 | @import "https://use.fontawesome.com/releases/v5.6.3/css/all.css";
2 |
3 | body {
4 | background-color: #f5f5f5;
5 | }
6 | html, body, div, input, fieldset, form, h1, p, textarea, button {
7 | margin: 0;
8 | padding: 0;
9 | border: 0;
10 | box-sizing: border-box;
11 | }
12 | textarea {
13 | border: none;
14 | resize: none;
15 | }
16 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 |
4 | import state from './states.js';
5 | import getters from './getters.js';
6 | import mutations from './mutations.js';
7 | import actions from './actions.js';
8 |
9 | Vue.use(Vuex);
10 |
11 | export default new Vuex.Store({
12 | state,
13 | getters,
14 | mutations,
15 | actions
16 | });
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # memo-application
2 |
3 | > A Vue.js project
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm run dev
13 |
14 | # build for production with minification
15 | npm run build
16 | ```
17 |
18 | For detailed explanation on how things work, consult the [docs for vue-loader](http://vuejs.github.io/vue-loader).
19 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
20 |
21 |
29 |
--------------------------------------------------------------------------------
/src/components/AppHeader.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
19 |
20 |
40 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // https://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parserOptions: {
6 | parser: 'babel-eslint'
7 | },
8 | env: {
9 | browser: true,
10 | },
11 | extends: [
12 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
13 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
14 | 'plugin:vue/essential',
15 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md
16 | 'standard'
17 | ],
18 | // required to lint *.vue files
19 | plugins: [
20 | 'vue'
21 | ],
22 | // add your custom rules here
23 | rules: {
24 | // allow async-await
25 | 'generator-star-spacing': 'off',
26 | 'semi': [
27 | 'error',
28 | 'always'
29 | ],
30 | // allow debugger during development
31 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/store/mutations.js:
--------------------------------------------------------------------------------
1 | import {
2 | FETCH_MEMOS,
3 | ADD_MEMO,
4 | DELETE_MEMO,
5 | EDIT_MEMO,
6 | SET_EDITING_ID,
7 | RESET_EDITING_ID
8 | } from './mutations-types';
9 |
10 | export default {
11 | [FETCH_MEMOS] (state, payload) {
12 | state.memos = payload;
13 | },
14 | [ADD_MEMO] (state, payload) {
15 | state.memos.push(payload);
16 | },
17 | [DELETE_MEMO] (state, id) {
18 | // this.memos를 state.memos로 변경해줘야한다.
19 | const targetIndex = state.memos.findIndex(v => v.id === id);
20 | state.memos.splice(targetIndex, 1);
21 | },
22 | [EDIT_MEMO] (state, payload) {
23 | const { id, content } = payload;
24 | const targetIndex = state.memos.findIndex(v => v.id === id);
25 | const targetMemo = state.memos[targetIndex];
26 | state.memos.splice(targetIndex, 1, { ...targetMemo, content });
27 | },
28 | [SET_EDITING_ID] (state, id) {
29 | state.editingId = id;
30 | },
31 | [RESET_EDITING_ID] (state) {
32 | state.editingId = 0;
33 | }
34 | };
35 |
--------------------------------------------------------------------------------
/src/store/actions.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import {
3 | FETCH_MEMOS,
4 | ADD_MEMO,
5 | DELETE_MEMO,
6 | EDIT_MEMO
7 | } from './mutations-types';
8 |
9 | const memoAPICore = axios.create({
10 | baseURL: 'http://localhost:8000/api/memos'
11 | });
12 |
13 | export function fetchMemos ({ commit }) {
14 | memoAPICore.get('/')
15 | .then(res => {
16 | commit(FETCH_MEMOS, res.data);
17 | });
18 | }
19 |
20 | export function addMemo ({ commit }, payload) {
21 | memoAPICore.post('/', payload)
22 | .then(res => {
23 | // 3. ADD_MEMO 변이를 호출하고 API를 통해 받아온 메모 데이터를 넘겨준다.
24 | commit(ADD_MEMO, res.data);
25 | });
26 | }
27 |
28 | export function deleteMemo ({ commit }, id) {
29 | memoAPICore.delete(`/${id}`)
30 | .then(() => {
31 | commit(DELETE_MEMO, id);
32 | });
33 | }
34 |
35 | export function updateMemo ({ commit }, payload) {
36 | const { id, content } = payload;
37 | memoAPICore.put(`/${id}`, { content })
38 | .then(() => {
39 | commit(EDIT_MEMO, payload);
40 | });
41 | }
42 |
43 | export default {
44 | fetchMemos,
45 | addMemo,
46 | deleteMemo,
47 | updateMemo
48 | };
49 |
--------------------------------------------------------------------------------
/src/components/MemoApp.vue:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
52 |
53 |
59 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "memo-application",
3 | "description": "A Vue.js project",
4 | "version": "1.0.0",
5 | "author": "martinyounghoonkim ",
6 | "license": "MIT",
7 | "private": true,
8 | "scripts": {
9 | "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
10 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules",
11 | "dpd:create": "dpd create memo-db",
12 | "dpd:up": "cd memo-db && dpd -d"
13 | },
14 | "dependencies": {
15 | "axios": "^0.18.0",
16 | "vue": "^2.5.11",
17 | "vuex": "^3.1.0"
18 | },
19 | "browserslist": [
20 | "> 1%",
21 | "last 2 versions",
22 | "not ie <= 8"
23 | ],
24 | "devDependencies": {
25 | "babel-core": "^6.26.0",
26 | "babel-loader": "^7.1.2",
27 | "babel-preset-env": "^1.6.0",
28 | "babel-preset-stage-3": "^6.24.1",
29 | "cross-env": "^5.0.5",
30 | "css-loader": "^0.28.7",
31 | "eslint": "^4.15.0",
32 | "babel-eslint": "^8.2.1",
33 | "eslint-config-standard": "^10.2.1",
34 | "eslint-friendly-formatter": "^3.0.0",
35 | "eslint-loader": "^1.7.1",
36 | "eslint-plugin-import": "^2.7.0",
37 | "eslint-plugin-node": "^5.2.0",
38 | "eslint-plugin-promise": "^3.4.0",
39 | "eslint-plugin-standard": "^3.0.1",
40 | "eslint-plugin-vue": "^4.0.0",
41 | "file-loader": "^1.1.4",
42 | "vue-loader": "^13.0.5",
43 | "vue-template-compiler": "^2.4.4",
44 | "webpack": "^3.6.0",
45 | "webpack-dev-server": "^2.9.1"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var webpack = require('webpack')
3 |
4 | module.exports = {
5 | entry: './src/main.js',
6 | output: {
7 | path: path.resolve(__dirname, './dist'),
8 | publicPath: '/dist/',
9 | filename: 'build.js'
10 | },
11 | module: {
12 | rules: [
13 | {
14 | test: /\.(js|vue)$/,
15 | loader: 'eslint-loader',
16 | enforce: 'pre',
17 | include: [path.resolve('src'), path.resolve('test')],
18 | options: {
19 | formatter: require('eslint-friendly-formatter'),
20 | emitWarning: true,
21 | }
22 | },
23 | {
24 | test: /\.css$/,
25 | use: [
26 | 'vue-style-loader',
27 | 'css-loader'
28 | ],
29 | },
30 | {
31 | test: /\.vue$/,
32 | loader: 'vue-loader',
33 | options: {
34 | loaders: {
35 | }
36 | // other vue-loader options go here
37 | }
38 | },
39 | {
40 | test: /\.js$/,
41 | loader: 'babel-loader',
42 | exclude: /node_modules/
43 | },
44 | {
45 | test: /\.(png|jpg|gif|svg)$/,
46 | loader: 'file-loader',
47 | options: {
48 | name: '[name].[ext]?[hash]'
49 | }
50 | }
51 | ]
52 | },
53 | resolve: {
54 | alias: {
55 | 'vue$': 'vue/dist/vue.esm.js'
56 | },
57 | extensions: ['*', '.js', '.vue', '.json']
58 | },
59 | devServer: {
60 | historyApiFallback: true,
61 | noInfo: true,
62 | overlay: true
63 | },
64 | performance: {
65 | hints: false
66 | },
67 | devtool: '#eval-source-map'
68 | }
69 |
70 | if (process.env.NODE_ENV === 'production') {
71 | module.exports.devtool = '#source-map'
72 | // http://vue-loader.vuejs.org/en/workflow/production.html
73 | module.exports.plugins = (module.exports.plugins || []).concat([
74 | new webpack.DefinePlugin({
75 | 'process.env': {
76 | NODE_ENV: '"production"'
77 | }
78 | }),
79 | new webpack.optimize.UglifyJsPlugin({
80 | sourceMap: true,
81 | compress: {
82 | warnings: false
83 | }
84 | }),
85 | new webpack.LoaderOptionsPlugin({
86 | minimize: true
87 | })
88 | ])
89 | }
90 |
--------------------------------------------------------------------------------
/src/components/MemoForm.vue:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
49 |
50 |
96 |
--------------------------------------------------------------------------------
/src/components/Memo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ memo.title }}
4 |
5 | {{ memo.content }}
6 |
12 |
13 |
16 |
17 |
18 |
19 |
62 |
63 |
109 |
--------------------------------------------------------------------------------