Springboot+Vue前后端分离实现博客系统(前端Vue篇)

1、前言

接下来,我们来完成vueblog前端的部分功能。可能会使用的到技术如下:

  • vue
  • element-ui
  • axios
  • mavon-editor
  • markdown-it
  • github-markdown-css

直接使用 npm install element-ui 、npm install github-markdown-css ......

2、环境准备

1)首先要先安装node、下载node地址:

Node.js官方安装包及源码下载地址:http://nodejs.org/download/

Springboot+Vue前后端分离实现博客系统(前端Vue篇)_第1张图片

Springboot+Vue前后端分离实现博客系统(前端Vue篇)_第2张图片

安装node完成之后,查看版本信息(如果提示出错,配置一下环境变量,将nodejs的路径加入path中)

 

Springboot+Vue前后端分离实现博客系统(前端Vue篇)_第3张图片

2)安装vue的环境

# 安装淘宝npm
npm install -g cnpm --registry=https://registry.npm.taobao.org
# vue-cli 安装依赖包
cnpm install --g vue-cli

3、新建项目

进入指定的文件夹下,执行:vue init webpack vue-blog-front      ;这里的vue-blog-front是项目名称。

Springboot+Vue前后端分离实现博客系统(前端Vue篇)_第4张图片

这里创建项目需要等待一会儿0.0,我这边使用的vscode,导入刚刚创建的项目

Springboot+Vue前后端分离实现博客系统(前端Vue篇)_第5张图片

1.先执行npm install,下载该项目需要的依赖。

目录结构大致解释

├── README.md            项目介绍
├── index.html           入口页面
├── build              构建脚本目录
│  ├── build-server.js         运行本地构建服务器,可以访问构建后的页面
│  ├── build.js            生产环境构建脚本
│  ├── dev-client.js          开发服务器热重载脚本,主要用来实现开发阶段的页面自动刷新
│  ├── dev-server.js          运行本地开发服务器
│  ├── utils.js            构建相关工具方法
│  ├── webpack.base.conf.js      wabpack基础配置
│  ├── webpack.dev.conf.js       wabpack开发环境配置
│  └── webpack.prod.conf.js      wabpack生产环境配置
├── config             项目配置
│  ├── dev.env.js           开发环境变量
│  ├── index.js            项目配置文件
│  ├── prod.env.js           生产环境变量
│  └── test.env.js           测试环境变量
├── mock              mock数据目录
│  └── hello.js
├── package.json          npm包配置文件,里面定义了项目的npm脚本,依赖包等信息
├── src               源码目录 
│  ├── main.js             入口js文件
│  ├── app.vue             根组件
│  ├── components           公共组件目录
│  │  └── title.vue
│  ├── assets             资源目录,这里的资源会被wabpack构建
│  │  └── images
│  │    └── logo.png
│  ├── routes             前端路由
│  │  └── index.js
│  ├── store              应用级数据(state)状态管理
│  │  └── index.js
│  └── views              页面目录
│    ├── hello.vue
│    └── notfound.vue
├── static             纯静态资源,不会被wabpack构建。
└── test              测试文件目录(unit&e2e)
  └── unit              单元测试
    ├── index.js            入口脚本
    ├── karma.conf.js          karma配置文件
    └── specs              单测case目录
      └── Hello.spec.js

2.使用npm安装Router、Vuex、element-ui

Springboot+Vue前后端分离实现博客系统(前端Vue篇)_第6张图片

3.在src目录下的main.js,引入element-ui依赖。

import Element from 'element-ui'
import "element-ui/lib/theme-chalk/index.css"

// 引入element
Vue.use(Element)

接下来就可以在页面上使用element-ui组件了。

4.npm安装axios

npm install axios --save

Springboot+Vue前后端分离实现博客系统(前端Vue篇)_第7张图片

然后同样我们在main.js中全局引入axios。

import axios from 'axios'

// 全局引用axios
Vue.prototype.$axios = axios 

组件中,我们就可以通过this.$axios.get()来发起我们的请求了哈。

5.页面路由

我们在views文件夹下定义几个页面:

  • BlogDetail.vue(博客详情页)
  • BlogEdit.vue(编辑博客)
  • Blogs.vue(博客列表)
  • Login.vue(登录页面)

这里只说明BlogDetail.vue(博客详情页),其他页面都类似(当然你得会些许前端的知识)

页面的结构是:









页面中引入了一个公共的组件,页面的头部内容,这样抽取成一个组件,需要用到该头部内容的页面直接引入该组件即可。

Springboot+Vue前后端分离实现博客系统(前端Vue篇)_第8张图片

然后再路由中心配置:

  • router\index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../views/Login.vue'
