Day200.ElementUI结合SpringBoot前后端分离小项目 -ElementUI

ElementUI

小项目

项目搭建

  • 前端页面布局

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ircJ0Hlc-1614005800427)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222140002233.png)]


前端搭建

  • 前端脚手架搭建

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CD5M5sAP-1614005800431)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222142705892.png)]

确认项目是否构建成功:进入到项目的根路径

执行npm start

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gL7TfM3A-1614005800433)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210220212300388.png)]

  • 访问localhost:8080
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bXtWhmdE-1614005800436)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222143004278.png)]

代表项目搭建成功!

  • 安装axios

npm install axios --save-dev

  • 在【main.js】中指定当前项目中使用axios
	import axios from 'axios';
	
	Vue.prototype.$http=axios;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qt0fZIGX-1614005800439)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222173258903.png)]

  • 下载elementui的依赖

npm i element-ui -S

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ScEyhcz9-1614005800441)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222142823224.png)]

  • 在【main.js】中指定当前项目中使用elementui
    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';

  //在vue脚手架中使用elementui
	Vue.use(ElementUI);
  • 清理下helloworld组件

  • 创建components/Index.vue组件

.<template>
    <h1>主页</h1>
</template>

router/index.js【注册路由】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jsC6voGR-1614005800443)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222143920199.png)]

访问http://localhost:8080/index

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ADnMycwp-1614005800444)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222143947119.png)]

  • router/index.js【设置默认路由】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fEKjw79C-1614005800446)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222144055492.png)]

  • App.vue【公共导航栏】
<template>
  <div id="app">
    <el-container>
      <el-header>
        <!--导航菜单-->
        <el-menu
          :default-active="activeIndex"
          class="el-menu-demo"
          mode="horizontal"
          @select="handleSelect"
        >
          <el-menu-item index="/index">主页</el-menu-item>
          <el-menu-item index="/users">用户管理</el-menu-item>
          <el-menu-item index="/msgs">消息中心</el-menu-item>
          <el-menu-item index="/orders">订单管理</el-menu-item>
        </el-menu>
      </el-header>
      <el-main>
		<!--展示上面切换的组件-->
        <router-view></router-view>
      </el-main>
    </el-container>
  </div>
</template>

<script>
export default {
    
    
  name: "App",
  data() {
    
    
    return {
    
    
      activeIndex: this.$route.path,
    };
  },
  methods: {
    
    
    handleSelect(key, keyPath) {
    
    
      console.log(key, keyPath);
      //路由切换
      this.$router.push(key);
    },
  },
};
</script>

<style></style>
  • components/index.vue【主页】
.<template>
  <div>
    <el-carousel :interval="4000" type="card" height="400px">
      <!--让他遍历imgs数组里的图片-->
      <el-carousel-item v-for="img in imgs" :key="img">
        <el-image
          style="height: 400px;width: 900px"
          :src="img"
          fit="contain"
        ></el-image>
      </el-carousel-item>
    </el-carousel>  
  </div>
</template>

<script>
//导入图片
import indexImg1 from "../assets/indexImgs/1.jpg";
import indexImg2 from "../assets/indexImgs/2.jpg";
import indexImg3 from "../assets/indexImgs/3.jpg";
import indexImg4 from "../assets/indexImgs/4.jpg";
import indexImg5 from "../assets/indexImgs/5.jpg";
import indexImg6 from "../assets/indexImgs/6.jpg";

export default {
     
     
  name: "Index",
  data() {
     
     
    return {
     
     
      //将上面导入的图片装入imgs数组中
      imgs: [indexImg1, indexImg2, indexImg3, indexImg4, indexImg5, indexImg6],
    };
  },
};
</script>

<style></style>

在这里插入图片描述

  • components/user/List.vue
.<template>
  <div>
    <el-table :data="tableData.filter(data => !search || data.name.toLowerCase().includes(search.toLowerCase()))" style="width: 100%">
      <el-table-column label="编号" width="180">
        <template slot-scope="scope">
          <span style="margin-left: 10px">{
   
   { scope.row.id }}</span>
        </template>
      </el-table-column>
      <el-table-column label="姓名" width="180">
        <template slot-scope="scope">
          <el-popover trigger="hover" placement="top">
            <p>姓名: {
   
   { scope.row.name }}</p>
            <p>住址: {
   
   { scope.row.address }}</p>
            <div slot="reference" class="name-wrapper">
              <el-tag size="medium">{
   
   { scope.row.name }}</el-tag>
            </div>
          </el-popover>
        </template>
      </el-table-column>
      <el-table-column label="生日" value-format="yyyy-MM-dd" prop="bir"> </el-table-column>
      <el-table-column label="性别" prop="sex"> </el-table-column>
      <el-table-column label="地址" prop="address"> </el-table-column>
      <el-table-column align="right">
        <template slot="header" slot-scope="scope">
          <el-input v-model="search" size="mini" placeholder="请输入姓名关键字" />
        </template>
        <template slot-scope="scope">
          <el-button size="mini" @click="handleEdit(scope.$index, scope.row)"
            >编辑</el-button
          >
          <el-button
            size="mini"
            type="danger"
            @click="handleDelete(scope.$index, scope.row)"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <el-button type='success' size='mini' style="margin-top: 10px">添加</el-button>
  </div>
