SpingBoot + Vue + Element UI + Echarts 整合的小 Demo

SpingBoot + Vue + Element UI + Echarts 整合的小 Demo

Vue 工程

1、执行命令

cnpm install [email protected] --save

2、main.js 中引入

import echarts from 'echarts'
Vue.prototype.$echarts = echarts

3、代码

<template>
    <div id="myChart" :style="{width: '800px', height: '600px'}"></div>
</template>
<script>
    export default {
    
    
        name: 'Echarts',
        mounted(){
    
    
            // 基于准备好的dom,初始化echarts实例
            let myChart = this.$echarts.init(document.getElementById('myChart'))
            // 绘制图表
            myChart.setOption()  //一般从官网复制Option过来直接放到setOption()里面
        }
    }
</script>
  • App.vue
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/add">添加数据</router-link> |
      <router-link to="/table">数据管理</router-link> |
      <router-link to="/pie">饼图</router-link> |
      <router-link to="/bar">柱状图</router-link>
    </div>
    <div style="border:0px solid red;width: 800px;height: 600px;margin-left: 366px;">
      <router-view/>
    </div>
  </div>
</template>
<template slot-scope="scope">
    <img :src="scope.row.icon" style="height: 70px"/>
</template>
=================================================================
<template>
  <el-table
    :data="tableData"
    border
    style="width: 100%">
    <el-table-column
      prop="icon"
      label="图片"
      width="160">
      <template slot-scope="liu">
        <img :src="liu.row.icon" style="height: 70px"/>
      </template>
    </el-table-column>

    <el-table-column
      fixed="right"
      label="操作"
      width="100">
      <template slot-scope="scope">
		//传递参数把操作的此行对象传入  fruitDelete(scope.row)
        <el-button @click="fruitDelete(scope.row)" type="text" size="small">删除</el-button>
        <el-button @click="findFruit(scope.row)" type="text" size="small">编辑</el-button>
      </template>
        
    </el-table-column>
  </el-table>
</template>

<script>
export default {
    
    
    ===============
  methods: {
    
    
    findFruit (object) {
    
    
      this.$router.push('/edit?id=' + object.id) // 页面跳转到我们的edit页面带上id
        //let id = this.$route.query.id // 获取id 在edit页面中这样获取id
    },
    fruitDelete (row) {
    
     // 传入我们的数据 row
      let _this = this
      this.$confirm('是否确定要删除' + row.name + '?', '删除数据', {
    
    
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
    
     // 点击确定就进入这个回调中
        _this.$axios.delete('http://localhost:8181/fruit/delete/' + row.id).then(function (response) {
    
    
          if (response.data) {
    
    
            _this.$alert(row.name + '删除成功!', '删除数据', {
    
    
              confirmButtonText: '确定',
              callback: action => {
    
    
                // 跳转到/table
                location.reload() // 点击确定就执行这个  ---刷新页面
              }
            })
          }
        })
      }).catch(() => {
    
    
      })
    }

  },
    ======================
  // get 去请求  then 去回调
  // this 表示的vue对象,在回调中我们拿的是回调的对象  所以我们设置_this来表示全局的对象
  created () {
    
    
    let _this = this
    this.$axios.get('http://localhost:8181/fruit/list').then(function (response) {
    
    
      _this.tableData = response.data
    })
  },
    =====================
  data () {
    
    
    return {
    
    
      tableData: null
    }
  }
}
</script>

  • 数据校验
<template>
    <el-form ref="fruitRules" :model="fruit" :rules="rules" label-width="80px" class="demo-ruleForm" style="width: 600px">
        <!-- prop 就是跟我们的校验规则绑定的-->
        <el-form-item label="名称" prop="name">
            <el-input v-model="fruit.name"></el-input>
        </el-form-item>
        <el-form-item label="销量" prop="sale">
            <el-input v-model.number="fruit.sale"></el-input>
        </el-form-item>
        <el-form-item label="图片" prop="icon">
            <el-input v-model="fruit.icon"></el-input>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="onSubmit('fruitRules')">立即创建</el-button>
            <el-button @click="onSubmit1('form')">取消</el-button>
        </el-form-item>
    </el-form>
</template>