import Blogs from '../views/Blogs.vue'
import BlogEdit from '../views/BlogEdit.vue'
import BlogDetail from '../views/BlogDetail.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Index',
    redirect: {name: "Blogs"}
  },
  {
    path: '/blogs',
    name: 'Blogs',
    component: Blogs
  },
  {
    path: '/login',
    name: 'Login',
    component: Login
  },
  {
    path: '/blog/add',
    name: 'BlogAdd',
    component: BlogEdit,
    meta: {
      requireAuth: true
    }
  },
  {
    path: '/blog/:blogId',
    name: 'BlogDetail',
    component: BlogDetail
  },
  {
    path: '/blog/:blogId/edit',
    name: 'BlogEdit',
    component: BlogEdit,
    meta: {
      requireAuth: true
    }
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

接下来我们去开发我们的页面。其中,带有meta:requireAuth: true说明是需要登录字后才能访问的受限资源,后面我们路由权限拦截时候会用到。

登录页面

Login.vue





从返回的结果请求头中获取到token的信息,然后使用store提交token和用户信息的状态。完成操作之后,我们调整到了/blogs路由,即博客列表页面。

const token = res.headers['authorization']
_this.$store.commit('SET_TOKEN', token)
_this.$store.commit('SET_USERINFO', res.data.data)
_this.$router.push("/blogs")

token的状态同步

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    token: '',
    userInfo: JSON.parse(sessionStorage.getItem("userInfo"))
  },
  mutations: {
    // set
    SET_TOKEN: (state, token) => {
      state.token = token
      localStorage.setItem("token", token)
    },
    SET_USERINFO: (state, userInfo) => {
      state.userInfo = userInfo
      sessionStorage.setItem("userInfo", JSON.stringify(userInfo))
    },
    REMOVE_INFO: (state) => {
      state.token = ''
      state.userInfo = {}
      localStorage.setItem("token", '')
      sessionStorage.setItem("userInfo", JSON.stringify(''))
    }

  },
  getters: {
    // get
    getUser: state => {
      return state.userInfo
    }

  },
  actions: {
  },
  modules: {
  }
})

存储token,我们用的是localStorage,存储用户信息,我们用的是sessionStorage。毕竟用户信息我们不需要长久保存,保存了token信息,我们随时都可以初始化用户信息。

定义全局axios拦截器

点击登录按钮发起登录请求,成功时候返回了数据,如果是密码错误,我们是不是也应该弹窗消息提示。为了让这个错误弹窗能运用到所有的地方,所以我对axios做了个后置拦截器,就是返回数据时候,如果结果的code或者status不正常,那么我对应弹窗提示。

import axios from 'axios'
import Element from 'element-ui'
import router from './router'
import store from './store'


axios.defaults.baseURL = "http://localhost:8088"

// 前置拦截
axios.interceptors.request.use(config => {
  return config
})

axios.interceptors.response.use(response => {
    let res = response.data;

    console.log("=================")
    console.log(res)
    console.log("=================")

    if (res.code === 200) {
      return response
    } else {

      Element.Message.error('错了哦,这是一条错误消息', {duration: 3 * 1000})

      return Promise.reject(response.data.msg)
    }
  },
  error => {
    console.log(error)
    if(error.response.data) {
      error.message = error.response.data.msg
    }

    if(error.response.status === 401) {
      store.commit("REMOVE_INFO")
      router.push("/login")
    }

    Element.Message.error(error.message, {duration: 3 * 1000})
    return Promise.reject(error)
  }
)

路由权限拦截

permission.js

import router from "./router";

// 路由判断登录 根据路由配置文件的参数
router.beforeEach((to, from, next) => {

  if (to.matched.some(record => record.meta.requireAuth)) { // 判断该路由是否需要登录权限

    const token = localStorage.getItem("token")
    console.log("------------" + token)

    if (token) { // 判断当前的token是否存在 ; 登录存入的token
      if (to.path === '/login') {

      } else {
        next()
      }
    } else {
      next({
        path: '/login'
      })
    }
  } else {
    next()
  }
})

通过之前我们再定义页面路由时候的的meta信息,指定requireAuth: true,需要登录才能访问,因此这里我们在每次路由之前(router.beforeEach)判断token的状态,觉得是否需要跳转到登录页面。

{
  path: '/blog/add', // 注意放在 path: '/blog/:blogId'之前
  name: 'BlogAdd',
  meta: {
    requireAuth: true
  },
  component: BlogEdit
}

然后我们再main.js中import我们的permission.js

import './permission.js'  // 路由拦截

最后启动项目测试:

1.npm install

2.npm run serve

Springboot+Vue前后端分离实现博客系统(前端Vue篇)_第9张图片

启动成功。

Springboot+Vue前后端分离实现博客系统(前端Vue篇)_第10张图片

Springboot+Vue前后端分离实现博客系统(前端Vue篇)_第11张图片

Springboot+Vue前后端分离实现博客系统(前端Vue篇)_第12张图片

自此vue的前端开发完成。前端代码

文章参考

你可能感兴趣的:(Vue)