</template>

<script>
export default {
     
     
  name: "List",
  data() {
     
     
    return {
     
     
      tableData: [
        {
     
     
          id: 1,
          name: "王小虎",
          bir: "2016-05-02",
          address: "上海市普陀区金沙江路 1518 弄",
          sex: "男",
        },
        {
     
     
          id: "2",
          name: "郑小昌",
          bir: "2026-05-02",
          address: "温州市普陀区金沙江路 1518 弄",
          sex: "男",
        },
      ],
      search: ''
    };
  },
  methods: {
     
     
    handleEdit(index, row) {
     
     
      console.log(index, row);
    },
    handleDelete(index, row) {
     
     
      console.log(index, row);
    },
  },
};
</script>

<style></style>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-88iyeqc3-1614005800448)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222161519060.png)]


后端搭建

  • 构建Idea项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zVsWrTWw-1614005800450)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222162354639.png)]

  • 构建数据库
CREATE DATABASES elementuser; 

CREATE TABLE t_users(
	id INT(6) PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(80),
	bir DATETIME,
	sex VARCHAR(4),
	address VARCHAR(120)	
)
  • pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.17</version>
</dependency>
  • application.yaml

1、配置项目名

2、配置项目路径

3、配置数据库配置【url、type、driverclass、数据库账户&密码】

4、配置mybatis【mapper文件位置、entity位置】

5、配置服务端口

spring:
  application:
    name: elementusers #项目名
  datasource:
    url: jdbc:mysql://localhost:3306/elementuser?characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false
    type: com.alibaba.druid.pool.DruidDataSource #使用Druid数据连接池
    driver-class-name: com.mysql.jdbc.Driver #数据库驱动
    username: root
    password: '00000'
   resources:
    static-locations: classpath:/static/ #指定静态资源路径
server:
  port: 6161
  servlet:
    context-path: / #项目路径
