├── .babelrc ├── .eslintrc.js ├── .gitignore ├── README.md ├── build ├── karma.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── package.json ├── server.js ├── src ├── App.vue ├── assets │ └── logo.png ├── components │ ├── Feed.vue │ ├── Project.vue │ ├── ProjectList.vue │ ├── ProjectNew.vue │ ├── ProjectView.vue │ ├── SideNav.vue │ └── TopNav.vue ├── global.styl ├── index.html ├── main.js └── variables.styl └── test └── unit ├── Hello.spec.js └── index.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"], 3 | "plugins": ["transform-runtime"], 4 | "comments": false 5 | } 6 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | var production = process.env.NODE_ENV === 'production' 2 | 3 | module.exports = { 4 | 'root': true, 5 | 6 | 'env': { 7 | 'browser': true, 8 | 'node': true 9 | }, 10 | 11 | 'ecmaFeatures': { 12 | 'arrowFunctions': true, 13 | 'destructuring': true, 14 | 'classes': true, 15 | 'defaultParams': true, 16 | 'blockBindings': true, 17 | 'modules': true, 18 | 'objectLiteralComputedProperties': true, 19 | 'objectLiteralShorthandMethods': true, 20 | 'objectLiteralShorthandProperties': true, 21 | 'restParams': true, 22 | 'spread': true, 23 | 'forOf': true, 24 | 'generators': true, 25 | 'templateStrings': true, 26 | 'superInFunctions': true, 27 | 'experimentalObjectRestSpread': true 28 | }, 29 | 30 | 'rules': { 31 | 'accessor-pairs': 2, 32 | 'array-bracket-spacing': 0, 33 | 'block-scoped-var': 0, 34 | 'brace-style': [2, '1tbs', { 'allowSingleLine': true }], 35 | 'camelcase': 0, 36 | 'comma-dangle': [2, 'never'], 37 | 'comma-spacing': [2, { 'before': false, 'after': true }], 38 | 'comma-style': [2, 'last'], 39 | 'complexity': 0, 40 | 'computed-property-spacing': 0, 41 | 'consistent-return': 0, 42 | 'consistent-this': 0, 43 | 'constructor-super': 2, 44 | 'curly': [2, 'multi-line'], 45 | 'default-case': 0, 46 | 'dot-location': [2, 'property'], 47 | 'dot-notation': 0, 48 | 'eol-last': 2, 49 | 'eqeqeq': [2, 'allow-null'], 50 | 'func-names': 0, 51 | 'func-style': 0, 52 | 'generator-star-spacing': [2, { 'before': true, 'after': true }], 53 | 'guard-for-in': 0, 54 | 'handle-callback-err': [2, '^(err|error)$' ], 55 | 'indent': [2, 2, { 'SwitchCase': 1 }], 56 | 'key-spacing': [2, { 'beforeColon': false, 'afterColon': true }], 57 | 'linebreak-style': 0, 58 | 'lines-around-comment': 0, 59 | 'max-nested-callbacks': 0, 60 | 'new-cap': [2, { 'newIsCap': true, 'capIsNew': false }], 61 | 'new-parens': 2, 62 | 'newline-after-var': 0, 63 | 'no-alert': 0, 64 | 'no-array-constructor': 2, 65 | 'no-caller': 2, 66 | 'no-catch-shadow': 0, 67 | 'no-cond-assign': 2, 68 | 'no-console': 0, 69 | 'no-constant-condition': 0, 70 | 'no-continue': 0, 71 | 'no-control-regex': 2, 72 | 'no-debugger': production ? 2 : 0, 73 | 'no-delete-var': 2, 74 | 'no-div-regex': 0, 75 | 'no-dupe-args': 2, 76 | 'no-dupe-keys': 2, 77 | 'no-duplicate-case': 2, 78 | 'no-else-return': 0, 79 | 'no-empty': 0, 80 | 'no-empty-character-class': 2, 81 | 'no-empty-label': 2, 82 | 'no-eq-null': 0, 83 | 'no-eval': 2, 84 | 'no-ex-assign': 2, 85 | 'no-extend-native': 2, 86 | 'no-extra-bind': 2, 87 | 'no-extra-boolean-cast': 2, 88 | 'no-extra-parens': 0, 89 | 'no-extra-semi': 0, 90 | 'no-fallthrough': 2, 91 | 'no-floating-decimal': 2, 92 | 'no-func-assign': 2, 93 | 'no-implied-eval': 2, 94 | 'no-inline-comments': 0, 95 | 'no-inner-declarations': [2, 'functions'], 96 | 'no-invalid-regexp': 2, 97 | 'no-irregular-whitespace': 2, 98 | 'no-iterator': 2, 99 | 'no-label-var': 2, 100 | 'no-labels': 2, 101 | 'no-lone-blocks': 2, 102 | 'no-lonely-if': 0, 103 | 'no-loop-func': 0, 104 | 'no-mixed-requires': 0, 105 | 'no-mixed-spaces-and-tabs': 2, 106 | 'no-multi-spaces': 2, 107 | 'no-multi-str': 2, 108 | 'no-multiple-empty-lines': [2, { 'max': 1 }], 109 | 'no-native-reassign': 2, 110 | 'no-negated-in-lhs': 2, 111 | 'no-nested-ternary': 0, 112 | 'no-new': 2, 113 | 'no-new-func': 0, 114 | 'no-new-object': 2, 115 | 'no-new-require': 2, 116 | 'no-new-wrappers': 2, 117 | 'no-obj-calls': 2, 118 | 'no-octal': 2, 119 | 'no-octal-escape': 2, 120 | 'no-param-reassign': 0, 121 | 'no-path-concat': 0, 122 | 'no-process-env': 0, 123 | 'no-process-exit': 0, 124 | 'no-proto': 0, 125 | 'no-redeclare': 2, 126 | 'no-regex-spaces': 2, 127 | 'no-restricted-modules': 0, 128 | 'no-return-assign': 2, 129 | 'no-script-url': 0, 130 | 'no-self-compare': 2, 131 | 'no-sequences': 2, 132 | 'no-shadow': 0, 133 | 'no-shadow-restricted-names': 2, 134 | 'no-spaced-func': 2, 135 | 'no-sparse-arrays': 2, 136 | 'no-sync': 0, 137 | 'no-ternary': 0, 138 | 'no-this-before-super': 2, 139 | 'no-throw-literal': 2, 140 | 'no-trailing-spaces': 2, 141 | 'no-undef': 2, 142 | 'no-undef-init': 2, 143 | 'no-undefined': 0, 144 | 'no-underscore-dangle': 0, 145 | 'no-unexpected-multiline': 2, 146 | 'no-unneeded-ternary': 2, 147 | 'no-unreachable': 2, 148 | 'no-unused-expressions': 0, 149 | 'no-unused-vars': [2, { 'vars': 'all', 'args': 'none' }], 150 | 'no-use-before-define': 0, 151 | 'no-var': 0, 152 | 'no-void': 0, 153 | 'no-warning-comments': 0, 154 | 'no-with': 2, 155 | 'object-curly-spacing': 0, 156 | 'object-shorthand': 0, 157 | 'one-var': [2, { 'initialized': 'never' }], 158 | 'operator-assignment': 0, 159 | 'operator-linebreak': [2, 'after', { 'overrides': { '?': 'before', ':': 'before' } }], 160 | 'padded-blocks': 0, 161 | 'prefer-const': 0, 162 | 'quote-props': 0, 163 | 'quotes': [2, 'single', 'avoid-escape'], 164 | 'radix': 2, 165 | 'semi': [2, 'never'], 166 | 'semi-spacing': 0, 167 | 'sort-vars': 0, 168 | 'space-after-keywords': [2, 'always'], 169 | 'space-before-blocks': [2, 'always'], 170 | 'space-before-function-paren': [2, 'always'], 171 | 'space-in-parens': [2, 'never'], 172 | 'space-infix-ops': 2, 173 | 'space-return-throw-case': 2, 174 | 'space-unary-ops': [2, { 'words': true, 'nonwords': false }], 175 | 'spaced-comment': [2, 'always', { 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!'] }], 176 | 'strict': 0, 177 | 'use-isnan': 2, 178 | 'valid-jsdoc': 0, 179 | 'valid-typeof': 2, 180 | 'vars-on-top': 0, 181 | 'wrap-iife': [2, 'any'], 182 | 'wrap-regex': 0, 183 | 'yoda': [2, 'never'] 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | rethinkdb_data/ 6 | vuedb/ 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue RethinkDB Example 2 | 3 | Vue + Express + RethinkDB 4 | 5 | ## Installation 6 | 7 | ``` bash 8 | # Install RethinkDB 9 | 10 | http://rethinkdb.com/docs/install/ 11 | 12 | # Install dependencies 13 | npm install 14 | ``` 15 | 16 | ## Usage 17 | 18 | ```bash 19 | # Run RethinkDB 20 | rethinkdb 21 | 22 | # Run app 23 | npm run dev 24 | ``` 25 | -------------------------------------------------------------------------------- /build/karma.conf.js: -------------------------------------------------------------------------------- 1 | var webpackConf = require('./webpack.base.conf') 2 | delete webpackConf.entry 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | browsers: ['PhantomJS'], 7 | frameworks: ['jasmine'], 8 | reporters: ['spec'], 9 | files: ['../test/unit/index.js'], 10 | preprocessors: { 11 | '../test/unit/index.js': ['webpack'] 12 | }, 13 | webpack: webpackConf, 14 | webpackMiddleware: { 15 | noInfo: true 16 | } 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | 3 | module.exports = { 4 | entry: { 5 | app: './src/main.js' 6 | }, 7 | output: { 8 | path: path.resolve(__dirname, '../dist/static'), 9 | publicPath: '/static/', 10 | filename: '[name].js' 11 | }, 12 | resolve: { 13 | extensions: ['', '.js', '.vue', 'styl'], 14 | alias: { 15 | 'src': path.resolve(__dirname, '../src') 16 | } 17 | }, 18 | resolveLoader: { 19 | root: path.join(__dirname, 'node_modules') 20 | }, 21 | module: { 22 | loaders: [ 23 | { 24 | test: /\.vue$/, 25 | loader: 'vue' 26 | }, 27 | { 28 | test: /\.js$/, 29 | loader: 'babel!eslint', 30 | exclude: /node_modules/ 31 | }, 32 | { 33 | test: /\.json$/, 34 | loader: 'json' 35 | }, 36 | { 37 | test: /\.(png|jpg|gif|svg)$/, 38 | loader: 'url', 39 | query: { 40 | limit: 10000, 41 | name: '[name].[ext]?[hash:7]' 42 | } 43 | }, 44 | { 45 | test: /\.styl$/, loader: 'style-loader!css-loader!stylus-loader' 46 | }, 47 | 48 | { test: /bootstrap\/js\//, loader: 'imports?jQuery=jquery' }, 49 | { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&minetype=application/font-woff" }, 50 | { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" } 51 | ] 52 | }, 53 | vue: { 54 | loaders: { 55 | js: 'babel!eslint' 56 | } 57 | }, 58 | eslint: { 59 | formatter: require('eslint-friendly-formatter') 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack') 2 | var config = require('./webpack.base.conf') 3 | var HtmlWebpackPlugin = require('html-webpack-plugin') 4 | 5 | // eval-source-map is faster for development 6 | config.devtool = 'eval-source-map' 7 | 8 | // add hot-reload related code to entry chunks 9 | var polyfill = 'eventsource-polyfill' 10 | var hotClient = 'webpack-hot-middleware/client?noInfo=true&reload=true' 11 | Object.keys(config.entry).forEach(function (name, i) { 12 | var extras = i === 0 ? [polyfill, hotClient] : [hotClient] 13 | config.entry[name] = extras.concat(config.entry[name]) 14 | }) 15 | 16 | // necessary for the html plugin to work properly 17 | // when serving the html from in-memory 18 | config.output.publicPath = '/' 19 | 20 | config.plugins = (config.plugins || []).concat([ 21 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 22 | new webpack.optimize.OccurenceOrderPlugin(), 23 | new webpack.HotModuleReplacementPlugin(), 24 | new webpack.NoErrorsPlugin(), 25 | // https://github.com/ampedandwired/html-webpack-plugin 26 | new HtmlWebpackPlugin({ 27 | filename: 'index.html', 28 | template: 'src/index.html' 29 | }) 30 | ]) 31 | 32 | module.exports = config 33 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack') 2 | var config = require('./webpack.base.conf') 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | var HtmlWebpackPlugin = require('html-webpack-plugin') 5 | 6 | // naming output files with hashes for better caching. 7 | // dist/index.html will be auto-generated with correct URLs. 8 | config.output.filename = '[name].[chunkhash].js' 9 | config.output.chunkFilename = '[id].[chunkhash].js' 10 | 11 | // whether to generate source map for production files. 12 | // disabling this can speed up the build. 13 | var SOURCE_MAP = true 14 | 15 | config.devtool = SOURCE_MAP ? 'source-map' : false 16 | 17 | // generate loader string to be used with extract text plugin 18 | function generateExtractLoaders (loaders) { 19 | return loaders.map(function (loader) { 20 | return loader + '-loader' + (SOURCE_MAP ? '?sourceMap' : '') 21 | }).join('!') 22 | } 23 | 24 | config.vue.loaders = { 25 | js: 'babel!eslint', 26 | // http://vuejs.github.io/vue-loader/configurations/extract-css.html 27 | css: ExtractTextPlugin.extract('vue-style-loader', generateExtractLoaders(['css'])), 28 | less: ExtractTextPlugin.extract('vue-style-loader', generateExtractLoaders(['css', 'less'])), 29 | sass: ExtractTextPlugin.extract('vue-style-loader', generateExtractLoaders(['css', 'sass'])), 30 | stylus: ExtractTextPlugin.extract('vue-style-loader', generateExtractLoaders(['css', 'stylus'])) 31 | } 32 | 33 | config.plugins = (config.plugins || []).concat([ 34 | // http://vuejs.github.io/vue-loader/workflow/production.html 35 | new webpack.DefinePlugin({ 36 | 'process.env': { 37 | NODE_ENV: '"production"' 38 | } 39 | }), 40 | new webpack.optimize.UglifyJsPlugin({ 41 | compress: { 42 | warnings: false 43 | } 44 | }), 45 | new webpack.optimize.OccurenceOrderPlugin(), 46 | // extract css into its own file 47 | new ExtractTextPlugin('[name].[contenthash].css'), 48 | // generate dist index.html with correct asset hash for caching. 49 | // you can customize output by editing /build/index.template.html 50 | // see https://github.com/ampedandwired/html-webpack-plugin 51 | new HtmlWebpackPlugin({ 52 | filename: '../index.html', 53 | template: 'src/index.html' 54 | }) 55 | ]) 56 | 57 | module.exports = config 58 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-rethinkdb-example", 3 | "description": "Vue + Express + RethinkDB", 4 | "author": "Wei-ying Chen ", 5 | "private": true, 6 | "scripts": { 7 | "dev": "nodemon server.js", 8 | "build": "rimraf dist && webpack --progress --hide-modules --config build/webpack.prod.conf.js", 9 | "test": "karma start build/karma.conf.js --single-run" 10 | }, 11 | "dependencies": { 12 | "body-parser": "^1.15.0", 13 | "bootstrap": "^3.3.6", 14 | "font-awesome": "^4.5.0", 15 | "less": "^2.6.0", 16 | "lodash": "^4.2.1", 17 | "rethinkdb": "^2.2.1", 18 | "rethinkdbdash": "^2.2.18", 19 | "stylus": "^0.53.0", 20 | "vue": "^1.0.15", 21 | "vue-resource": "^0.7.0", 22 | "vue-router": "^0.7.10" 23 | }, 24 | "devDependencies": { 25 | "babel-core": "^6.0.0", 26 | "babel-loader": "^6.0.0", 27 | "babel-plugin-transform-runtime": "^6.0.0", 28 | "babel-preset-es2015": "^6.0.0", 29 | "babel-preset-stage-2": "^6.0.0", 30 | "babel-runtime": "^5.8.0", 31 | "bootstrap-webpack": "0.0.5", 32 | "connect-history-api-fallback": "^1.1.0", 33 | "css-loader": "^0.23.0", 34 | "eslint": "^1.10.3", 35 | "eslint-friendly-formatter": "^1.2.2", 36 | "eslint-loader": "^1.2.0", 37 | "eventsource-polyfill": "^0.9.6", 38 | "exports-loader": "^0.6.2", 39 | "express": "^4.13.3", 40 | "extract-text-webpack-plugin": "^0.9.1", 41 | "file-loader": "^0.8.4", 42 | "font-awesome-webpack": "0.0.4", 43 | "function-bind": "^1.0.2", 44 | "html-webpack-plugin": "^1.7.0", 45 | "imports-loader": "^0.6.5", 46 | "inject-loader": "^2.0.1", 47 | "jasmine-core": "^2.4.1", 48 | "json-loader": "^0.5.4", 49 | "karma": "^0.13.15", 50 | "karma-jasmine": "^0.3.6", 51 | "karma-phantomjs-launcher": "^0.2.1", 52 | "karma-spec-reporter": "0.0.23", 53 | "karma-webpack": "^1.7.0", 54 | "less-loader": "^2.2.2", 55 | "phantomjs": "^1.9.19", 56 | "rimraf": "^2.5.0", 57 | "style-loader": "^0.13.0", 58 | "stylus-loader": "^1.5.1", 59 | "url-loader": "^0.5.7", 60 | "vue-hot-reload-api": "^1.2.0", 61 | "vue-html-loader": "^1.0.0", 62 | "vue-loader": "^8.0.0", 63 | "vue-style-loader": "^1.0.0", 64 | "webpack": "^1.12.2", 65 | "webpack-dev-middleware": "^1.4.0", 66 | "webpack-hot-middleware": "^2.6.0" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const r = require('rethinkdbdash')() 3 | const bodyParser = require('body-parser') 4 | const webpack = require('webpack') 5 | const config = require('./build/webpack.dev.conf') 6 | const _ = require('lodash') 7 | 8 | const app = express() 9 | const router = express.Router() 10 | const compiler = webpack(config) 11 | const jsonParser = bodyParser.json() 12 | 13 | // handle fallback for HTML5 history API 14 | app.use(require('connect-history-api-fallback')()) 15 | 16 | // serve webpack bundle output 17 | app.use(require('webpack-dev-middleware')(compiler, { 18 | publicPath: config.output.publicPath, 19 | stats: { 20 | colors: true, 21 | chunks: false 22 | } 23 | })) 24 | 25 | // enable hot-reload and state-preserving 26 | // compilation error display 27 | app.use(require('webpack-hot-middleware')(compiler)) 28 | 29 | router.get('/projects', (req, res) => { 30 | r.table("projects").orderBy('createdAt').run().then(result => { 31 | res.send(result) 32 | }).catch(err => { 33 | console.log("Error:", err) 34 | }) 35 | }) 36 | 37 | router.post('/projects', jsonParser, (req, res) => { 38 | const project = { 39 | 'title': req.body.title, 40 | 'content': req.body.content, 41 | 'createdAt': new Date().toJSON() 42 | } 43 | r.table('projects').insert(project).run().then(result => { 44 | res.send(result) 45 | }).catch(err => { 46 | console.log('Error:', err) 47 | }) 48 | }) 49 | 50 | router.get('/projects/:id', (req, res) => { 51 | r.table('projects').get(req.params.id).run().then(result => { 52 | res.send(result) 53 | }).catch(err => { 54 | console.log('Error:', err) 55 | }) 56 | }) 57 | 58 | router.get('/projects/:id/feeds', (req, res) => { 59 | r.table('feeds').filter({projectId: req.params.id}).orderBy('createdAt').run().then(result => { 60 | res.send(result) 61 | }).catch(err => { 62 | console.log('Error:', err) 63 | }) 64 | }) 65 | 66 | router.get('/feeds', (req, res) => { 67 | r.table("feeds").orderBy('createdAt').run().then(result => { 68 | res.send(result) 69 | }).catch(err => { 70 | console.log("Error:", err) 71 | res.send(result) 72 | }) 73 | }) 74 | 75 | router.post('/feeds', jsonParser, (req, res) => { 76 | const feed = { 77 | 'content': req.body.content, 78 | 'createdAt': new Date().toJSON(), 79 | 'projectId': req.body.projectId 80 | } 81 | r.table('feeds').insert(feed).run().then(result => { 82 | res.send(result) 83 | }).catch(err => { 84 | console.log('Error:', err) 85 | }) 86 | }) 87 | 88 | app.use('/api', router) 89 | 90 | app.listen(8090, 'localhost', function (err) { 91 | if (err) { 92 | console.log(err) 93 | return 94 | } 95 | console.log('Listening at http://localhost:8090') 96 | }) 97 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 22 | 23 | 26 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weiying-chen/vue-rethinkdb-example/06a7ab81c4c8c1795f63223ea5d09b11067fa679/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/Feed.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | -------------------------------------------------------------------------------- /src/components/Project.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | -------------------------------------------------------------------------------- /src/components/ProjectList.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 42 | -------------------------------------------------------------------------------- /src/components/ProjectNew.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 50 | -------------------------------------------------------------------------------- /src/components/ProjectView.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 73 | -------------------------------------------------------------------------------- /src/components/SideNav.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 27 | 28 | 46 | -------------------------------------------------------------------------------- /src/components/TopNav.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 53 | -------------------------------------------------------------------------------- /src/global.styl: -------------------------------------------------------------------------------- 1 | @import '../node_modules/bootstrap/dist/css/bootstrap.css' 2 | @import '../node_modules/font-awesome/css/font-awesome.css' 3 | @import './variables.styl' 4 | @import url(https://fonts.googleapis.com/css?family=Roboto:400,700,400italic) 5 | @import url(https://fonts.googleapis.com/css?family=Signika:400,300) 6 | 7 | /* Tags */ 8 | 9 | body { 10 | color: $text-color 11 | background: #eee 12 | font-family: 'Roboto', sans-serif 13 | font-size: 14px 14 | } 15 | 16 | a { 17 | color: $link-color 18 | } 19 | 20 | h1, 21 | h2, 22 | h3, 23 | h4 { 24 | font-family: 'Signika', sans-serif 25 | } 26 | 27 | input[type="text"], textarea { 28 | outline: none 29 | box-shadow: none !important 30 | } 31 | 32 | /* Classes */ 33 | 34 | .page-header { 35 | margin-top: 0 36 | border-color: $border-color 37 | color: #aaa 38 | } 39 | 40 | .btn { 41 | font-family: 'Signika', sans-serif 42 | } 43 | 44 | .panel { 45 | border-color: $border-color 46 | -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, 0) 47 | box-shadow: 0 0 0 rgba(0, 0, 0, 0) 48 | h3 { 49 | margin-top: 0 50 | } 51 | .panel-body > h2 { 52 | margin-top: 0 53 | } 54 | } 55 | 56 | .input-group-addon { 57 | background-color: #fff 58 | border-color: $border-color 59 | border-top-width: 0 60 | border-bottom-width: 0 61 | border-right-width: 0 62 | border-radius: 0 63 | padding-right: 0 64 | } 65 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue RethinkDB Example{% for (var css in o.htmlWebpackPlugin.files.css) { %} 6 | {% } %} 7 | 8 | 9 |
{% for (var chunk in o.htmlWebpackPlugin.files.chunks) { %} 10 | {% } %} 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import Resource from 'vue-resource' 4 | import App from './App' 5 | import ProjectNew from './components/ProjectNew' 6 | import ProjectList from './components/ProjectList' 7 | import ProjectView from './components/ProjectView' 8 | 9 | Vue.use(Router) 10 | Vue.use(Resource) 11 | 12 | const router = new Router() 13 | 14 | router.map({ 15 | '/projects/new': { 16 | component: ProjectNew 17 | }, 18 | 19 | '/projects': { 20 | component: ProjectList 21 | }, 22 | 23 | '/project/:id': { 24 | component: ProjectView 25 | } 26 | }) 27 | 28 | router.beforeEach(function () { 29 | window.scrollTo(0, 0) 30 | }) 31 | 32 | router.redirect({ 33 | '*': '/projects' 34 | }) 35 | 36 | router.start(App, '#app') 37 | -------------------------------------------------------------------------------- /src/variables.styl: -------------------------------------------------------------------------------- 1 | /* Variables */ 2 | 3 | $brand-color = #44caaf 4 | $link-color = #3ea3d7 5 | $text-color = #333 6 | $border-color = #e2e2e2 7 | -------------------------------------------------------------------------------- /test/unit/Hello.spec.js: -------------------------------------------------------------------------------- 1 | /* global describe, it, expect */ 2 | 3 | import Vue from 'vue' 4 | import Hello from 'src/components/Hello' 5 | 6 | describe('Hello.vue', () => { 7 | it('should render correct contents', () => { 8 | const vm = new Vue({ 9 | template: '
', 10 | components: { Hello } 11 | }).$mount() 12 | expect(vm.$el.querySelector('.hello h1').textContent).toBe('Hello World!') 13 | }) 14 | }) 15 | 16 | // also see example testing a component with mocks at 17 | // https://github.com/vuejs/vue-loader-example/blob/master/test/unit/a.spec.js#L24-L49 18 | -------------------------------------------------------------------------------- /test/unit/index.js: -------------------------------------------------------------------------------- 1 | // Polyfill fn.bind() for PhantomJS 2 | /* eslint-disable no-extend-native */ 3 | Function.prototype.bind = require('function-bind') 4 | 5 | // require all test files (files that ends with .spec.js) 6 | var testsContext = require.context('.', true, /\.spec$/) 7 | testsContext.keys().forEach(testsContext) 8 | --------------------------------------------------------------------------------