<script>
    export default {
    
    
        name: "Add",
        data() {
    
    
            return {
    
    
                fruit: {
    
    
                    name: '',
                    sale: '',
                    icon: ''
                },
                rules:{
    
       //数据校验规则
                    // required 必填项 如果不填就打印 message,trigger表示什么时候触发,blur表示光标离开的时候
                    name:[
                        {
    
     required: true, message: '请输入水果名称', trigger: 'blur' }
                    ],
                    sale:[
                        {
    
     required: true, message: '请输入销量', trigger: 'blur' },
                        {
    
     type: 'number', message: '销量必须为数字值'}
                    ],
                    icon:[
                        {
    
     required: true, message: '请输入图片链接', trigger: 'blur' }
                    ]
                }
            }
        },
        methods: {
    
    
            onSubmit(formName){
    
    
                this.$refs[formName].validate((valid) => {
    
    
                    if (valid) {
    
    
                        let _this = this
                        axios.post('http://localhost:8181/fruit/add',this.fruit).then(function (response) {
    
    
                            if(response.data){
    
    
                                _this.$alert(_this.fruit.name+'添加成功!', '添加数据', {
    
    
                                    confirmButtonText: '确定',
                                    callback: action => {
    
    
                                        //跳转到/table
                                        _this.$router.push('/table')
                                    }
                                });
                            }
                        })
                    }
                });
            }onSubmit1(formName){
    
    
      		this.$router.push('/table') //取消就回到首页
    }
        }
    }
</script>

<style scoped>

</style>
  • APP、Table、Edit、Add、Bar、Pie.Vue
<template>
  <div id="app">
    <div id="nav">
<!--      <router-link to="/add">添加数据</router-link> |-->
      <router-link to="/add">添加数据</router-link> |
      <router-link to="/table">数据管理</router-link> |
      <router-link to="/pie">饼图</router-link> |
      <router-link to="/bar">柱状图</router-link>
    </div>
    <div style="border:0px solid red;width: 800px;height: 600px;margin-left: 400px;">
      <router-view/>
    </div>
  </div>
</template>

<script>
export default {
    
    
  name: 'App'
}
</script>

<style>
#app {
    
    
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
<!--=====================================================================================================-->
<template>
  <el-table
    :data="tableData"
    border
    style="width: 100%">
    <el-table-column
      fixed
      prop="id"
      label="水果ID"
      width="160">
    </el-table-column>
    <el-table-column
      prop="name"
      label="水果名称"
      width="160">
    </el-table-column>
    <el-table-column
      prop="sale"
      label="水果销量"
      width="160">
    </el-table-column>
    <el-table-column
      prop="icon"
      label="图片"
      width="160">
      <template slot-scope="liu">
        <img :src="liu.row.icon" style="height: 70px"/>
      </template>
    </el-table-column>
    <el-table-column
      fixed="right"
      label="操作"
      width="100">
      <template slot-scope="scope">
        <el-button @click="fruitDelete(scope.row)" type="text" size="small">删除</el-button>
        <el-button @click="findFruit(scope.row)" type="text" size="small">编辑</el-button>
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
export default {
    
    
  methods: {
    
    
    findFruit (object) {
    
    
      this.$router.push('/edit?id=' + object.id) // 页面跳转到我们的edit页面带上id
    },
    fruitDelete (row) {
    
     // 传入我们的数据 row
      let _this = this
      this.$confirm('是否确定要删除' + row.name + '?', '删除数据', {
    
    
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
    
     // 点击确定就进入这个回调中
        _this.$axios.delete('http://localhost:8181/fruit/delete/' + row.id).then(function (response) {
    
    
          if (response.data) {
    
    
            _this.$alert(row.name + '删除成功!', '删除数据', {
    
    
              confirmButtonText: '确定',
              callback: action => {
    
    
                // 跳转到/table
                location.reload() // 点击确定就执行这个  ---刷新页面
              }
            })
          }
        })
      }).catch(() => {
    
    
      })
    }

  },
  // get 去请求  then 去回调
  // this 表示的vue对象,在回调中我们拿的是回调的对象  所以我们设置_this来表示全局的对象
  created () {
    
    
    let _this = this
    this.$axios.get('http://localhost:8181/fruit/list').then(function (response) {
    
    
      _this.tableData = response.data
    })
  },
  data () {
    
    
    return {
    
    
      tableData: null
    }
  }
}
</script>

<!--=====================================================================================================-->
<template>
  <el-form ref="form" :rules="rules" :model="fruit" label-width="80px" style="width: 600px">
    <el-form-item label="水果ID">
      <el-input v-model="fruit.id" readonly></el-input>
    </el-form-item>
    <el-form-item label="名称" prop="name">
      <el-input v-model="fruit.name"></el-input>
    </el-form-item>
    <el-form-item label="销量" prop="sale">
      <el-input v-model.number="fruit.sale"></el-input>
    </el-form-item>
    <el-form-item label="图片" prop="icon">
<!--      // prop 就是跟我们的校验规则绑定的-->
      <el-input v-model="fruit.icon"></el-input>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="onSubmit('form')">立即修改</el-button>
      <el-button @click="onSubmit1('form')">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script>
