15---整合Echarts和完善头像上传

1、完善头像上传功能

  1. 上次写的头像上传功能,不能实现上传保存后立刻刷新右上角头像,这里做一个完善。
  2. 首先是在Manage.vue中(父),写刷新User的方法
//传一个user过去到header 
<Header :collapseBtnClass="collapseBtnClass" :collapse="collapse" :user="user"></Header>
<script>
//user数据
data() {
     return {
       collapseBtnClass:'el-icon-s-fold' ,
       isCollapse:false,
       sideWidth:200 ,
       logoTextShow:true,
       user:{}
     }
   },

created(){
    //从后台获取最新的User数据
    this.getUser()
   },

getUser(){
      let username = localStorage.getItem("user")?JSON.parse(localStorage.getItem("user")).username:""
      if(username){
        //从后台获取user数据
        this.request.get("/user/username/"+username).then(res=>{
          //重新赋值后台的最新User数据
          this.user=res.data
        })
      }
    
     }
  
  </script>

Header.vue里面

 props:{
        collapseBtnClass:String,
        collapse:Function,
        user: Object
    },

Person.vue里面

<script>
...


save(){
        this.request.post("/user",this.form).then(res=>{
          if(res.code==='200'){
            this.$message.success("保存成功!")
            //触发父级更新User的方法
            this.$emit("refreshUser")
            //更新浏览器存储的用户信息
            this.getUser().then(res=>{
              res.token=JSON.parse(localStorage.getItem("user")).token
              localStorage.setItem("user",JSON.stringify(res))
            })
          }else{
            this.$message.error("保存失败!")
        }
      })

    },
      
      
      </script>
  1. 这样就完美实现上传头像保存并能够刷新头像

完整代码:(改动过的页面的代码)

Manage.vue

<template>
  <el-container style="height: 100vh; border: 1px solid #eee">
    <!-- 侧边栏 -->
    <el-aside :width="sideWidth+'px'" style="background-color: rgb(238, 241, 246);height: 100%;" >
    <Aside :isCollapse="isCollapse" :logoTextShow="logoTextShow" ></Aside>
  </el-aside>

 <el-container>
  <!-- 菜单栏 -->
   <el-header style="border-bottom: 1px solid #ccc">
    <Header :collapseBtnClass="collapseBtnClass" :collapse="collapse" :user="user"></Header>
   </el-header>
   <el-main>
    <!-- 页面主体 -->
    <!-- 表示当前页面的子路由(在children中设置)会在router-view里面展示 -->
    <router-view @refreshUser="getUser" />
   </el-main>
 </el-container>
</el-container>
</template>

<script>
import Aside from '@/components/Aside.vue'
import Header from '@/components/Header.vue'

export default {
 name:'Manage',
 components: {Aside,Header},
 data() {
     return {
       collapseBtnClass:'el-icon-s-fold' ,
       isCollapse:false,
       sideWidth:200 ,
       logoTextShow:true,
       user:{}
     }
   },
   created(){
    //从后台获取最新的User数据
    this.getUser()
   },
   methods:{
     collapse(){ //点击收缩按钮触发
       this.isCollapse=!this.isCollapse
       if(this.isCollapse){  //收缩
         this.sideWidth=64
         this.collapseBtnClass='el-icon-s-unfold'
         this.logoTextShow=false
       }else{  //展开
         this.sideWidth = 200 
         this.collapseBtnClass='el-icon-s-fold'
         this.logoTextShow=true 
       }
     },
     getUser(){
      let username = localStorage.getItem("user")?JSON.parse(localStorage.getItem("user")).username:""
      if(username){
        //从后台获取user数据
        this.request.get("/user/username/"+username).then(res=>{
          //重新赋值后台的最新User数据
          this.user=res.data
        })
      }
    
     }
   }
}
</script>

Header.vue

