前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue 前后端分离项目(二)

Vue 前后端分离项目(二)

原创
作者头像
HLee
修改2021-07-05 14:34:50
3950
修改2021-07-05 14:34:50
举报
文章被收录于专栏:房东的猫房东的猫

简介

Vue项目

代码语言:javascript
复制
启动项目:npm run serve

Router

index.js

代码语言:javascript
复制
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Pie from '../views/Pie.vue'
import Table from '../views/Table.vue'
import Edit from '../views/Edit.vue'
import Add from '../views/Add.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/table',
    name: 'Table',
    component: Table
  },
  {
    path: '/edit',
    name: 'Edit',
    component: Edit
  },
  {
    path: '/add',
    name: 'Add',
    component: Add
  },
  {
    path: '/bar',
    name: 'Bar',
    component: () => import(/* webpackChunkName: "bar" */ '../views/Bar.vue')
  },
  {
    path: '/pie',
    name: 'Pie',
    component: Pie
  }
]

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

export default router

Views

App.vue

http://localhost:8080

代码语言:javascript
复制
<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  components: {
    HelloWorld
  }
}
</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>

Table.vue

http://localhost:8080/table

代码语言:javascript
复制
<template>
    <el-table
            :data="tableData"
            border
            style="width: 100%">
        <el-table-column
                fixed
                prop="id"
                label="编号"
                width="150">
        </el-table-column>
        <el-table-column
                prop="name"
                label="名字"
                width="120">
        </el-table-column>
        <el-table-column
                prop="sale"
                label="销量"
                width="120">
        </el-table-column>
        <el-table-column
                prop="icon"
                label="图片"
                width="120">
            <!-- slot-scope="scope"与:src="scope.row.icon"的scope需要映射起来就行 -->
            <template slot-scope="scope">
                <img :src="scope.row.icon" style="height: 70px"/>
            </template>
        </el-table-column>
        <el-table-column
                fixed="right"
                label="操作"
                width="100">
            <template slot-scope="scope">
                <el-button @click="del(scope.row)" type="text" size="small">删除</el-button>
                <el-button @click="edit(scope.row)"type="text" size="small">编辑</el-button>
            </template>
        </el-table-column>
    </el-table>
</template>

<script>
    export default {
        methods: {
            edit(row) {
                //第一种方式
                // this.$router.push({
                //     path: '/update',
                //     query:{ // 这里写要传的参数
                //         id: row.id
                //     }
                // })
                // 第二种方式
                // row.id
                // console.log(row)
                this.$router.push('/edit?id=' + row.id)
            },
            del(row) {
                let _this = this
                console.log(row.id);
                this.$confirm('是否确定删除 ' + row.name + '?', '删除数据', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    axios.delete('http://localhost:3000/vue-master/fruit/delete/'+row.id).then(function(res){
                        if (res.data) {
                            _this.$alert(row.name + ' 删除成功!', '删除数据', {
                                confirmButtonText: '确定',
                                callback: action => {
                                    // //跳转到/table
                                    // location.reload()
                                    window.location.reload() // 动态刷新
                                }
                            });
                        }
                    })
                }).catch(() => {

                })
            }
        },
        created() {
            let _this = this
            axios.get('http://localhost:3000/vue-master/fruit/findAllFruits').then(function (res) {
                console.log(res)
                _this.tableData = res.data
            })
        },
        data() {
            return {
                tableData: null
            }
        }
    }
</script>

Edit.vue

http://localhost:8080/edit

代码语言:javascript
复制
<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">
            <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>取消</el-button>
        </el-form-item>
    </el-form>
</template>

<script>
    export default {
        name: "Edit",
        data() {
            return {
                fruit: {
                    id: '',
                    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' }
                    ]
                }
            }
        },
        created() {
            let id = this.$route.query.id
            let _this = this
            axios.get('http://localhost:3000/vue-master/fruit/findById/'+id).then(function (response) {
                _this.fruit = response.data
            })
        },
        methods: {
            onSubmit(formName) {
                this.$refs[formName].validate((valid) => {
                    if (valid) {
                        let _this = this
                        axios.put('http://localhost:3000/vue-master/fruit/update',this.fruit).then(function (response) {
                            if(response.data){
                                _this.$alert(_this.fruit.name+'修改成功!', '修改数据', {
                                    confirmButtonText: '确定',
                                    callback: action => {
                                        //跳转到/table
                                        _this.$router.push('/table')
                                    }
                                });
                            }
                        })
                    }
                });
            }
        }
    }