export default {
    
    
  name: "Edit",
  data () {
    
    
    return {
    
    
      fruit: {
    
    
        name: '',
        sale: '',
        icon: ''
      },
      rules:{
    
    
        name:[
          {
    
     required: true, message: '请输入水果名称', trigger: 'blur' } // required 必填项 如果不填就打印 message,trigger表示什么时候触发,blur表示光标离开的时候
        ],
        sale:[
          {
    
     required: true, message: '请输入销量', trigger: 'blur' },
          {
    
     type: 'number', message: '销量必须为数字值'}
        ],
        icon:[
          {
    
     required: true, message: '请输入图片链接', trigger: 'blur' }
        ]
      }
    }
  },
  created() {
    
    
    let id = this.$route.query.id // 获取id
    let _this = this
    this.$axios.get('http://localhost:8181/fruit/find/'+id).then(function (response) {
    
    
      _this.fruit = response.data
    })
  },
  methods: {
    
    
    onSubmit(formName) {
    
    
      this.$refs[formName].validate((valid) => {
    
    
        if (valid) {
    
    
          let _this = this
          this.$axios.put('http://localhost:8181/fruit/update',this.fruit).then(function (response) {
    
    
            if(response.data){
    
    
              _this.$alert(_this.fruit.name+'修改成功!', '修改数据', {
    
    
                confirmButtonText: '确定',
                callback: action => {
    
    
                  //跳转到/table
                  _this.$router.push('/table')
                }
              });
            }
          })
        }
      });
    },
    onSubmit1(formName){
    
    
      this.$router.push('/table')
    }
  }
}
</script>
<style scoped>
</style>
<!--=====================================================================================================-->
<template>
  <el-form ref="fruitRules" :model="fruit" :rules="rules" label-width="80px" class="demo-ruleForm" style="width: 600px">
    <el-form-item label="名称" prop="name">
      <el-input v-model="fruit.name"></el-input>
    </el-form-item>
    <el-form-item label="销量" prop="sale">
      <el-input v-model.number="fruit.sale"></el-input>
    </el-form-item>
    <el-form-item label="图片" prop="icon">
      <el-input v-model="fruit.icon"></el-input>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="onSubmit('fruitRules')">立即创建</el-button>
      <el-button @click="onSubmit1('form')">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script>