<template>
    <div style="font-size: 12px;line-height:60px;display: flex;">
        <div style="flex:1;font-size:18px">
       <span :class="collapseBtnClass" style="cursor:pointer" @click="collapse"></span>
       <el-breadcrumb separator="/" style="display:inline-block;margin-left: 10px;">
        <el-breadcrumb-item :to="'/'">首页</el-breadcrumb-item>
        <el-breadcrumb-item>{{currentPathName}}</el-breadcrumb-item>
       </el-breadcrumb> 
     </div>
     <el-dropdown style="width:150px;cursor:pointer;text-align: right;" >
        <div style="display:inline-block">
            <img :src="user.avatarUrl" alt=""
                style="width:30px;border-radius: 50%;position:relative;top: 10px; right: 5px">
            <span>{{user.nickname}}</span><i class="el-icon-arrow-down" style="margin-left:5px"></i>

        </div>
        

       <el-dropdown-menu slot="dropdown" style="width:100px; text-align:center">
            <el-dropdown-item style="font-size:14px;padding:5px 0">
                    <router-link to="/password" style="text-decoration:none">修改密码</router-link>
            </el-dropdown-item>
            <el-dropdown-item style="font-size:14px;padding:5px 0">
                    <router-link to="/person" style="text-decoration:none">个人信息</router-link>
            </el-dropdown-item>
            <el-dropdown-item style="font-size:14px;padding:5px 0">
                    <span style="text-decoration: none" @click="logout"> 退出</span>
            </el-dropdown-item>
       </el-dropdown-menu>
     </el-dropdown>
    </div>
</template>

<script>
export default{
    name:"Header",
    props:{
        collapseBtnClass:String,
        collapse:Function,
        user: Object
    },
    computed:{
        currentPathName(){
            return this.$store.state.currentPathName;  //需要监听的数据
        }
    },
    data(){
        return{
           

        }
    },
    methods:{
        collapse(){
            this.$emit("asideCollapse")
        },
        logout(){
            this.$router.push("/login")
            localStorage.removeItem("user")
            this.$message.success("退出成功")
        }
    }

}

</script>

<style scoped>

</style>

Person.vue

<template>
   <el-card style="width:500px;padding:20px;">
    <el-form label-width="80px" size="small">
      <el-upload
        class="avatar-uploader"
        action="http://localhost:8081/file/upload"
        :show-file-list="false"
        :on-success="handleAvatarSuccess">
        <img v-if="form.avatarUrl" :src="form.avatarUrl" class="avatar">
        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
      </el-upload>
          <el-form-item label="用户名" >
            <el-input v-model="form.username" autocomplete="off" disabled ></el-input>
          </el-form-item>
          <el-form-item label="昵称" >
            <el-input v-model="form.nickname" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="邮箱" >
            <el-input v-model="form.email" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="电话" >
            <el-input v-model="form.phone" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="地址" >
            <el-input type="textarea" v-model="form.address" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="save">确 定</el-button>
          </el-form-item>
        </el-form>
   </el-card>
</template>

<script>
export default{
    name:"Person",
    data(){
        return{
            form:{},
            user:localStorage.getItem("user")?JSON.parse(localStorage.getItem("user")):{}
        }
    },
    created(){
       this.getUser().then(res=>{
        console.log(res)
        this.form=res
          
        })
    },
    methods:{
      async getUser(){
        return (await this.request.get("/user/username/"+this.user.username)).data
      },
      save(){
        this.request.post("/user",this.form).then(res=>{
          if(res.code==='200'){
            this.$message.success("保存成功!")
            //触发父级更新User的方法
            this.$emit("refreshUser")
            //更新浏览器存储的用户信息
            this.getUser().then(res=>{
              res.token=JSON.parse(localStorage.getItem("user")).token
              localStorage.setItem("user",JSON.stringify(res))
            })
          }else{
            this.$message.error("保存失败!")
        }
      })

    },
    handleAvatarSuccess(res){
      this.form.avatarUrl=res

    }


    }
}

</script>