</script>

<style scoped>

</style>

Add.vue

http://localhost:8080/add

代码语言:javascript
复制
<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>取消</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
                        axios.post('http://localhost:3000/vue-master/fruit/add',this.fruit).then(function (response) {
                            if(response.data){
                                _this.$alert(_this.fruit.name+'添加成功!', '添加数据', {
                                    confirmButtonText: '确定',
                                    callback: action => {
                                        //跳转到/table
                                        _this.$router.push('/table')
                                    }
                                });
                            }
                        })
                    }
                });
            }
        }
    }
</script>

<style scoped>

</style>

Bar.vue

http://localhost:8080/bar

代码语言:javascript
复制
<template>
  <div id="myChart" :style="{width: '800px', height: '600px'}"></div>
</template>
<script>
  export default {
    name: 'Echarts',
    data() {
      return{}
    },
    mounted(){
      let _this = this
      axios.get('http://localhost:3000/vue-master/fruit/barVO').then(function (res) {
        // 基于准备好的dom,初始化echarts实例
        let myChart = _this.$echarts.init(document.getElementById('myChart'))
        // 绘制图表
        myChart.setOption({
          title: {
            text: '水果销量统计',
            left: 'center',
            top: 20,
            textStyle: {
              color: '#555555'
            }
          },
          tooltip: {},
          xAxis: {
            // 获取names属性
            data: res.data.names
          },
          yAxis: {},
          series: [{
            name: '销量',
            type: 'bar',
            data: res.data.values
          }]
        });
      })
    }
  }
</script>

Pie.vue

http://localhost:8080/pie

代码语言:javascript
复制
<template>
    <div id="myChart" :style="{width: '800px', height: '600px'}"></div>