export default {
    
    
  name: "Add",
  data() {
    
    
    return {
    
    
      fruit: {
    
    
        name: '',
        sale: '',
        icon: ''
      },
      rules:{
    
    
        name:[
          {
    
     required: true, message: '请输入水果名称', trigger: 'blur' }
        ],
        sale:[
          {
    
     required: true, message: '请输入销量', trigger: 'blur' },
          {
    
     type: 'number', message: '销量必须为数字值'}
        ],
        icon:[
          {
    
     required: true, message: '请输入图片链接', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    
    
    onSubmit(formName){
    
    
      this.$refs[formName].validate((valid) => {
    
    
        if (valid) {
    
    
          let _this = this
          this.$axios.post('http://localhost:8181/fruit/add',this.fruit).then(function (response) {
    
    
            if(response.data){
    
    
              _this.$alert(_this.fruit.name+'添加成功!', '添加数据', {
    
    
                confirmButtonText: '确定',
                callback: action => {
    
    
                  //跳转到/table
                  _this.$router.push('/table')
                }
              });
            }
          })
        }
      });
    },
    onSubmit1(formName){
    
    
      this.$router.push('/table')
    }
  }
}
</script>

<style scoped>

</style>

<!--=====================================================================================================-->
<template>
  <div id="myChart" :style="{width: '800px', height: '600px'}"></div>
</template>
<script>

export default {
    
    
  name: 'Echarts',
  mounted () {
    
    
    let _this = this
    this.$axios('http://localhost:8181//fruit/barVO').then(function (response) {
    
    
      // 基于准备好的dom,初始化echarts实例
      let myChart = _this.$echarts.init(document.getElementById('myChart'))
      // 绘制图表
      myChart.setOption({
    
    
        title: {
    
    
          text: '水果销量统计',
          left: 'center',
          top: 20,
          textStyle: {
    
    
            color: '#555555'
          }
        },
        tooltip: {
    
    },
        xAxis: {
    
    
          data: response.data.names
        },
        yAxis: {
    
    },
        series: [{
    
    
          name: '销量',
          type: 'bar',
          data: response.data.values
        }]
      })
    })
  }
}
</script>
<!--=====================================================================================================-->
<template>
  <div id="myChart" :style="{width: '800px', height: '600px'}"></div>
</template>
<script>
export default {
    
    
  name: 'Echarts',
  mounted () {
    
    
    let _this = this
    this.$axios.get('http://localhost:8181//fruit/pieVO').then(function (response) {
    
    
      // 基于准备好的dom,初始化echarts实例
      let myChart = _this.$echarts.init(document.getElementById('myChart'))
      // 绘制图表
      myChart.setOption({
    
    
        backgroundColor: '#2c343c',

        title: {
    
    
          text: '水果销量统计',
          left: 'center',
          top: 20,
          textStyle: {
    
    
            color: '#ccc'
          }
        },
        tooltip: {
    
    
          trigger: 'item'
        },

        visualMap: {
    
    
          show: false,
          min: 80,
          max: 600,
          inRange: {
    
    
            colorLightness: [0, 1]
          }
        },
        series: [
          {
    
    
            name: '访问来源',
            type: 'pie',
            radius: '55%',
            center: ['50%', '50%'],
            data:
              // response.data 来表示回调的数据
              response.data.sort(function (a, b) {
    
     return a.value - b.value; }),
            roseType: 'radius',
            label: {
    
    
              color: 'rgba(255, 255, 255, 0.3)'
            },
            labelLine: {
    
    
              lineStyle: {
    
    
                color: 'rgba(255, 255, 255, 0.3)'
              },
              smooth: 0.2,
              length: 10,
              length2: 20
            },
            itemStyle: {
    
    
              color: '#c23531',
              shadowBlur: 200,
              shadowColor: 'rgba(0, 0, 0, 0.5)'
            },

            animationType: 'scale',
            animationEasing: 'elasticOut',
            animationDelay: function (idx) {
    
    
              return Math.random() * 200
            }
          }
        ]
      })
    })
  }
}
</script>
  • main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import axios from 'axios'
import Echarts from 'echarts'

Vue.prototype.$echarts = Echarts
Vue.prototype.$axios = axios
Vue.use(Element)
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
    
    
  el: '#app',
  router,
  components: {
    
     App },
  template: '<App/>'
})
  • index.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import axios from 'axios'
import Echarts from 'echarts'

Vue.prototype.$echarts = Echarts
Vue.prototype.$axios = axios
Vue.use(Element)
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
    
    
  el: '#app',
  router,
  components: {
    
     App },
  template: '<App/>'
})

Spring Boot 工程

  • pom.xml 导入 MBP 依赖
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.2</version>
</dependency>

<!--代码生成器-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.3.2</version>
</dependency>

<!--模板-->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity</artifactId>
    <version>1.7</version>
</dependency>
  • 代码生成器
package com.liu;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

public class GenerateTest {
    
    
    public static void main(String[] args) {
    
    
        //创建generator对象
        AutoGenerator autoGenerator = new AutoGenerator();
        //数据源
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL);//选择数据库类型
        dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSourceConfig.setUsername("root");
        dataSourceConfig.setPassword("1234");
        dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/test11");
        autoGenerator.setDataSource(dataSourceConfig);//将数据源组装到Generator中
        //全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");
        globalConfig.setAuthor("admin"); //代码生成后会有注释,上面会写作者
        globalConfig.setOpen(false); //项目文件路径是否自动打开
        globalConfig.setServiceName("%sService");
        autoGenerator.setGlobalConfig(globalConfig);
        //包信息
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.liu"); //设置父包
        packageConfig.setEntity("entity");   //设置子包
        packageConfig.setMapper("mapper");
        packageConfig.setService("service");
        packageConfig.setServiceImpl("service.impl");
        packageConfig.setController("controller");
        autoGenerator.setPackageInfo(packageConfig);
        //策略配置  跟数据库相关的东西
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setInclude("fruit"); //相关表
        strategyConfig.setNaming(NamingStrategy.underline_to_camel); //设置实体 下划线转驼峰
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel); //设置字段 下划线转驼峰
        strategyConfig.setEntityLombokModel(true); //自动加lombok
        autoGenerator.setStrategy(strategyConfig);
        //运行
        autoGenerator.execute();
    }
}

在这里插入图片描述

  • application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test11
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl    打印sql语句
  mapper-locations: classpath:com/southwind/mapper/xml/*.xml  把xml扫描进来
server:
  port: 8181
  • 跨域
package com.liu.configuration;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CrosConfiguration implements WebMvcConfigurer {
    
    

    @Override
    public void addCorsMappings(CorsRegistry registry) {
    
    
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("*");
    }
}
  • 没有在yml中配置数据源 导致出错

在这里插入图片描述

  • 跨域

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_51998352/article/details/118060353