springboot+vue网站开发02-前端页面的渲染代码展示

springboot+vue网站开发02-前端页面的渲染代码展示!经过上面2个小节的分享,我们已经准备好了前端渲染所需要的数据接口了。可以给大家正常返回新闻分类的信息了。


下面给大家看看,前端vue网站开发的代码,已经渲染的业务流程是什么。


如图,我们查看了package.json内容,里面告诉我们,该前端项目,调用了哪些插件。

比如大家熟悉的,路由,以及状态管理插件vuex。前端布局ui插件element-ui,前端http请求插件axios等等。


 

路由里设置的,默认调用了Home.vue插件,渲染我们的首页信息。

<!-- 首页 -->
<template>
    <div>
        <sg-navbar></sg-navbar>
        <div class="container">
            <el-row  :gutter="30">
                <el-col :sm="24" :md="16" style="transition:all .5s ease-out;margin-bottom:30px;">
                    <sg-articlelist></sg-articlelist>
                </el-col>
                <el-col :sm="24"  :md="8" >
                    <sg-rightlist></sg-rightlist>
                </el-col>
            </el-row>
        </div>
    </div>
</template>

<script>
import header from '../components/header.vue'
import articlelist from '../components/articlelist.vue'
import rightlist from '../components/rightlist.vue'
    export default {
        name:'Home',
        data() { //选项 / 数据
            return {

            }
        },
        methods: { //事件处理器

        },
        components: { //定义组件
            'sg-navbar':header,
            'sg-articlelist':articlelist,
            'sg-rightlist':rightlist,
        },
        created() { //生命周期函数

        }
    }
</script>

<style>

</style>

 

里面写了2个组件,分别对应,导航组件,新闻列表组件,右侧热点新闻 组件。三个组件,给它起了一个别名:映射。在模板代码里就可以使用这个别名来当做标签使用了。

这个项目的代码风格是传统的风格(vue2,选项式编码风格。)


 

<el-submenu index="/Share">
							<template slot="title"><i class="fa fa-wa fa-archive"></i> 分类</template>
							<el-menu-item v-for="(item,index) in classListObj" :key="'class1'+index" :index="'/Share?classId='+item.id">{{item.name}}</el-menu-item>
						</el-submenu>

 在header头部组件内,有我们想要的导航栏信息,使用了是elementUI的标签。

elementUI对这个嵌套菜单的样式设计,渲染的时候有要求。比如:<!-- index 和key 必须要转成字符串,不然控制台会报错-->


这都是vue2选项式开发风格,不再过多的介绍了。看不懂的话,可以去看我的vue2专栏学习一下。


import request from '@/utils/request'

// 查询分类列表
export function getCategoryList() {
    return request({
        url: '/category/getCategoryList',
        headers: {
          isToken: false
        },
        method: 'get'
    })
}

 业务请求api接口封装好了,在一个

里面,调用了axios的信息完成统一请求风格。


 

 

如图所示,后端的控制器内部路径设置,和前端请求路径信息保持一致。即可。


axios里面,关于服务器基础地址baseURL.我之前学习时犯了错,这个必须严格按照官方要求写好,大小写字母不允许自己乱改,只能是这个样子的。

import axios from 'axios'
import { Notification, MessageBox, Message } from 'element-ui'
import router from '@/router'
import store from '../store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'


// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: store.state.baseURL,
  // 超时
  timeout: 10000
})
// request拦截器
service.interceptors.request.use(config => {
  // 是否需要设置 token
  const isToken = (config.headers || {}).isToken === false
  if (getToken() && !isToken) {
    config.headers['token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
  }
  // get请求映射params参数
  if (config.method === 'get' && config.params) {
    let url = config.url + '?'
    for (const propName of Object.keys(config.params)) {
      const value = config.params[propName]
      var part = encodeURIComponent(propName) + '='
      if (value !== null && typeof (value) !== 'undefined') {
        if (typeof value === 'object') {
          for (const key of Object.keys(value)) {
            if (value[key] !== null && typeof (value[key]) !== 'undefined') {
              const params = propName + '[' + key + ']'
              const subPart = encodeURIComponent(params) + '='
              url += subPart + encodeURIComponent(value[key]) + '&'
            }
          }
        } else {
          url += part + encodeURIComponent(value) + '&'
        }
      }
    }
    url = url.slice(0, -1)
    config.params = {}
    config.url = url
  }
  return config
}, error => {
  console.log(error)
  Promise.reject(error)
})

// 响应拦截器
service.interceptors.response.use(res => {
  // 未设置状态码则默认成功状态
  const code = res.data.code || 200
  // 获取错误信息
  const msg = errorCode[code] || res.data.msg || errorCode['default']
  if (code === 401) {
    MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
      confirmButtonText: '重新登录',
      cancelButtonText: '取消',
      type: 'warning'
    }
    ).then(() => {

      localStorage.setItem('logUrl', router.currentRoute.fullPath);
      router.push({
        path: '/Login?login=1'
      });

    }).catch(() => { })
    return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
  } else if (code === 500) {
    Message({
      message: msg,
      type: 'error'
    })
    return Promise.reject(new Error(msg))
  } else if (code !== 200) {
    Notification.error({
      title: msg
    })
    return Promise.reject('error')
  } else {
    // 把字符串total 转换成 数字 total
    if (res.data.data && res.data.data.total) {
      res.data.data.total = parseInt(res.data.data.total)
    }
    return res.data.data
  }
},
  error => {
    console.log('err' + error)
    let { message } = error
    if (message === 'Network Error') {
      message = '后端接口连接异常'
    } else if (message.includes('timeout')) {
      message = '系统接口请求超时'
    } else if (message.includes('Request failed with status code')) {
      message = '系统接口' + message.substr(message.length - 3) + '异常'
    }
    Message({
      message: message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

可以看见,把基础地址封装到了状态管理里面去了。


import Vue from 'vue'
import Vuex from 'vuex'
// import * as getters from './getters.js'

Vue.use(Vuex)

/** 状态定义 */
export const state = {
  loading: false,
  themeObj: 0,//主题
  keywords:'',//关键词
  errorImg: 'this.onerror=null;this.src="' + require('../../static/img/tou.jpg') + '"',
  baseURL:'http://localhost:7777/'
}

export default new Vuex.Store({
    state,
})

 里面还写了一些认证的内容,不做过多的介绍了。

到此为止,我们就已经完成了前端页面请求后端接口,渲染前端页面分类导航栏信息的目的了。