<style>

  .avatar-uploader{
    text-align: center;
    padding-bottom: 10px;
  }
  .avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }
  .avatar-uploader .el-upload:hover {
    border-color: #409EFF;
  }
  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 138px;
    height: 138px;
    line-height: 138px;
    text-align: center;
  }
  .avatar {
    width: 138px;
    height: 138px;
    display: block;
  }
</style>

示例:

在这里插入图片描述

2、整合使用Echarts

  1. Echarts就是在前端展示一些模型图,如折线图、圆柱图、饼图等等
  2. 安装

vue里面安装

npm i echarts -S

  1. 安装好后,打开官方文档,参照使用 官网: https://echarts.apache.org/examples/zh/index.html

在这里插入图片描述

  1. 我写的首页代码,直接粘贴如下

Home.vue

<template>
    <div>
        <el-row :gutter="10" style="margin-bottom: 60px">
            <el-col :span="6">
                <el-card style="color:#409EFF">
                    <div ><i class="el-icon-user-solid" />用户总数</div>
                    <div style="padding: 10px 0;text-align:center;font-weight:bold">
                        100
                    </div>
                </el-card>

            </el-col>
            <el-col :span="6">
                <el-card style="color:#F56C6C">
                    <div ><i class="el-icon-money" />销售总量</div>
                    <div style="padding: 10px 0;text-align:center;font-weight:bold">
                        ¥1000000
                    </div>
                </el-card>
            </el-col>
            <el-col :span="6">
                <el-card style="color:#E6A23C">
                    <div><i class="el-icon-bank-card" />收益总额</div>
                    <div style="padding: 10px 0;text-align:center;font-weight:bold">
                        ¥300000
                    </div>
                </el-card>
            </el-col>
            <el-col :span="6">
                <el-card style="color:#67C23A">
                    <div><i class="el-icon-s-shop" />门店总数</div>
                    <div style="padding: 10px 0;text-align:center;font-weight:bold">
                        20
                    </div>
                </el-card>
            </el-col>




        </el-row>



        <el-row>
            <el-col :span="12">
                <div id="main" style="width: 500px;height: 400px"></div>
            </el-col>
            <el-col :span="12">
                <div id="pie" style="width: 500px;height: 400px"></div>
            </el-col>
        </el-row>
        
      
    </div>
</template>

<script>
import * as echarts from 'echarts';
export default{
    name:"Home",
    data(){
        return{

        }
    },
    mounted(){  //页面元素渲染之后再触发
        var chartDom = document.getElementById('main');
        var myChart = echarts.init(chartDom);
        var option = {
            title:{
                text:'各季度用户注册人数统计',
                subtext:'趋势图',
                left:'center'
            },
        xAxis: {
            type: 'category',
            data: ["第一季度","第二季度","第三季度","第四季度"]
        },
        yAxis: {
            type: 'value'
        },
        series: [
            {
            data: [],
            type: 'line'
            },
            {
            data: [],
            type: 'bar'
            }
        ]
        };
        this.request.get("/echarts/members").then(res=>{
            //填空
            option.series[0].data=res.data
            option.series[1].data=res.data
            //数据准备完毕再set
            myChart.setOption(option);

            pieOption.series[0].data=[
                {name:"第一季度",value:res.data[0]},
                {name:"第二季度",value:res.data[1]},
                {name:"第三季度",value:res.data[2]},
                {name:"第四季度",value:res.data[3]},
            ]
            pieChart.setOption(pieOption);
            
        })
     

        //饼图

        var pieDom = document.getElementById('pie');
        var pieChart = echarts.init(pieDom);
        var pieOption = {
            title:{
                text:'各季度用户注册人数统计',
                subtext:'比例图',
                left:'center'
            },
        tooltip: {
            trigger: 'item'
        },
        legend: {
            orient: 'vertical',
            left: 'left'
        },
        series: [
            {
            type: 'pie',
            radius: '70%',
            label:{//饼图图形上的文本标签
                normal:{
                    show:true,
                    position:'inner',//标签位置
                    textStyle:{
                        fontWeight:300,
                        fontSize:16  //文件字体大小
                    },
                    formatter:'{d}%'
                }

            },
            data: [],
            emphasis: {
                itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
            }
            }
        ]
        };




    }
}

