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

Vue 前后端分离项目(一)

原创
作者头像
HLee
修改2021-06-28 14:50:32
1.6K1
修改2021-06-28 14:50:32
举报
文章被收录于专栏:房东的猫

简介

Vue项目

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

Vue访问永远都是App.vue,然后用<router-view></router-view>开启了一个小窗口进行页面路由,相当于一个容器,用来动态渲染你选择的router。

Router

index.js

代码语言:javascript
复制
import Vue from 'vue'
import VueRouter from 'vue-router'
import BookManage from '../views/BookManage.vue'  // 后缀vue可以省略
import BookAdd from '../views/BookAdd.vue'
import BookUpdate from '../views/BookUpdate.vue'
import PageThree from '../views/PageThree.vue'
import PageFour from '../views/PageFour.vue'
import Index from '../views/Index.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: '图书管理',
    component: Index,
    show: true,
    redirect: '/BookManage',
    children: [ // 子页面
      {
        path: '/BookManage',
        name: '查询图书',
        component: BookManage
      },
      {
        path: '/BookAdd',
        name: '添加图书',
        component: BookAdd
      }
    ]
  },
  {
    path:'/BookUpdate',
    component:BookUpdate,
    show:false
  },
  {
    path: '/navigation',
    name: '导航2',
    show: true,
    component: Index,
    children: [ // 子页面
      {
        path: '/PageThree',
        name: '导航2-页面1',
        component: PageThree
      },
      {
        path: '/PageFour',
        name: '导航2-页面2',
        component: PageFour
      }
    ]
  }
]

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

export default router

Views

App.vue

代码语言:javascript
复制
<!--template只允许有一个div-->
<template>
  <div id="app">
    <el-container style="height: 500px; border: 1px solid #eee">
      <el-aside width="200px" style="background-color: rgb(238, 241, 246)">
        <!--动态设定导航栏:menu与router进行绑定-->
        <!--要实现路由跳转,先要在el-menu标签上添加router属性,然后只要在每个el-menu-item标签内的index属性设置一下url即可实现点击el-menu-item实现路由跳转。-->
        <el-menu router :default-openeds="['0']">
          <!--这里的index指的是下标 从0开始计算 -->
          <el-submenu v-for="(item, index) in $router.options.routes" :index="index+''" v-if="item.show">
            <template slot="title"><i class="el-icon-message"></i>{{item.name}}</template>
            <!-- <el-menu-item>标签中的index值就是要跳转的router -->
            <!-- <el-menu-item>标签中的class属性用来控制导航栏的选中(route.path:指的是地址栏的path)-->
            <el-menu-item v-for="(item2, index2) in item.children" :index="item2.path" :class="$route.path==item2.path?'is-active':''">{{item2.name}}</el-menu-item>
          </el-submenu>
        </el-menu>
      </el-aside>
      <el-main>
        <!-- 路由匹配到的组件将显示在这里,相当于一个容器,用来动态渲染你选择的router -->
        <router-view></router-view>
      </el-main>
    </el-container>
  </div>
</template>

<style>
  .el-header {
    background-color: #B3C0D1;
    color: #333;
    line-height: 60px;
  }

  .el-aside {
    color: #333;
  }
</style>

<script>
  export default {
    data() {
      const item = {
        date: '2016-05-02',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1518 弄'
      };
      return {
        tableData: Array(20).fill(item)
      }
    }
  };
</script>

说明:<template>下只能有一个根结点

  • default-openeds="['0']"指的是默认打开
  • <el-menu-item>标签中的index值就是要跳转的router页面
  • <el-menu-item>标签中的class属性用来控制导航栏的选中(route.path:指的是地址栏的path),当地址栏中的path和item2.path相等时,变为选中

Index.vue

代码语言:javascript
复制
<template>
    <!-- 路由匹配到的组件将显示在这里 -->
    <router-view></router-view>
</template>

<script>
    export default {
        name: "Index"
    }
</script>

<style scoped>

</style>

BookManage.vue

