├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── LICENSE
├── README.md
├── components
├── App.vue
├── Editor.vue
├── NotesList.vue
└── Toolbar.vue
├── index.html
├── main.js
├── package.json
├── static
└── build.js
├── styles.css
├── vuex
├── actions.js
└── store.js
└── webpack.config.js
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
4 | extends: 'standard',
5 | // required to lint *.vue files
6 | plugins: [
7 | 'html'
8 | ],
9 | // add your custom rules here
10 | 'rules': {
11 | // allow paren-less arrow functions
12 | 'arrow-parens': 0,
13 | 'no-undef': 0,
14 | 'one-var': 0,
15 | // allow debugger during development
16 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18 | .grunt
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 |
23 | # Compiled binary addons (http://nodejs.org/api/addons.html)
24 | build/Release
25 |
26 | # Dependency directory
27 | node_modules
28 |
29 | # Optional npm cache directory
30 | .npm
31 |
32 | # Optional REPL history
33 | .node_repl_history
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 coligo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Firebase + Vuex 构建 Notes App
2 |
3 | 之前翻译了基于博客 [coligo](http://coligo.io/learn-vuex-by-building-notes-app/) 的文章:[用 Vuex 构建一个笔记应用](https://segmentfault.com/a/1190000005015164),这次在此基础上做了一点更新:
4 |
5 | * 把数据放在 Firebase 上,不会每次关掉浏览器就丢失数据
6 | * 添加了笔记检索功能
7 | * 为了保证代码整洁,加上了 eslint
8 | * more...
9 |
10 | 在运行之前,记得把 store.js 里面的数据引用改成你自己账号的链接。
11 |
12 | ```js
13 | // 改一下数据应用
14 | let notesRef = new Firebase('https://crackling-inferno-296.firebaseio.com/notes')
15 | ```
16 |
17 | ### Install the dependencies
18 |
19 | ```bash
20 | npm install
21 | ```
22 |
23 | ### Run the dev server with hot reload at localhost:8080
24 |
25 | ```bash
26 | npm run dev
27 | ```
28 |
29 | ### Build the app for production
30 |
31 | ```bash
32 | npm run build
33 | ```
34 |
--------------------------------------------------------------------------------
/components/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
22 |
--------------------------------------------------------------------------------
/components/Editor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
25 |
--------------------------------------------------------------------------------
/components/NotesList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
44 |
45 |
46 |
47 |
95 |
--------------------------------------------------------------------------------
/components/Toolbar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 |
27 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Notes | coligo.io
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import store from './vuex/store'
3 | import App from './components/App.vue'
4 |
5 | /* eslint-disable */
6 | new Vue({
7 | store, // inject store to all children
8 | el: 'body',
9 | components: { App }
10 | })
11 | /* eslint-disable */
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "note-app-vuejs-vuex",
3 | "version": "1.0.0",
4 | "description": "A notes application built using VueJs and Vuex",
5 | "main": "index.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "https://github.com/coligo-io/notes-app-vuejs-vuex.git"
9 | },
10 | "scripts": {
11 | "dev": "webpack-dev-server --inline --hot",
12 | "build": "webpack -p"
13 | },
14 | "keywords": [
15 | "vuejs",
16 | "vuex",
17 | "notes"
18 | ],
19 | "author": "Fady Makram",
20 | "license": "MIT",
21 | "devDependencies": {
22 | "babel-core": "^6.7.6",
23 | "babel-loader": "^6.2.4",
24 | "babel-plugin-transform-runtime": "^6.7.5",
25 | "babel-preset-es2015": "^6.6.0",
26 | "babel-runtime": "^5.8.38",
27 | "css-loader": "^0.23.1",
28 | "eslint": "^2.0.0",
29 | "eslint-config-standard": "^5.1.0",
30 | "eslint-friendly-formatter": "^1.2.2",
31 | "eslint-loader": "^1.3.0",
32 | "eslint-plugin-html": "^1.3.0",
33 | "eslint-plugin-promise": "^1.0.8",
34 | "eslint-plugin-standard": "^1.3.2",
35 | "vue-hot-reload-api": "^1.3.2",
36 | "vue-html-loader": "^1.2.2",
37 | "vue-loader": "^8.2.3",
38 | "vue-style-loader": "^1.0.0",
39 | "webpack": "^1.12.15",
40 | "webpack-dev-server": "^1.14.1"
41 | },
42 | "dependencies": {
43 | "vue": "^1.0.21",
44 | "vuex": "^0.6.2",
45 | "firebase": "^2.4.2"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/styles.css:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Raleway:400,300);
2 |
3 | html, #app {
4 | height: 100%;
5 | }
6 |
7 | body {
8 | margin: 0;
9 | padding: 0;
10 | border: 0;
11 | height: 100%;
12 | max-height: 100%;
13 | position: relative;
14 | }
15 |
16 | #toolbar {
17 | float: left;
18 | width: 80px;
19 | height: 100%;
20 | background-color: #30414D;
21 | color: #767676;
22 | padding: 35px 25px 25px 25px;
23 | }
24 |
25 | #notes-list {
26 | float: left;
27 | width: 300px;
28 | height: 100%;
29 | background-color: #F5F5F5;
30 | font-family: 'Raleway', sans-serif;
31 | font-weight: 400;
32 | }
33 |
34 | input {
35 | margin-bottom: 20px;
36 | width: 100%;
37 | border-radius: 4px;
38 | line-height: 25px;
39 | }
40 |
41 | #notes-list .input{
42 | width: 80%;
43 | margin: auto;
44 | text-align: center;
45 | }
46 |
47 | #list-header {
48 | padding: 5px 25px 25px 25px;
49 | }
50 |
51 | #list-header h2 {
52 | font-weight: 300;
53 | text-transform: uppercase;
54 | text-align: center;
55 | font-size: 22px;
56 | padding-bottom: 8px;
57 | }
58 |
59 | #notes-list .container {
60 | height: calc(100% - 137px);
61 | max-height: calc(100% - 137px);
62 | overflow: auto;
63 | width: 100%;
64 | padding: 0;
65 | }
66 |
67 | #notes-list .container .list-group-item {
68 | /*border: 0;*/
69 | border-radius: 0;
70 | }
71 |
72 | .list-group-item {
73 | border-bottom: 1px solid #d4d4d4;
74 | }
75 |
76 | .list-group-item-heading {
77 | font-weight: 300;
78 | font-size: 15px;
79 | }
80 |
81 | #note-editor {
82 | height: 100%;
83 | margin-left: 380px;
84 | }
85 |
86 | #note-editor textarea {
87 | height: 100%;
88 | border: 0;
89 | border-radius: 0;
90 | }
91 |
92 | #toolbar i {
93 | font-size: 30px;
94 | margin-bottom: 35px;
95 | cursor: pointer;
96 | opacity: 0.8;
97 | transition: opacity 0.5s ease;
98 | }
99 |
100 | #toolbar i:hover {
101 | opacity: 1;
102 | }
103 |
104 | .starred {
105 | color: #F7AE4F;
106 | }
107 |
--------------------------------------------------------------------------------
/vuex/actions.js:
--------------------------------------------------------------------------------
1 | export const addNote = ({ dispatch }) => {
2 | dispatch('ADD_NOTE')
3 | }
4 |
5 | export const editNote = ({ dispatch }, e) => {
6 | dispatch('EDIT_NOTE', e.target.value)
7 | }
8 |
9 | export const deleteNote = ({ dispatch }) => {
10 | dispatch('DELETE_NOTE')
11 | }
12 |
13 | export const updateActiveNote = ({ dispatch }, key, note) => {
14 | dispatch('SET_ACTIVE_NOTE', key, note)
15 | }
16 |
17 | export const toggleFavorite = ({ dispatch }) => {
18 | dispatch('TOGGLE_FAVORITE')
19 | }
20 |
--------------------------------------------------------------------------------
/vuex/store.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import Firebase from 'firebase'
4 |
5 | Vue.use(Vuex)
6 |
7 | let notesRef = new Firebase('https://crackling-inferno-296.firebaseio.com/notes')
8 |
9 | notesRef.on('value', snapshot => {
10 | state.notes = snapshot.val()
11 | })
12 |
13 | const state = {
14 | notes: {},
15 | activeNote: {},
16 | activeKey: ''
17 | }
18 |
19 | const mutations = {
20 | ADD_NOTE (state) {
21 | const newNote = {
22 | text: 'New note',
23 | favorite: false
24 | }
25 | var addRef = notesRef.push()
26 | state.activeKey = addRef.key()
27 | addRef.set(newNote)
28 | state.activeNote = newNote
29 | },
30 |
31 | EDIT_NOTE (state, text) {
32 | notesRef.child(state.activeKey).update({
33 | 'text': text
34 | })
35 | },
36 |
37 | DELETE_NOTE (state) {
38 | // notesRef.(state.activeNote)
39 | notesRef.child(state.activeKey).set(null)
40 | // state.activeNote = state.notes[0]
41 | },
42 |
43 | TOGGLE_FAVORITE (state) {
44 | state.activeNote.favorite = !state.activeNote.favorite
45 | notesRef.child(state.activeKey).update({
46 | 'favorite': state.activeNote.favorite
47 | })
48 | // state.activeNote.favorite = !state.activeNote.favorite
49 | },
50 |
51 | SET_ACTIVE_NOTE (state, key, note) {
52 | state.activeNote = note
53 | state.activeKey = key
54 | }
55 | }
56 |
57 | export default new Vuex.Store({
58 | state,
59 | mutations
60 | })
61 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | entry: './main.js',
3 | output: {
4 | path: './static',
5 | publicPath: '/static/',
6 | filename: 'build.js'
7 | },
8 | module: {
9 | preLoaders: [{
10 | test: /\.vue$/,
11 | loader: 'eslint'
12 | }, {
13 | test: /\.js$/,
14 | loader: 'eslint'
15 | }],
16 | loaders: [{
17 | test: /\.js$/,
18 | loader: 'babel',
19 | exclude: /node_modules/
20 | }, {
21 | test: /\.vue$/,
22 | loader: 'vue'
23 | }]
24 | },
25 | babel: {
26 | presets: ['es2015'],
27 | plugins: ['transform-runtime']
28 | },
29 | eslint: {
30 | formatter: require('eslint-friendly-formatter')
31 | },
32 | devtools: '#source-map'
33 | }
34 |
--------------------------------------------------------------------------------