mybatis:
  mapper-locations: classpath:com.achang.mapper/*.xml  #指定mapper文件位置
  type-aliases-package: com.achang.entity #指定entity位置
  • entity/User
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Accessors(chain = true)//开启链式调用
public class User {
    
    
    private String id;
    private String name;
    
    //设置日期格式,pattern格式化格式,timezone时区:我们在东八区
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GTM+8")
    private Date bir;
    
    private String sex;
    private String address;
}

查询所有

  • UserDao
@Mapper
public interface UserDao {
    
    
    //查询所有用户信息
    List<User> findAll();
}
  • mapper.xml
<mapper namespace="com.achang.dao.UserDao">
    <select id="findAll" resultType="User" >
        select id,name,bir,sex,address from t_users
    </select>
</mapper>
  • service/Userservice
public interface UserService {
    
    
    //查询所有用户信息
    List<User> findAll();
}
  • service/impl/UserServiceImpl
@Service
@Transactional
public class UserServiceImpl implements UserService {
    
    

    @Autowired
    private UserDao userDao;

    @Override
    public List<User> findAll() {
    
    
        return userDao.findAll();
    }
}
  • 测试:testFindAll()
@SpringBootTest
class ElementusersApplicationTests {
    
    
    @Autowired
    private UserService userService;

    @Test
    void testFindAll() {
    
    
        for (User user : userService.findAll()) {
    
    
            System.out.println(user);
        }
    }
}
  • UserController,findAll()
@RestController
@RequestMapping("/user")
@CrossOrigin //解决跨域问题
public class UserController {
    
    
    @Autowired
    private UserService userService;

    @GetMapping("/findAll")
    public List<User> findAll(){
    
    
        return userService.findAll();
    }
    
}
  • 测试,访问:http://localhost:6161/user/findAll

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F4BcqzeC-1614005800451)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222172705812.png)]


  • 前端components/users/List.vue发送axios请求获取数据,created()
    created(){
    
    
      this.$http.get("http://localhost:6161/user/findAll").then(function(resp){
    
    
        console.info(response.data);
        this.tableData=resp.data;
      })
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t2U0C7s5-1614005800452)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222193337210.png)]


添加功能

  • UserDao
//保存用户信息
void save(User user);
  • mapper/UserDaoMapper.xml
<insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">
    insert into t_users
    values (#{id},#{name},#{bir},,#{sex},#{address})
</insert>
  • service/UserService
//保存用户信息
void save(User user);
  • service/impl/UserServiceImpl
@Override
public void save(User user) {
    
    
    userDao.save(user);
}
  • 测试save()
@Test
void testSave(){
    
    
    userService.save(new User("2","阿昌",new Date(),"男","浙江省欧洲市"));
}
  • 创建一个给前端返回状态类vo/Result
@Data
public class Result {
    
    
    private Boolean status = true;
    private String msg;
}
  • UserController
//保存用户
@PostMapping("/save")
public Result save(@RequestBody User user){
    
    
    Result result = new Result();
    try {
    
    
        userService.save(user);
        result.setMsg("用户数据保存成功!");
    } catch (Exception e) {
    
    
        e.printStackTrace();
        result.setStatus(false);
        result.setMsg("用户数据保存失败!");

    }
    return result;
}
  • 前端components/users/List.vue发送axios请求获取数据,onSubmit()
onSubmit() {
    
    
    console.log("submit!");
    //发送一个axios请求
    let _this = this;
    this.$http
        .post("http://localhost:6161/user/save", this.form)
        .then(function (resp) {
    
    
        console.log(resp.data);
        if (resp.data.status) {
    
    
            _this.$message({
    
    
                message: "保存成功!! " + resp.data.msg,
                type: "success",
            });
            //清空表单信息
            _this.form = {
    
    sex:'男'};
            //隐藏表单
            _this.show3 = false;
            //刷新表单
            _this.findAll();
        } else {
    
    
            _this.$message({
    
    
                message: "保存失败 " + resp.data.msg,
                type: "error",
            });
        }
    });
}
  • 将上面的查询所有用户信息封装成一个方法,findAll()
    findAll() {
    
    
      let _this = this;
      this.$http
        .get("http://localhost:6161/user/findAll")
        .then(function (resp) {
    
    
          console.info(resp.data);
          _this.tableData = resp.data;
        });
    },
  • 查询所有的axios请求
  created() {
    
    
    this.findAll();
  },

删除功能

  • UserDao
//根据id删除用户
void delete(String id);
  • UserDaoMapper.xml
<delete id="delete" parameterType="String">
    delete from t_users where id = #{id}
</delete>
  • UserService
//根据id删除用户
void delete(String id);
  • service/impl/UserServiceImpl
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public void delete(String id) {
    
    
    userDao.delete(id);
}
  • 测试delete()
@Test
void testDelete(){
    
    
    userService.delete("18");
}
  • UserController
//根据id删除用户
@GetMapping("/delete")
public Result delete(String  id){
    
    
    Result result = new Result();

    try {
    
    
        userService.delete(id);
        result.setMsg("用户数据删除成功!");
    } catch (Exception e) {
    
    
        e.printStackTrace();
        result.setStatus(false);
        result.setMsg("用户数据删除失败!");
    }
    return result;
}
  • 前端页面修改
<el-popconfirm
               confirm-button-text="好的"
               cancel-button-text="不用了"
               icon="el-icon-info"
               icon-color="red"
               title="你确定要删除吗?"
               @confirm=handleDelete(scope.$index,scope.row)
               >
    <el-button
               slot="reference"
               size="mini"
               type="danger"
               >删除</el-button
        >
</el-popconfirm>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lUi0Yc3Q-1614005800454)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222201333429.png)]

  • 前端handleDelete()
handleDelete(index, row) {
    
    
    console.log(index, row);
    //发送axios请求处理删除
    let _this = this;
    this.$http
        .get("http://localhost:6161/user/delete?id=" + row.id)
        .then(function (resp) {
    
    
        if (resp.data.status) {
    
    
            _this.$message({
    
    
                message: "删除成功!! " + resp.data.msg,
                type: "success",
            });
            //刷新表单
            _this.findAll();
        } else {
    
    
            _this.$message({
    
    
                message: "删除失败 " + resp.data.msg,
                type: "error",
            });
        }
    });
}

修改功能

  • saveUserInfo()
saveUserInfo(){
    
    
    //打开表单弹窗
    this.show3=!this.show3;

    //清空添加表单
    this.form={
    
    sex: "男"};
}

在这里插入图片描述

  • UserDao
    //更新用户信息
    void update(User user);
  • UserService
    //更新用户信息
    void update(User user);
  • UserServiceImpl
@Override
public void update(User user) {
    
    
    userDao.update(user);
}
  • UserController,保存和修改方法合一
    //保存或修改用户
    @PostMapping("/saveOrUpdate")
    public Result save(@RequestBody User user) {
    
    
        Result result = new Result();
        try {
    
    
            if (StringUtils.isEmpty(user.getId())) {
    
    
                userService.update(user);
                result.setMsg("用户数据编辑成功!");
            } else {
    
    
                userService.save(user);
                result.setMsg("用户数据保存成功!");
            }
        }
        catch (Exception e){
    
    
            result.setStatus(false);
            result.setMsg("用户数据保存或修改操作失败!");
        }
        return result;
    }
  • 保存按钮的前端axios请求修改

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c7WOw4Z6-1614005800458)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222205240673.png)]


表单验证

  • 异步验证

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RDF1pC9x-1614005800459)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222210205488.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O5oAYJ7h-1614005800460)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222210223695.png)]

  • 审核验证

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hhcy9rKL-1614005800461)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222211758207.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7M4Ohcsj-1614005800462)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222211930704.png)]


分页组件

  • UserDao
//分页查询
List<User> findPage(@Param("start")Integer start,@Param("rows")Integer rows);

//查询总条数
Long findTotals();
  • UserDaoMapper.xml
<select id="findPage" resultType="User">
    select id,name,bir,sex,address
    from t_users limit #{start},#{rows}
</select>

<select id="findTotals" resultType="long">
    select count(id) from t_users
</select>
  • UserService
//分页查询
List<User> findPage(Integer pageNow, Integer rows);

//查询总条数
Long findTotals();
  • UserServiceImpl
@Override
public List<User> findPage(Integer pageNow, Integer rows) {
    
    
    int start = (pageNow - 1)*rows;
    return userDao.findPage(start,rows);
}

@Override
public Long findTotals() {
    
    
    return userDao.findTotals();
}
  • UserController
//分页查询的方法
@GetMapping("/findByPage")
public Map<String, java.lang.Object> findByPage(Integer pageNow, Integer pageSize){
    
    
    Map<String, Object> result = new HashMap<>();
    pageNow = pageNow ==null?1:pageNow;
    pageSize = pageSize==null?4:pageSize;
    List<User> users = userService.findPage(pageNow, pageSize);
    Long totals = userService.findTotals();

    result.put("users",users);
    result.put("total",totals);


    return result;
}
  • 前端页面
    <el-row>
      <el-col :span="12" :offset="12">
        <!--分页组件-->
        <el-pagination
          layout="prev, pager, next,jumper,total,sizes"
          :total="total"
          :page-size="size"
          :current-page="pageNow"
          :page-sizes=[2,4,6,8,10]
          prev-text="上一页"
          next-text="下一页"
          background
          small
          @current-change="findPage"
          @size-change="findSize"

        >
        </el-pagination
      ></el-col>
    </el-row>
   
<script>
export default {
     
     
  name: "List",
  data() {
     
     
    return {
     
     
      total:0,
      size:4,
      pageNow:1,
    }
  },
  methods: {
     
     
    //处理相关分页方法
    findPage(page){
     
     
      this.page=page;
      this.findAll(page,this.size);
    },
    findSize(size){
     
     
      this.size=size;
      this.findAll(this.page,size);
    },
    findAll(page,size) {
     
     
      page = page?page:this.pageNow
      size = size?size:this.size
      let _this = this;
      this.$http
        .get("http://localhost:6161/user/findByPage?pageNow="+page+"&pageSize="+size)
        .then(function (resp) {
     
     
          console.info(resp.data);
          _this.tableData = resp.data.users;
          _this.total=resp.data.total;
        });
    },
  },
  created() {
     
     
    this.findAll();
  },
};
</script>

<style></style>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uGNncbhA-1614005800463)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222221315055.png)]


打包部署

  • 在有package.json目录下执行,npm run build

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ysVayGti-1614005800464)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222221848923.png)]

  • 生成dist目录

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aBc0wXmz-1614005800465)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222222032337.png)]

  • 将dist目录下的文件部署到后端即可,拉到后端static文件文件夹下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jsSVT7jF-1614005800466)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222222149316.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nBhQd5TZ-1614005800467)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210222224006690.png)]

  • 访问:http://localhost:6161
  • 效果
    在这里插入图片描述
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43284469/article/details/113960908
今日推荐