代码语言:javascript
复制
<template>
    <div>
        <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="520">
            </el-table-column>
            <el-table-column
                    prop="author"
                    label="作者"
                    width="120">
            </el-table-column>
            <el-table-column
                    fixed="right"
                    label="操作"
                    width="100">
                <template slot-scope="scope">
                    <el-button @click="edit(scope.row)" type="text" size="small">修改</el-button>
                    <el-button @click="deleteBook(scope.row)" type="text" size="small">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <el-pagination
                background
                layout="prev, pager, next"
                :page-size="5"
                :total=total
                @current-change="page">
        </el-pagination>
    </div>
</template>

<script>
    export default {
        methods: {
            edit(row) {
                this.$router.push({
                    path: '/BookUpdate',
                    query:{ // 这里写要传的参数
                        id: row.id
                    }
                })
                // row.id
                // console.log(row)
            },
            deleteBook(row) {
                const _this = this
                axios.delete('http://localhost:3000/vue-master/book/delete/'+row.id).then(function(resp){
                    _this.$alert('《'+row.name+'》删除成功!', '消息', {
                        confirmButtonText: '确定',
                        callback: action => {
                            window.location.reload() // 动态刷新
                        }
                    })
                })
            },
            page(curentPage) {
                // alert(curentPage)
                const _this = this
                axios.get('http://localhost:3000/vue-master/book/findAll?page=' + curentPage + '&size=5').then(function (resp) {
                    console.log(resp)
                    _this.tableData = resp.data.content
                    _this.total = resp.data.total
                })
            }
        },
        created() {
            const _this = this
            axios.get('http://localhost:3000/vue-master/book/findAll?page=1&size=5').then(function (resp) {
                console.log(resp)
                _this.tableData = resp.data.content
                _this.total = resp.data.total
            })
        },
        data() {
            return {
                total: null,
                tableData: null
            }
        }
    }
</script>

说明:

  • 页面一加载就会去默认执行created()方法获取后端服务数据

BookAdd.vue

代码语言:javascript
复制
<template>
    <el-form style="width: 60%" :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
        <el-alert
                title="成功提示的文案"
                type="success"
                show-icon>
        </el-alert>
        <el-form-item label="图书名称" prop="name">
            <el-input v-model="ruleForm.name"></el-input>
        </el-form-item>
        <el-form-item label="作者" prop="author">
            <el-input v-model="ruleForm.author"></el-input>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
            <el-button @click="resetForm('ruleForm')">重置</el-button>
        </el-form-item>
    </el-form>
</template>
<script>
    export default {
        data() {
            return {
                ruleForm: {
                    name: '',
                    author: ''
                },
                rules: {
                    name: [
                        {required: true, message: '请输入活动名称', trigger: 'blur'}, // required: true(必填)trigger:触发事件  blur失去焦点
                        {min: 1, max: 15, message: '长度在 1 到 15 个字符', trigger: 'blur'}
                    ],
                    author: [
                        {required: true, message: '请选择活动区域', trigger: 'blur'}
                    ]
                }
            };
        },
        methods: {
            submitForm(formName) {
                const _this = this
                this.$refs[formName].validate((valid) => {
                    if (valid) {
                        console.log(_this.ruleForm)
                        // alert('校验通过');
                        axios.post('http://localhost:3000/vue-master/book/saveBook', this.ruleForm).then(function (resp) {
                            console.log(resp)
                            if (resp.data == 'success') {
                                // alert('添加成功');
                                // _this.$message('添加成功');  // 提示一条信息
                                // _this.$router.push('/BookManage') // 添加成功后跳转到BookManage页面
                                _this.$alert('《' + _this.ruleForm.name + '》添加成功!', '消息', {
                                    confirmButtonText: '确定',
                                    callback: action => {
                                        _this.$router.push('/BookManage')
                                    }
                                });
                            }
                        })
                    } else {
                        console.log('校验未通过');
                        return false;
                    }
                });
            },
            resetForm(formName) {
                this.$refs[formName].resetFields();
            }
        }
    }
</script>