</template>
<script>
    export default {
        name: 'Echarts',
        data () {
            return {}
        },
        mounted(){
            let  _this = this
            axios.get('http://localhost:3000/vue-master/fruit/pieVO').then(function (res) {
                console.log(res)
                // 基于准备好的dom,初始化echarts实例
                let myChart = _this.$echarts.init(document.getElementById('myChart'))
                // 绘制图表
                myChart.setOption({
                    backgroundColor: '#2c343c',
                    title: {
                        text: '水果销量统计',
                        left: 'center',
                        top: 20,
                        textStyle: {
                            color: '#3fb1e3'
                        }
                    },
                    tooltip: {
                        trigger: 'item'
                    },
                    visualMap: {
                        show: false,
                        min: 80,
                        max: 600,
                        inRange: {
                            colorLightness: [0, 1]
                        }
                    },
                    series: [
                        {
                            name: '访问来源',
                            type: 'pie',
                            radius: '55%',
                            center: ['50%', '50%'],
                            data: res.data.sort(function (a, b) { return a.value - b.value; }),
                            // data: [
                            //     {
                            //         value: 335,
                            //         name: '直接访问',
                            //         itemStyle: { // 自定义饼状图颜色
                            //             color: "#3fb1e3"
                            //         }
                            //     },
                            //     {value: 310, name: '邮件营销'},
                            //     {value: 274, name: '联盟广告'},
                            //     {value: 235, name: '视频广告'},
                            //     {value: 400, name: '搜索引擎'}
                            // ].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>

SpringBoot项目

Controller层

代码语言:javascript
复制
package com.vue.master.controller;

import com.vue.master.domain.Fruit;
import com.vue.master.service.FruitService;
import com.vue.master.vo.BarVO;
import com.vue.master.vo.PieVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author Huan Lee
 * @version 1.0
 * @date 6/26/21 7:00 PM
 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。
 */
@RestController
@RequestMapping(value = "/fruit")
@Slf4j
public class FruitController {

    @Resource
    private FruitService fruitService;

    /**
     * 获取全部水果
     */
    @RequestMapping(value = "/findAllFruits")
    public List<Fruit> findAllFruits() {
        log.info("获取到了全部的水果");
        return fruitService.findAllFruits();
    }

    /**
     * 删除水果
     *
     */
    @DeleteMapping(value = "/delete/{id}")
    public boolean delete(@PathVariable("id") String id) {

        log.info("删除的水果id为:{}", id);
        String result = fruitService.delete(id);
        if (!result.equals("")) {
            return true;
        }
        return false;
    }

    /**
     * 查询书籍
     *
     */
    @GetMapping(value = "/findById/{id}")
    public Fruit findById(@PathVariable("id") String id) {

        log.info("通过id查询水果信息 :{}", id);
        Fruit result = fruitService.findById(id);
        if (null != result) {
            return result;
        }
        return null;
    }

    /**
     * 修改水果
     *
     */
    @PutMapping(value = "/update")
    public String update(@RequestBody Fruit book) {

        log.info("更新水果:id:{} - name:{} - sale:{}", book.getId(), book.getName(), book.getSale());
        Fruit result = fruitService.update(book);
        if (null != result) {
            return "success";
        }
        return "error";
    }

    /**
     * 新增水果
     *
     */
    @PostMapping(value = "/add")
    public String add(@RequestBody Fruit fruit) {

        log.info("name:{} - id:{}", fruit.getName(), fruit.getId());
        Fruit result = fruitService.add(fruit);
        if (null != result) {
            return "success";
        }
        return "error";
    }

    /**
     * 饼状图
     * @return
     */
    @GetMapping("/barVO")
    public BarVO barVO(){
        return fruitService.barVOList();
    }

    /**
     *
     * @return
     */
    @GetMapping("/pieVO")
    public List<PieVO> pieVO(){
        return fruitService.pieVOList();
    }

}

Service层

代码语言:javascript
复制
package com.vue.master.service;

import com.vue.master.domain.Fruit;
import com.vue.master.vo.BarVO;
import com.vue.master.vo.PieVO;

import java.util.List;

/**
 * @author Huan Lee
 * @version 1.0
 * @date 6/26/21 7:01 PM
 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。
 */
public interface FruitService {

    /**
     * 获取全部水果
     */
    List<Fruit> findAllFruits();

    /**
     * 删除水果
     * @param id
     */
    String delete(String id);

    /**
     * 查询水果
     * @param id
     */
    Fruit findById(String id);

    /**
     * 更新水果
     * @param fruit
     */
    Fruit update(Fruit fruit);

    /**
     * 新增水果
     * @param fruit
     */
    Fruit add(Fruit fruit);

    /**
     *
     * @return
     */
    BarVO barVOList();

    /**
     *
     * @return
     */
    List<PieVO> pieVOList();
}

Impl层

代码语言:javascript
复制
package com.vue.master.impl;

import com.vue.master.domain.Fruit;
import com.vue.master.service.FruitService;
import com.vue.master.util.DateUtil;
import com.vue.master.vo.BarVO;
import com.vue.master.vo.DataVO;
import com.vue.master.vo.PieVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import com.google.common.collect.ImmutableList;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Huan Lee
 * @version 1.0
 * @date 6/26/21 7:02 PM
 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。
 */
@Service
@Slf4j
public class FruitServiceImpl implements FruitService {

    List<Fruit> fruitsList = new ImmutableList.Builder<Fruit>()
            .add(Fruit.builder().id("1").name("苹果").sale(23).icon("https://image.baidu.com/search/detail?ct=503316480&z=undefined&tn=baiduimagedetail&ipn=d&word=%E8%8B%B9%E6%9E%9C%E5%9B%BE%E7%89%87&step_word=&ie=utf-8&in=&cl=2&lm=-1&st=undefined&hd=undefined&latest=undefined&copyright=undefined&cs=3888057658,807170831&os=396816456,2808873952&simid=4242466081,718230718&pn=11&rn=1&di=73920&ln=1548&fr=&fmq=1624710208845_R&fm=&ic=undefined&s=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&is=0,0&istype=0&ist=&jit=&bdtype=0&spn=0&pi=0&gsm=0&objurl=https%3A%2F%2Fgimg2.baidu.com%2Fimage_search%2Fsrc%3Dhttp%253A%252F%252Fimg3.tbcdn.cn%252Ftfscom%252Fi4%252F1598683295%252FTB2NDtzpXXXXXXkXpXXXXXXXXXX_%2521%25211598683295.jpg%26refer%3Dhttp%253A%252F%252Fimg3.tbcdn.cn%26app%3D2002%26size%3Df9999%2C10000%26q%3Da80%26n%3D0%26g%3D0n%26fmt%3Djpeg%3Fsec%3D1627302208%26t%3D122db7d43a0e19080981c53e26c34539&rpstart=0&rpnum=0&adpicid=0&nojc=undefined").build())
//            .add(Fruit.builder().id("2").name("香蕉").sale(67).icon("http://").build())
//            .add(Fruit.builder().id("3").name("火龙果").sale(122).icon("http://").build())
            .add(Fruit.builder().id("4").name("樱桃").sale(178).icon("http://").build())
//            .add(Fruit.builder().id("5").name("芒果").sale(23).icon("http://").build())
            .add(Fruit.builder().id("6").name("草莓").sale(567).icon("http://").build())
            .add(Fruit.builder().id("7").name("香瓜").sale(234).icon("http://").build())
//            .add(Fruit.builder().id("8").name("圣女果").sale(12).icon("http://").build())
            .add(Fruit.builder().id("9").name("榴莲").sale(66).icon("http://").build())
            .add(Fruit.builder().id("10").name("葡萄").sale(367).icon("http://").build())
            .build();

    @Override
    public List<Fruit> findAllFruits() {
        return fruitsList;
    }

    @Override
    public String delete(String id) {
        return id;
    }

    @Override
    public Fruit findById(String id) {
        return Fruit.builder().name("香蕉").sale(2356).id(id).icon("http://localhost:3000").build();
    }

    @Override
    public Fruit update(Fruit fruit) {
        return fruit;
    }

    @Override
    public Fruit add(Fruit fruit) {
        return fruit;
    }

    @Override
    public BarVO barVOList() {

        BarVO barVO = new BarVO();
        List<String> names = new ArrayList<>();
        List<DataVO> values = new ArrayList<>();

        //先查出数据
        List<Fruit> fruits = fruitsList;
        for (Fruit fruit : fruits) {
            names.add(fruit.getName());
            DataVO dataVO = new DataVO();
            dataVO.setValue(fruit.getSale());
            dataVO.setItemStyle(DateUtil.createItemStyle(fruit.getSale()));
            values.add(dataVO);
        }

        barVO.setNames(names);
        barVO.setValues(values);
        return barVO;
    }

    @Override
    public List<PieVO> pieVOList() {
        List<PieVO> pieVOList = new ArrayList<>();
        List<Fruit> fruits = fruitsList;
        for (Fruit fruit : fruits) {
            PieVO pieVO = new PieVO();
            pieVO.setValue(fruit.getSale());
            pieVO.setName(fruit.getName());
            pieVO.setItemStyle(DateUtil.createItemStyle(fruit.getSale()));
            pieVOList.add(pieVO);
        }
        return pieVOList;
    }
}

VO

代码语言:javascript
复制
package com.vue.master.vo;

import lombok.Getter;
import lombok.Setter;

import java.util.List;

/**
 * @author Huan Lee
 * @version 1.0
 * @date 6/27/21 2:13 PM
 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。
 */
@Getter
@Setter
public class BarVO {

    private List<String> names;
    private List<DataVO> values;
}


package com.vue.master.vo;

import lombok.Getter;
import lombok.Setter;

import java.util.Map;

/**
 * @author Huan Lee
 * @version 1.0
 * @date 6/27/21 2:18 PM
 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。
 */
@Getter
@Setter
public class PieVO {

    private Integer value;
    private Map<String,String> itemStyle;
    private String name;
}


package com.vue.master.vo;

import lombok.Getter;
import lombok.Setter;

import java.util.Map;

/**
 * @author Huan Lee
 * @version 1.0
 * @date 6/27/21 2:15 PM
 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。
 */
@Getter
@Setter
public class DataVO {

    private Integer value;
    private Map<String,String> itemStyle;
}

配置文件

代码语言:javascript
复制
spring:
  application:
    name: vue-master #应用程序名称.如:注册eureka上的服务名称

server:
  port: 3000
  servlet:
    context-path: /vue-master  #地址栏调用的服务名

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • Vue项目
    • Router
      • index.js
    • Views
      • App.vue
      • Table.vue
      • Edit.vue
      • Add.vue
      • Bar.vue
      • Pie.vue
  • SpringBoot项目
    • Controller层
      • Service层
        • Impl层
          • VO
            • 配置文件
            相关产品与服务
            邮件推送
            邮件推送(Simple Email Service,SES)是一款基于腾讯云端的平台化服务, 为企业提供安全稳定、简单快速、精准高效的营销、通知和事务邮件的推送服务。产品提供灵活的 IP 部署、电子邮件身份验证以及企业专属定制的启动计划,以保护发件人声誉,同时提供精准智能的数据分析。产品的服务范围覆盖200+国家/地区,可即时触达全球各地的邮箱地址。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档