diff --git a/.DS_Store b/.DS_Store
index 8f052a65..0fb6f821 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/README.md b/README.md
index ded117d6..89b47226 100644
--- a/README.md
+++ b/README.md
@@ -1,95 +1,48 @@
# vue2-blog
-![image](https://img.shields.io/badge/vue-2.5.9-blue.svg)
+![image](https://img.shields.io/badge/vue-2.5.13-blue.svg)
![image](https://img.shields.io/badge/vue--router-3.0.1-blue.svg)
![image](https://img.shields.io/badge/vuex-3.0.1-blue.svg)
-![image](https://img.shields.io/badge/element--ui-2.0.7-blue.svg)
+![image](https://img.shields.io/badge/element--ui-2.0.11-blue.svg)
-#### 还在开发,敬请期待! (已完成90%)
-> 你的 "star" 是我最大的动力!🌹
-
-
-## 前言
-
-该项目是基于 vue全家桶 + element-ui组件库,构建的一个后台类应用模板,也是一个后台应用实例。目的是为了帮助开发人员快速的搭建基于 vue-cli 开发的后台应用和vue学习者参考学习。
-
-
-## 说明
-> 如果对您有帮助,您可以点右上角 "star"一下!非常感谢!^_^ 🌹
-
-> 或者您可以 "follow(关注)" 作者,我会不断开源更多实用的项目。
-
-> 如有问题可以直接在 Issues 中提,或者加入我们下方的vue群更进一步地交流。
-
-
-## 其他开源项目
-- 第一阶段:echo回声(移动端,难度:简单 ~ 中等) —— [仓库地址](https://github.com/uncleLian/vue2-echo) —— [演示地址](http://echo.liansixin.win)
-
-- 第二阶段:今日头条(移动端 & native,难度:困难) —— [仓库地址](https://github.com/uncleLian/vue2-news) —— [web演示地址](http://toutiao.liansixin.win), [native端演示地址](http://native.liansixin.win)
-
-- 第三阶段:头条号(pc端,难度:中等 ~ 困难) —— [仓库地址](https://github.com/uncleLian/vue2-health) —— [演示地址](http://health.liansixin.win) (还在开发,敬请期待!已实现核心功能)
+## 简介
+vue2-blog 是一个后台集成解决方案,它基于 [vue.js](https://github.com/vuejs/vue) 和 [element-ui](https://github.com/ElemeFE/element)。使用了最新的前端技术栈。内置登录、动态路由、I18n国际化等功能特性。目的是为了帮助开发人员快速搭建后台应用和vue学习者参考学习。
## 项目演示
#### [演示地址](http://blog.liansixin.win)
-
-## 基本功能
-##### 1、element ui 组件库(完成)
-##### 2、登录登出(完成)
-##### 3、根据路由表递归生成侧边栏(可配置图标、登录、展开子菜单等)(完成)
-##### 4、根据当前路由生成面包屑(完成)
-##### 5、统一的API请求、拦截以及错误处理(完成)
-##### 6、自动匹配开发环境和生产环境的请求链接(完成)
-##### 7、没有相匹配的路由将跳转至404页面(完成)
-##### 8、全局捕捉错误信息(完成)
-##### 9、面包屑、图钉、返回顶部(完成)
-
-## 自定义组件
-##### 1、面包屑:breadcrumb.vue(完成)
-##### 2、图钉:sticky.vue(完成)
-##### 3、返回顶部:backTop.vue(完成)
-##### 4、动态数值:countTo.vue(完成)
-##### 5、加载提示:loading.vue(完成)
-
-## 集成功能
-##### 1、进度条(完成)
-##### 2、剪贴板(完成)
-##### 3、导入导出 excel 文件(完成)
-##### 4、图表echarts(完成)
-##### 5、富文本编辑器(完成)
-##### 6、Markdown(完成)
-##### 7、国际化(完成)
-##### 8、换肤(完成)
-##### 9、第三方登录
-
-## 综合实例
-##### 1、拖拽列表(完成)
-##### 2、拖拽表格(完成)
-##### 3、自定义图片上传、草稿、预览等(完成)
-
-## 更多
-##### 1、404 页面(完成)
-##### 2、错误日志(完成)
-
-## 第三方依赖
-##### 1、[element-ui](https://github.com/ElemeFE/element)(UI组件库)
-##### 2、[axios](https://github.com/axios/axios)(请求库)
-##### 3、[vue-progressbar](https://github.com/hilongjw/vue-progressbar)(进度条)
-##### 4、[vue-quill-editor](https://github.com/surmon-china/vue-quill-editor)(富文本编辑器)
-##### 5、[vuedraggable](https://github.com/SortableJS/Vue.Draggable)(基于sortablejs的vue的拖拽库)
-##### 6、[sortablejs](https://github.com/RubaXa/Sortable)(拖拽库)
-##### 7、[vue-clipboard-pack](https://github.com/uncleLian/vue-clipboard-pack)(本人基于clipboard.js封装的剪贴板)
-##### 8、[mockjs](https://github.com/nuysoft/Mock/tree/refactoring)(数据模拟)
-##### 9、[font-awesome](http://fontawesome.io/icons/)(字体库)
-##### 10、babel-polyfill(JS语法库,修复IE不支持语法问题)
-##### 11、[js-cookie](https://github.com/js-cookie/js-cookie)(方便处理cookie的JS库)
-##### 12、[stylus](https://github.com/stylus/stylus) stylus-loader(css预处理器)
-##### 13、less less-loader(css预处理器)
-##### 14、[js-xlsx](https://github.com/SheetJS/js-xlsx)(电子表格处理库)
-##### 15、[simplemde](https://github.com/sparksuite/simplemde-markdown-editor)(Markdown编辑器)
-##### 16、[showdown](https://github.com/showdownjs/showdown)(Markdown转换成HTML的库)
-##### 17、[vue-i18n](https://github.com/showdownjs/showdown)(实现多语言的库)
+## 功能
+- [x] 登录/注销
+- [x] 多环境发布
+- [x] 前端mock数据
+- [x] 动态侧边栏(支持多级路由和一键配置图标、登录、展开、缓存等选项)
+- [x] 动态面包屑
+- [x] 动态换肤(实现element-ui官网的换肤功能)
+- [x] 国际化多语言(中文、English)
+- [x] 进度条
+- [x] [剪贴板](https://github.com/uncleLian/vue-clipboard-pack)(另一个项目,打个广告~)
+- [x] 富文本编辑器(自定义图片上传、草稿、预览等)
+- [x] Markdown编辑器(搭配Markdown语法转HTML功能)
+- [x] 导入.md文件
+- [x] 导入导出Excel
+- [x] Echarts 图表
+- [x] 拖拽列表、表格
+- [x] 404页面
+- [x] 错误日志(全局错误捕捉)
+- [x] Iconfont图标
+- [x] 图钉
+- [x] 返回顶部
+- [x] 动态数值
+- [x] 加载提示(3种状态:加载中,无数据,出现错误且支持点击重新请求)
+
+##### 待更新
+- [ ] 权限验证
+- [ ] 文档
+
+## 部分截图
+
+
## 安装运行
@@ -97,21 +50,42 @@
# install dependencies
npm install
-# serve with hot reload at localhost:8084 or localhost:8020
+# serve with hot reload at localhost:8020
npm run dev
# build for production with minification
-npm run build
+npm run build(File in the docs folder)
```
-## 交流
+## 更新日志
+[发行说明](https://github.com/uncleLian/vue2-blog/releases)中记录了每个版本的详细更改。
+## 传送门
+- 第一阶段:echo回声(移动端,难度:简单,入门项目) —— [仓库地址](https://github.com/uncleLian/vue2-echo) —— [演示地址](http://echo.liansixin.win)
+
+- 第二阶段:今日头条(移动端 & native,难度:困难,进阶项目) —— [仓库地址](https://github.com/uncleLian/vue2-news) —— [web演示地址](http://toutiao.liansixin.win), [native端演示地址](http://native.liansixin.win)
+
+- 第三阶段:头条号(pc端,难度:中等,过渡项目) —— [仓库地址](https://github.com/uncleLian/vue2-health) —— [演示地址](http://health.liansixin.win) (还在开发,敬请期待!已实现核心功能)
+
+
+## 说明
+> 如果对您有帮助,你可以点右上角 "star"支持一下🌹
+
+> 或者您可以 "follow(关注)" 作者,我正在不断开源更多实用的项目。
+
+> 如有问题可以直接在 Issues 中提,或者加入我们下方的vue群更进一步地交流。
+
+
+## 交流
欢迎热爱学习、忠于分享的朋友一起来交流
- QQ:771674109
- Vue交流群:338241465 —— 广州-小鑫
-## License
+## 捐赠
+
+
+## License
[MIT](http://opensource.org/licenses/MIT)
Copyright (c) 2017-present,uncleLian
diff --git a/screenshots/donate.jpg b/screenshots/donate.jpg
new file mode 100644
index 00000000..78e1da73
Binary files /dev/null and b/screenshots/donate.jpg differ
diff --git a/screenshots/home.jpg b/screenshots/home.jpg
new file mode 100644
index 00000000..2613b8a4
Binary files /dev/null and b/screenshots/home.jpg differ
diff --git a/screenshots/login.jpg b/screenshots/login.jpg
new file mode 100644
index 00000000..aeef8df9
Binary files /dev/null and b/screenshots/login.jpg differ
diff --git a/src/api/index.js b/src/api/index.js
index 7b30f43f..07de5e23 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -1,5 +1,10 @@
import { request, instance } from '@/utils/request'
+// Tip:
+// 1、request方法适用于普遍的GET、POST方法
+// 2、instance方法适用于需要做特殊处理的请求,如:自定义Header、其他的http方法等
+// 3、使用解构参数,方便阅读和管理。
+
// 登录
export function getLogin(form) {
let res = request('/login', 'POST', form)
@@ -19,7 +24,7 @@ export function getList() {
}
// 图片
-export async function getPicture(data) {
- let res = await instance.get('http://api.toutiaojk.com/e/extend/jkh/picsearch', { params: data })
+export async function getPicture({key, page}) {
+ let res = await instance.get('http://api.toutiaojk.com/e/extend/jkh/picsearch', { params: {key, page} })
return res.data
}
diff --git a/src/main.js b/src/main.js
index 92b208d7..fefa88f3 100644
--- a/src/main.js
+++ b/src/main.js
@@ -70,25 +70,26 @@ Object.keys(filters).forEach(key => {
// 全局路由登录验证
router.beforeEach((to, from, next) => {
- let token = cache.getToken()
- if (to.path === '/login' && token) {
- next('/')
- } else if (to.matched.some(record => record.meta.login)) {
- if (token) {
- if (store.getters.user) {
- next()
+ if (to.matched.some(record => record.meta.login)) {
+ if (cache.getToken()) {
+ if (to.path === '/login') {
+ next('/')
} else {
- store.dispatch('get_user_data')
- .then(res => {
+ if (store.getters.user) {
next()
- })
- .catch(() => {
- window.alert('账号在别处登录,请重新登录')
- next({
- path: '/login',
- query: { redirect: to.fullPath }
+ } else {
+ store.dispatch('get_user_data').then(() => {
+ next()
})
- })
+ .catch(() => {
+ // 可根据错误信息,做相应需求,这里默认token值失效
+ window.alert('登录已失效,请重新登录')
+ next({
+ path: '/login',
+ query: { redirect: to.fullPath }
+ })
+ })
+ }
}
} else {
next({
diff --git a/src/mock/index.js b/src/mock/index.js
index 6bea216a..f88df1fd 100644
--- a/src/mock/index.js
+++ b/src/mock/index.js
@@ -1,5 +1,6 @@
/* eslint-disable */
var Mock = require('mockjs')
+
// 开发测试数据
// 登录
Mock.mock('http://blog.liansixin.win/api-dev/login', {
@@ -7,8 +8,13 @@ Mock.mock('http://blog.liansixin.win/api-dev/login', {
})
// 用户信息
Mock.mock('http://blog.liansixin.win/api-dev/user', {
- nickname: '思鑫',
- headimgurl: 'https://avatars1.githubusercontent.com/u/25951301?s=40&v=4'
+ code: 200,
+ msg: 'success',
+ data: {
+ nickname: '思鑫',
+ headimgurl: 'https://avatars1.githubusercontent.com/u/25951301?s=40&v=4',
+ role: 'admin'
+ }
})
// 列表
Mock.mock('http://blog.liansixin.win/api-dev/list', {
@@ -2199,7 +2205,8 @@ Mock.mock('http://blog.liansixin.win/api-prod/login', {
// 用户信息
Mock.mock('http://blog.liansixin.win/api-prod/user', {
nickname: 'uncleLian',
- headimgurl: 'https://avatars1.githubusercontent.com/u/25951301?s=40&v=4'
+ headimgurl: 'https://avatars1.githubusercontent.com/u/25951301?s=40&v=4',
+ role: 'admin'
})
// 列表
Mock.mock('http://blog.liansixin.win/api-prod/list', {
diff --git a/src/page/index/children/home/components/homeTable.vue b/src/page/index/children/home/components/homeTable.vue
index 267c596c..80a07464 100644
--- a/src/page/index/children/home/components/homeTable.vue
+++ b/src/page/index/children/home/components/homeTable.vue
@@ -60,7 +60,7 @@ export default {
mounted() {
getList().then(res => {
if (res) {
- this.tableJson = res.data.slice(0, 6)
+ this.tableJson = res.data.slice(0, 7)
}
})
}
diff --git a/src/router/index.js b/src/router/index.js
index 8e5b0d1d..8376fe45 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -268,8 +268,14 @@ export const routes = [
component: login
},
{
- path: '*',
+ name: '404',
+ path: '/404',
+ meta: { login: true },
component: page404
+ },
+ {
+ path: '*',
+ redirect: '/404'
}
]
diff --git a/src/store/index.js b/src/store/index.js
index 2a794320..db8e818a 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -7,10 +7,10 @@ import i18n from '@/language'
Vue.use(Vuex)
const state = {
- user: '',
- logs: [],
- language: 'zh',
- theme: '#42B983'
+ user: '', // 用户信息
+ logs: [], // 错误日志
+ language: 'zh', // 语言
+ theme: '#42B983' // 主题颜色
}
const getters = {
@@ -42,12 +42,12 @@ const actions = {
async get_login_data({ commit }, params) {
return new Promise((resolve, reject) => {
getLogin(params).then(res => {
- // console.log('token', res)
+ // console.log('login', res)
if (res && res.token) {
cache.setToken(res.token)
resolve()
} else {
- reject(new Error('nothing data'))
+ reject(new Error('nothing login data'))
}
})
.catch(err => {
@@ -59,9 +59,10 @@ const actions = {
async get_user_data({ commit }, token) {
return new Promise((resolve, reject) => {
getUser(token).then(res => {
- if (res) {
- commit('set_user', res)
- resolve()
+ // console.log('user', res)
+ if (res && res.code === 200 && res.data) {
+ commit('set_user', res.data)
+ resolve(res)
} else {
reject(new Error('nothing user data'))
}