说明:

  • :model="ruleForm"是用来绑定对象数组,根据v-model="ruleForm.name"是用来绑定某一个字段
  • :rules="rules"是用来绑定校验规则,根据prop="name"用来校验某一个选项的规则
    • trigger:'blur' 触发事件, blur失去焦点
    • required: true是否必填项
    • message: '请输入活动名称'提示信息

BookUpdate.vue

代码语言:javascript
复制
<template>
    <el-form style="width: 60%" :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
        <el-alert
                title="成功提示的文案"
                type="success"
                show-icon>
        </el-alert>
        <el-form-item label="图书编号" prop="id">
            <el-input v-model="ruleForm.id" readOnly></el-input>
        </el-form-item>
        <el-form-item label="图书名称" prop="name">
            <el-input v-model="ruleForm.name"></el-input>
        </el-form-item>
        <el-form-item label="作者" prop="author">
            <el-input v-model="ruleForm.author"></el-input>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="submitForm('ruleForm')">修改</el-button>
            <el-button @click="resetForm('ruleForm')">重置</el-button>
        </el-form-item>
    </el-form>
</template>

<script>
    export default {
        data() {
            return {
                ruleForm: {
                    id: '1',
                    name: '1212',
                    author: '23323'
                },
                rules: {
                    name: [
                        {required: true, message: '请输入活动名称', trigger: 'blur'}, // trigger:触发事件  blur失去焦点
                        {min: 1, max: 15, message: '长度在 1 到 15 个字符', trigger: 'blur'}
                    ],
                    author: [
                        {required: true, message: '请选择活动区域', trigger: 'blur'}
                    ]
                }
            };
        },
        methods: {
            submitForm(formName) {
                const _this = this
                this.$refs[formName].validate((valid) => {
                    if (valid) {
                        console.log(_this.ruleForm)
                        // alert('校验通过');
                        axios.put('http://localhost:3000/vue-master/book/update', this.ruleForm).then(function (resp) {
                            console.log(resp)
                            if (resp.data == 'success') {
                                // alert('添加成功');
                                // _this.$message('添加成功');  // 提示一条信息
                                // _this.$router.push('/BookManage') // 添加成功后跳转到BookManage页面
                                _this.$alert('《' + _this.ruleForm.name + '》修改成功!', '消息', {
                                    confirmButtonText: '确定',
                                    callback: action => {
                                        _this.$router.push('/BookManage')
                                    }
                                });
                            }
                        })
                    } else {
                        console.log('校验未通过');
                        return false;
                    }
                });
            },
            resetForm(formName) {
                this.$refs[formName].resetFields();
            }
        },
        created() {
            // 拿到edit传过来的id参数
            // alert(this.$route.query.id)
            const _this = this
            // this.$route.query.id 选参数用$route这个
            // this.$router.push 跳转用$router这个
            axios.get('http://localhost:3000/vue-master/book/findById/'+this.$route.query.id).then(function(resp){
                _this.ruleForm = resp.data
            })
        }
    }
</script>

说明:

PageThree.vue

代码语言:javascript
复制
<template>
    <h1>这是页面四</h1>
</template>

<script>
    export default {
        name: "PageFour"
    }
</script>

<style scoped>

</style>

PageFour.vue

代码语言:javascript
复制
<template>
    <h1>这是页面四</h1>
</template>

<script>
    export default {
        name: "PageFour"
    }
</script>

<style scoped>

</style>

SpringBoot项目

Controller层

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

