ElementUI
小项目
项目搭建
- 前端页面布局
前端搭建
- 前端脚手架搭建
确认项目是否构建成功:进入到项目的根路径
执行npm start
- 访问
localhost:8080
代表项目搭建成功!
- 安装axios
npm install axios --save-dev
- 在【main.js】中指定当前项目中使用axios
import axios from 'axios';
Vue.prototype.$http=axios;
- 下载elementui的依赖
npm i element-ui -S
- 在【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【注册路由】
访问http://localhost:8080/index
- router/index.js【设置默认路由】
- 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>
后端搭建
- 构建Idea项目
- 构建数据库
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
- 前端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;
})
}
添加功能
- 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>
- 前端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请求修改
表单验证
- 异步验证
- 审核验证
分页组件
- 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>
打包部署
- 在有
package.json
目录下执行,npm run build
- 生成dist目录
- 将dist目录下的文件部署到后端即可,拉到后端static文件文件夹下
- 访问:
http://localhost:6161
- 效果