diff --git a/build/vue.config.js b/build/vue.config.js
new file mode 100644
index 0000000..d09b52e
--- /dev/null
+++ b/build/vue.config.js
@@ -0,0 +1,12 @@
+var webpack = require('webpack');
+
+module.exports = {
+ configureWebpack: {
+ plugins: [
+ new webpack.ProvidePlugin({
+ 'window.Quill': 'quill/dist/quill.js',
+ 'Quill': 'quill/dist/quill.js'
+ }),
+ ]
+ }
+}
diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js
index 1f4f47e..1bec590 100644
--- a/build/webpack.base.conf.js
+++ b/build/webpack.base.conf.js
@@ -36,21 +36,33 @@ module.exports = {
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
- }
+ Views: resolve('src/views'),
+ Config: resolve('src/config'),
+ Components: resolve('src/components'),
+ Store: resolve('src/store'),
+ Router: resolve('src/router')
+ },
},
module: {
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
+ exclude: /node_modules(?!\/quill-image-drop-module|quill-image-resize-module)/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
+ exclude: /node_modules(?!\/quill-image-drop-module|quill-image-resize-module)/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
+ {
+ test: /\.scss$/,
+ loaders: ['style-loader', 'css-loader', 'sass-loader'],
+
+ },
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js
index 070ae22..53e6984 100755
--- a/build/webpack.dev.conf.js
+++ b/build/webpack.dev.conf.js
@@ -48,6 +48,10 @@ const devWebpackConfig = merge(baseWebpackConfig, {
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
+ new webpack.ProvidePlugin({
+ 'window.Quill': 'quill/dist/quill.js',
+ 'Quill': 'quill/dist/quill.js'
+ }),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js
index 2f17259..47f3401 100644
--- a/build/webpack.prod.conf.js
+++ b/build/webpack.prod.conf.js
@@ -43,12 +43,16 @@ const webpackConfig = merge(baseWebpackConfig, {
sourceMap: config.build.productionSourceMap,
parallel: true
}),
+ new webpack.ProvidePlugin({
+ 'window.Quill': 'quill/dist/quill.js',
+ 'Quill': 'quill/dist/quill.js'
+ }),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
- // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
+ // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true,
}),
diff --git a/config/index.js b/config/index.js
index 926ab36..0377f30 100644
--- a/config/index.js
+++ b/config/index.js
@@ -15,7 +15,7 @@ module.exports = {
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
- autoOpenBrowser: false,
+ autoOpenBrowser: true,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
diff --git a/package.json b/package.json
index 023fea3..8f0c4b1 100644
--- a/package.json
+++ b/package.json
@@ -14,8 +14,16 @@
"build": "node build/build.js"
},
"dependencies": {
+ "axios": "^0.18.0",
+ "js-md5": "^0.7.3",
+ "quill": "^1.3.6",
+ "quill-image-drop-module": "^1.0.3",
+ "quill-image-extend-module": "^1.1.2",
+ "quill-image-resize-module": "^3.0.0",
"vue": "^2.5.2",
- "vue-router": "^3.0.1"
+ "vue-quill-editor": "^3.0.6",
+ "vue-router": "^3.0.1",
+ "vuex": "^3.0.1"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
@@ -36,7 +44,7 @@
"chromedriver": "^2.27.2",
"copy-webpack-plugin": "^4.0.1",
"cross-spawn": "^5.0.1",
- "css-loader": "^0.28.0",
+ "css-loader": "^0.28.11",
"eslint": "^4.15.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
@@ -54,16 +62,20 @@
"jest-serializer-vue": "^0.3.0",
"nightwatch": "^0.9.12",
"node-notifier": "^5.1.2",
+ "node-sass": "^4.9.4",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
+ "quill-image-extend-module": "^1.1.2",
"rimraf": "^2.6.0",
+ "sass-loader": "^7.1.0",
"selenium-server": "^3.0.1",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
+ "style-loader": "^0.23.1",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
"vue-jest": "^1.0.2",
diff --git a/src/App.vue b/src/App.vue
index d74c648..e828af1 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,23 +1,18 @@
-

+
+
-
-
diff --git a/src/assets/css/reset.css b/src/assets/css/reset.css
new file mode 100644
index 0000000..87ad942
--- /dev/null
+++ b/src/assets/css/reset.css
@@ -0,0 +1,118 @@
+/**
+ * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
+ * http://cssreset.com
+ */
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video, input {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font-weight: normal;
+ vertical-align: baseline;
+}
+
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, menu, nav, section {
+ display: block;
+}
+
+body {
+ line-height: 1;
+}
+
+blockquote, q {
+ quotes: none;
+}
+
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: none;
+}
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+/* custom */
+a {
+ color: #7e8c8d;
+ text-decoration: none;
+ -webkit-backface-visibility: hidden;
+}
+
+li {
+ list-style: none;
+}
+
+::-webkit-scrollbar {
+ width: 5px;
+ height: 5px;
+}
+
+::-webkit-scrollbar-track-piece {
+ background-color: rgba(0, 0, 0, 0.2);
+ -webkit-border-radius: 6px;
+}
+
+::-webkit-scrollbar-thumb:vertical {
+ height: 5px;
+ background-color: rgba(125, 125, 125, 0.7);
+ -webkit-border-radius: 6px;
+}
+
+::-webkit-scrollbar-thumb:horizontal {
+ width: 5px;
+ background-color: rgba(125, 125, 125, 0.7);
+ -webkit-border-radius: 6px;
+}
+
+html, body {
+ width: 100%;
+}
+
+body {
+ -webkit-text-size-adjust: none;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+.w1200{
+ max-width: 1200px;
+}
+.center{
+ margin: 0 auto;
+}
+.float-left{
+ float: left;
+}
+.float-right{
+ float: right;
+}
+.hidden{
+ display: none;
+}
+.router-link-exact-active{
+ color: #00A7EB !important;
+}
+.clearbox:after,.clearbox:after{
+ content: "020";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+}
+.par20{
+ padding-right: 20px;
+}
diff --git a/src/assets/js/bus.js b/src/assets/js/bus.js
new file mode 100644
index 0000000..b0230b5
--- /dev/null
+++ b/src/assets/js/bus.js
@@ -0,0 +1,2 @@
+import Vue from 'vue'
+export default new Vue()
diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue
deleted file mode 100644
index 1c19f2a..0000000
--- a/src/components/HelloWorld.vue
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
{{ msg }}
-
Essential Links
-
-
Ecosystem
-
-
-
-
-
-
-
-
diff --git a/src/components/articleDetail/index.vue b/src/components/articleDetail/index.vue
new file mode 100644
index 0000000..1b26e8e
--- /dev/null
+++ b/src/components/articleDetail/index.vue
@@ -0,0 +1,66 @@
+
+
+
{{itemTitle}}
+
+
+ - 标签: {{tag.join('、')}}
+ - 时间: {{itemTime}}
+ - 阅读量: {{visitor}}
+
+
+
+
+
+
+
diff --git a/src/components/blogItem/index.vue b/src/components/blogItem/index.vue
new file mode 100644
index 0000000..a8157b0
--- /dev/null
+++ b/src/components/blogItem/index.vue
@@ -0,0 +1,95 @@
+
+
+
{{tag.join('|')}} {{itemTitle}}
+
+
+
{{itemTime}}
+
浏览量:({{visitor}})
+
查看全文>>
+
删除
+
修改
+
+
+
+
+
diff --git a/src/components/edit/index.vue b/src/components/edit/index.vue
new file mode 100644
index 0000000..ea49ef7
--- /dev/null
+++ b/src/components/edit/index.vue
@@ -0,0 +1,165 @@
+
+
+
+
+
diff --git a/src/components/pagination/index.vue b/src/components/pagination/index.vue
new file mode 100644
index 0000000..fb962bd
--- /dev/null
+++ b/src/components/pagination/index.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
diff --git a/src/components/quest-404.vue b/src/components/quest-404.vue
new file mode 100644
index 0000000..6ee08cb
--- /dev/null
+++ b/src/components/quest-404.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/src/components/success.vue b/src/components/success.vue
new file mode 100644
index 0000000..3db7768
--- /dev/null
+++ b/src/components/success.vue
@@ -0,0 +1,37 @@
+
+
+
文章发布成功
+
+ 返回首页返回上一页
+
+
+
+
+
+
diff --git a/src/components/titleBar.vue b/src/components/titleBar.vue
new file mode 100644
index 0000000..8b52e52
--- /dev/null
+++ b/src/components/titleBar.vue
@@ -0,0 +1,31 @@
+
+
+
{{title}}写博客
+
+
+
+
+
diff --git a/src/config/interceptors/index.js b/src/config/interceptors/index.js
new file mode 100644
index 0000000..9101dc7
--- /dev/null
+++ b/src/config/interceptors/index.js
@@ -0,0 +1,42 @@
+import axios from 'axios'
+import server from '../server'
+import utils from '../utils'
+import router from 'Router/index'
+
+const service = axios.create({
+ baseURI: server['base'],
+ timeout: 5000
+})
+service.interceptors.request.use(
+ config => {
+ if (utils.getStorage('token')) {
+ config.headers['X-Token'] = utils.getStorage('token')
+ config.headers['User-Type'] = utils.getStorage('userName')
+ }
+ return config
+ },
+ error => {
+ return Promise.reject(error)
+ }
+)
+
+service.interceptors.response.use(
+ response => {
+ return response
+ },
+ error => {
+ console.log(error)
+ if (error.response) {
+ switch (error.response.status) {
+ case 401:
+ case 403:
+ utils.removeItem('token')
+ router.replace('/admin/login')
+ }
+ }
+
+ return Promise.reject(error)
+ }
+)
+
+export default service
diff --git a/src/config/router.js b/src/config/router.js
new file mode 100644
index 0000000..3316fcd
--- /dev/null
+++ b/src/config/router.js
@@ -0,0 +1,8 @@
+let router = [
+ {title: '网站首页', path: '/index'},
+ {title: '关于我', path: '/aboutMe'},
+ {title: '留言', path: '/leaveMessage'},
+ {title: '最新技术', path: '/news'},
+ {title: '最近一些感想', path: '/mood'}
+]
+export default router
diff --git a/src/config/server.js b/src/config/server.js
new file mode 100644
index 0000000..02e94f6
--- /dev/null
+++ b/src/config/server.js
@@ -0,0 +1,13 @@
+let root = 'http://localhost:3000'
+export default {
+ 'visitor/article': `${root}/visitor/article`,
+ 'visitor/article/like': `${root}/visitor/article/like`,
+ 'user/article/delete': `${root}/user/article/delete`,
+ 'user/article/images': `${root}/user/article/images`,
+ 'images': `${root}/images/`,
+ 'user/article/add': `${root}/user/article/add`,
+ 'user/article/update': `${root}/user/article/update`,
+ 'visitor/article/detail': `${root}/visitor/article/detail`,
+ 'user/login': `${root}/user/login`,
+ 'base': root
+}
diff --git a/src/config/utils.js b/src/config/utils.js
new file mode 100644
index 0000000..c99384e
--- /dev/null
+++ b/src/config/utils.js
@@ -0,0 +1,45 @@
+
+export default {
+ throttle (fn, delay = 250) {
+ let last
+ let timer = null
+ return function () {
+ let context = this
+ let args = arguments
+ // console.log(this)
+ let now = +new Date()
+ if (last && now < last + delay) {
+ clearTimeout(timer)
+ timer = setTimeout(() => {
+ fn.apply(context, args)
+ }, delay)
+ } else {
+ last = now
+ fn.apply(context, args)
+ }
+ }
+ },
+ debounce (fn) {
+ let timer = null
+ return function () {
+ let context = this
+ let args = arguments
+ clearTimeout(timer)
+ timer = setTimeout(() => {
+ fn.apply(context, args)
+ }, 300)
+ }
+ },
+ setStorage (query) {
+ const storage = window.localStorage
+ for (let key in query) {
+ storage[key] = query[key]
+ }
+ },
+ getStorage (key) {
+ return window.localStorage.getItem(key)
+ },
+ removeItem (query) {
+ window.localStorage.removeItem(query)
+ }
+}
diff --git a/src/main.js b/src/main.js
index 417390e..1380b79 100644
--- a/src/main.js
+++ b/src/main.js
@@ -3,13 +3,25 @@
import Vue from 'vue'
import App from './App'
import router from './router'
+// import axios from 'axios'
+import VueQuillEditor from 'vue-quill-editor'
+import 'quill/dist/quill.core.css'
+import 'quill/dist/quill.snow.css'
+import 'quill/dist/quill.bubble.css'
+import store from 'Store/index'
+import axios from 'Config/interceptors/index'
+
+Vue.use(VueQuillEditor)
Vue.config.productionTip = false
+Vue.prototype.$http = axios
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
+ store,
+ axios,
components: { App },
template: ''
})
diff --git a/src/router/index.js b/src/router/index.js
index 5fa7f9d..c20a58e 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,15 +1,73 @@
import Vue from 'vue'
import Router from 'vue-router'
-import HelloWorld from '@/components/HelloWorld'
+// import HelloWorld from '@/components/HelloWorld'
+import Layout from 'Views/layout/index.vue'
+import AboutMe from 'Views/content/aboutMe/index.vue'
+import Admin from 'Views/content/admin/index.vue'
+import Edit from 'Components/edit'
+import ArticleDetail from 'Components/articleDetail'
+import Success from 'Components/success'
+import Login from 'Views/content/login/index.vue'
+import utils from 'Config/utils'
+import Quest404 from 'Components/quest-404'
Vue.use(Router)
-export default new Router({
+let router = new Router({
routes: [
{
path: '/',
- name: 'HelloWorld',
- component: HelloWorld
+ redirect: '/index'
+ },
+ {
+ path: '/index',
+ component: Layout
+ },
+ {
+ path: '/aboutMe',
+ component: AboutMe
+ },
+ {
+ path: '/admin',
+ meta: { requiresAuth: true },
+ component: Admin
+ },
+ {
+ path: '/admin/edit',
+ meta: { requiresAuth: true },
+ component: Edit
+ },
+ {
+ path: '/article/detail/:id',
+ component: ArticleDetail
+ },
+ {
+ path: '/article/success',
+ meta: { requiresAuth: true },
+ component: Success
+ },
+ {
+ path: '/admin/login',
+ component: Login
+ },
+ {
+ path: '*',
+ component: Quest404
}
]
})
+
+router.beforeEach((to, from, next) => {
+ if (to.matched.some(record => record.meta.requiresAuth)) {
+ let token = utils.getStorage('token')
+ if (token === null || token === '') {
+ next('/admin/login')
+ } else {
+ next()
+ }
+ } else {
+ next()
+ }
+})
+
+export default router
diff --git a/src/store/index.js b/src/store/index.js
new file mode 100644
index 0000000..005091e
--- /dev/null
+++ b/src/store/index.js
@@ -0,0 +1,22 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+Vue.use(Vuex)
+
+export default new Vuex.Store({
+ state: {
+ userName: '',
+ token: ''
+ },
+ actions: {
+ setStore ({commit, state}, data) {
+ commit('setStore', data)
+ }
+ },
+ mutations: {
+ setStore (state, data) {
+ state.userName = data.userName
+ state.token = data.token
+ }
+ },
+ getter: {}
+})
diff --git a/src/views/content/aboutMe/index.vue b/src/views/content/aboutMe/index.vue
new file mode 100644
index 0000000..d4d9b87
--- /dev/null
+++ b/src/views/content/aboutMe/index.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/src/views/content/admin/index.vue b/src/views/content/admin/index.vue
new file mode 100644
index 0000000..ed56d80
--- /dev/null
+++ b/src/views/content/admin/index.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
diff --git a/src/views/content/index.vue b/src/views/content/index.vue
new file mode 100644
index 0000000..014526a
--- /dev/null
+++ b/src/views/content/index.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
diff --git a/src/views/content/likeBlog/components/likeItem.vue b/src/views/content/likeBlog/components/likeItem.vue
new file mode 100644
index 0000000..fd1f404
--- /dev/null
+++ b/src/views/content/likeBlog/components/likeItem.vue
@@ -0,0 +1,45 @@
+
+
+
+
+ {{index+1}}.{{value.itemTitle}}
+
+
+
+
+
+
diff --git a/src/views/content/likeBlog/index.vue b/src/views/content/likeBlog/index.vue
new file mode 100644
index 0000000..5385f03
--- /dev/null
+++ b/src/views/content/likeBlog/index.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
diff --git a/src/views/content/login/index.vue b/src/views/content/login/index.vue
new file mode 100644
index 0000000..0eb720b
--- /dev/null
+++ b/src/views/content/login/index.vue
@@ -0,0 +1,109 @@
+
+
+
+
+
diff --git a/src/views/content/newBlog/index.vue b/src/views/content/newBlog/index.vue
new file mode 100644
index 0000000..1c97c7d
--- /dev/null
+++ b/src/views/content/newBlog/index.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
diff --git a/src/views/footer/index.vue b/src/views/footer/index.vue
new file mode 100644
index 0000000..6bf3831
--- /dev/null
+++ b/src/views/footer/index.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/src/views/header/components/navBar.vue b/src/views/header/components/navBar.vue
new file mode 100644
index 0000000..8e62a5b
--- /dev/null
+++ b/src/views/header/components/navBar.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
diff --git a/src/views/header/index.vue b/src/views/header/index.vue
new file mode 100644
index 0000000..a84c615
--- /dev/null
+++ b/src/views/header/index.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
diff --git a/src/views/layout/index.vue b/src/views/layout/index.vue
new file mode 100644
index 0000000..ef0192d
--- /dev/null
+++ b/src/views/layout/index.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
diff --git a/test/test.html b/test/test.html
new file mode 100644
index 0000000..4d0fccb
--- /dev/null
+++ b/test/test.html
@@ -0,0 +1,59 @@
+
+
+
+
+ Title
+
+
+
+
+
+
+
diff --git a/test/test.js b/test/test.js
new file mode 100644
index 0000000..9a32c10
--- /dev/null
+++ b/test/test.js
@@ -0,0 +1,13 @@
+function computePage (num, pageNum, arr) {
+ let mid = 5
+ let left = mid - num / 2
+ let right = mid + num / 2
+ left = left < 1 ? 1 : left
+ left = right > pageNum ? pageNum - 10 : left
+ return arr.slice(left, num)
+}
+let arr = []
+for (let i = 0; i < 20; i++) {
+ arr.push(i + 1)
+}
+console.log(computePage(9, 20, arr))
diff --git a/test/test2.html b/test/test2.html
new file mode 100644
index 0000000..c19f5a5
--- /dev/null
+++ b/test/test2.html
@@ -0,0 +1,56 @@
+
+
+
+
+ Title
+
+
+
+
+
+
+
+
+