</script>

包括一个折线图+圆柱图,和一个饼图

模型图的数据都是从数据库里面查的,下面写请求的后端接口

  1. 写一个EchartsController
package com.xqh.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.Quarter;
import com.xqh.common.Result;
import com.xqh.entity.User;
import com.xqh.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/echarts")
public class EchartsController {
    @Autowired
    private UserService userService;

    //假数据
    @GetMapping("/example")
    public Result get(){
        Map<String, Object> map = new HashMap<>();
        map.put("x",CollUtil.newArrayList("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"));
        map.put("y",CollUtil.newArrayList(150, 230, 224, 218, 135, 147, 260));
        return Result.success(map);

    }

    //四个季度的注册的用户数据,从数据库中拿
    @GetMapping("/members")
    public Result members(){
        List<User> list = userService.list();
        int q1=0; //第一季度
        int q2=0;
        int q3=0;
        int q4=0;
        for (User user: list) {
            Date createTime = user.getCreateTime();
            Quarter quarter = DateUtil.quarterEnum(createTime);
            switch(quarter){
                case Q1:q1 +=1; break;
                case Q2:q2 +=1; break;
                case Q3:q3 +=1; break;
                case Q4:q4 +=1; break;
                default:break;
            }

        }

        return Result.success(CollUtil.newArrayList(q1,q2,q3,q4));
    }
}

  1. 我们需要补充一下数据库的数据,不然不好测试,因为写的是四个季度的,可以多补充一些不同创建时间的数据,我的是这样的:

在这里插入图片描述

  1. 去前端页面测试效果

在这里插入图片描述

  1. 可以根据自己的需求来搞首页。这里首页模型图里的数据都是真实从数据库中取的,可以看我的vue代码,一一对应上数据库中的数据。(首页最上面那四个框是写定的数据…那个需要根据真实业务来,我们现在还没有那么多业务)
  2. 可以正常展示,就完成了!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot 是一个非常流行的 Java Web 开发框架,而 ECharts 是一个非常流行的可视化图表库。Spring Boot 可以轻松地整合 ECharts,以下是整合的步骤: 1. 在 pom.xml 中添加 ECharts 的依赖: ```xml <dependency> <groupId>org.webjars</groupId> <artifactId>echarts</artifactId> <version>{echarts-version}</version> </dependency> ``` 2. 创建一个 Spring Boot 控制器类,用于渲染 ECharts 图表: ```java @Controller public class EChartsController { @GetMapping("/echarts") public String echarts(Model model) { // 构造图表数据 List<Integer> data = Arrays.asList(1, 2, 3, 4, 5); // 将数据传递给模板引擎 model.addAttribute("data", data); // 返回模板名称 return "echarts"; } } ``` 3. 创建一个 Thymeleaf 模板文件,用于渲染 ECharts 图表: ```html <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>ECharts Demo</title> <!-- 引入 ECharts 的 CSS 文件 --> <link rel="stylesheet" th:href="@{/webjars/echarts/{echarts-version}/echarts.min.css}"/> </head> <body> <!-- 渲染 ECharts 图表 --> <div id="chart"></div> <!-- 引入 ECharts 的 JS 文件 --> <script th:src="@{/webjars/echarts/{echarts-version}/echarts.min.js}"></script> <script th:inline="javascript"> // 获取数据 var data = [[${data}]]; // 初始化图表 var chart = echarts.init(document.getElementById('chart')); chart.setOption({ xAxis: { type: 'category', data: ['A', 'B', 'C', 'D', 'E'] }, yAxis: { type: 'value' }, series: [{ data: data, type: 'bar' }] }); </script> </body> </html> ``` 以上就是 Spring Boot 整合 ECharts 的基本步骤。在实际开发中,还需要根据具体需求进行一些配置和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zero摄氏度

感谢鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值