import com.vue.master.domain.Book;
import com.vue.master.service.BookService;
import com.vue.master.vo.PageInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

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


    @Resource
    private BookService bookService;

    /**
     * 查找全部书籍
     * @return
     */
    @GetMapping(value = "/findAll")
    public PageInfoVO findAll(@RequestParam Integer page, @RequestParam Integer size) {
        log.info("********** findAll ************");
        return bookService.findAll(page, size);
    }

    /**
     * 新增书籍
     *
     */
    @PostMapping(value = "/saveBook")
    public String saveBook(@RequestBody Book book) {

        log.info("name:{} - author:{}", book.getName(), book.getAuthor());
        Book result = bookService.saveBook(book);
        if (null != result) {
            return "success";
        }
        return "error";
    }

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

        log.info("id :{}", id);
        Book result = bookService.findById(id);
        if (null != result) {
            return result;
        }
        return null;
    }

    /**
     * 修改书籍
     *
     */
    @PutMapping(value = "/update")
    public String update(@RequestBody Book book) {

        log.info("id:{} - name:{} - author:{}", book.getId(), book.getName(), book.getAuthor());
        Book result = bookService.saveBook(book);
        if (null != result) {
            return "success";
        }
        return "error";
    }

    /**
     * 删除书籍书籍
     *
     */
    @DeleteMapping(value = "/delete/{id}")
    public String delete(@PathVariable("id") String id) {

        log.info("id :{}", id);
        String result = bookService.delete(id);
        if (!result.equals("")) {
            return "success";
        }
        return "error";
    }
}

Service层

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

import com.vue.master.domain.Book;
import com.vue.master.vo.PageInfoVO;


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


    /**
     * 查找全部书
     * @param page
     * @param size
     * @return
     */
    PageInfoVO findAll(Integer page, Integer size);

    /**
     * 新增书籍
     * @param book
     */
    Book saveBook(Book book);

    /**
     * 查询书籍
     * @param id
     */
    Book findById(String id);

    /**
     * 更新书籍
     * @param book
     */
    Book update(Book book);

    /**
     * 删除书籍
     * @param id
     */
    String delete(String id);
}

Impl层

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

import com.vue.master.domain.Book;
import com.vue.master.service.BookService;
import com.vue.master.vo.PageInfoVO;
import lombok.extern.slf4j.Slf4j;

import com.google.common.collect.ImmutableList;
import org.springframework.stereotype.Service;

import java.util.List;

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


    @Override
    public PageInfoVO findAll(Integer page, Integer size) {

        List<Book> bookList = new ImmutableList.Builder<Book>()
                .add(Book.builder().id("1").name("21天精通Java").author("张子枫").build())
                .add(Book.builder().id("2").name("21天精通Python").author("周海媚").build())
                .add(Book.builder().id("3").name("21天精通Vue").author("李子茹").build())
                .add(Book.builder().id("4").name("21天精通C++").author("王万里").build())
                .add(Book.builder().id("5").name("21天精通PHP").author("王万里").build())
                .add(Book.builder().id("6").name("21天精通Go").author("王万里").build())
                .add(Book.builder().id("7").name("21天精通Thread").author("王万里").build())
                .add(Book.builder().id("8").name("21天精通Elasticsearch").author("王万里").build())
                .add(Book.builder().id("9").name("21天精通Lucene").author("王万里").build())
                .add(Book.builder().id("10").name("21天精通Html").author("王万里").build())
                .build();

        Integer from = (page - 1) * size;
        Integer to = page * size;

        PageInfoVO pageInfoVO = PageInfoVO.builder()
                .page(page)
                .size(size)
                .total(bookList.size())
                .content(bookList.subList(from, to))
                .build();

        return pageInfoVO;
    }

    @Override
    public Book saveBook(Book book) {
        return book;
    }


    @Override
    public Book findById(String id) {
        return Book.builder().author("李欢").name("你好 Book").id(id).build();
    }

    @Override
    public Book update(Book book) {
        return book;
    }

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

Domain

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

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

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

    private String id;
    private String name;
    private String author;
}

VO

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

import com.vue.master.domain.Book;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

import java.util.List;

/**
 * @author Huan Lee
 * @version 1.0
 * @date 6/10/21 8:56 PM
 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。
 */
@Getter
@Setter
@Builder
public class PageInfoVO {

    Integer page;
    Integer size;
    Integer total;
    List<Book> content;
}

配置文件

代码语言: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
      • Index.vue
      • BookManage.vue
      • BookAdd.vue
      • BookUpdate.vue
      • PageThree.vue
      • PageFour.vue
  • SpringBoot项目
    • Controller层
      • Service层
        • Impl层
          • Domain
            • VO
              • 配置文件
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档