最近想学关于vuejs 和 element ui ,趁着工作之余开发了一个在线相册的项目,功能有 注册,登录,预览,各种中心,图片上传,我的资源,图片编辑等,,在此做一个分享吧。
Git 地址 :https://github.com/ryz-13997318136/photoalbum.git
https://github.com/ryz-13997318136/photoalbum.git
https://github.com/ryz-13997318136/photoalbum.git
https://github.com/ryz-13997318136/photoalbum.git
1 界面预览
1.1 注册页面
1.2 主页
1.3 个人中心
1.4 图片上传界面
1.5 我的资源
1.6 资源编辑
2 好了界面大概就这样的,很简单,其中大量的使用了 element ui,我觉得它是一个非常不错的css库,界面简洁,风格一致。很多控件他给我们做好了,我们只管使用,这种库文件很适合做某某网站的后台管理系统。好了下面开始贴代码
2.1 启动类
@ComponentScan(basePackages="com.ryz.photoalbum") @EntityScan(basePackages="com.ryz.photoalbum.pojo") @EnableJpaRepositories(basePackages="com.ryz.photoalbum.repository") @SpringBootApplication public class PhotoalbumApplication { public static void main(String[] args) { SpringApplication.run(PhotoalbumApplication.class, args); } }
2.2 项目配置文件
spring.application.name=photo server.servlet.context-path=/photo server.port=8081 # 数据源配置 spring.datasource.url=jdbc:log4jdbc:mysql://118.25.65.113:3306/study spring.datasource.username=root spring.datasource.password=157123123 spring.datasource.driverClassName = net.sf.log4jdbc.DriverSpy spring.jpa.database = MYSQL spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql = true spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect # 定位模板的目录 spring.mvc.view.prefix=classpath:/templates/ # 给返回的页面添加后缀名 spring.mvc.view.suffix=.html spring.thymeleaf.cache=false basePath=D:\\image\\
2.3 系统控制层 ,用来处理首页的请求
@Controller @RequestMapping("/index") public class SysController { @Autowired UserService userService; @RequestMapping(value="/",method = RequestMethod.GET) public String index(Model model){ return "index"; } @RequestMapping(value="/main",method = RequestMethod.GET) public ModelAndView mian(String id){ ModelAndView view = new ModelAndView(); view.setViewName("main"); view.addObject("cUser",userService.findPUserById(id)); return view; } }
2.4 文件控制层,用来处理文件的上传,下载,编辑,删除的请求
@Controller @RequestMapping("/file") @Configuration public class FileController { @Resource private ResourceLoader resourceLoader; @Autowired private ImageService imageService; @Value("${basePath}") private String basePath; @RequestMapping("/upload") @ResponseBody public String handleFileUpload(@RequestParam("file")MultipartFile file, String userId){ if(file.isEmpty()){ return "FAIL"; } SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); String location =df.format(new Date()) + System.getProperty("file.separator"); // 判断文件夹是否存在,不存在则 basePath = "all_image"+System.getProperty("file.separator"); File targetFile = new File(basePath + location); if(!targetFile.exists()){ targetFile.mkdirs(); } String fileName = file.getOriginalFilename(); fileName = fileName.length()>10?fileName.substring(fileName.length()-10):fileName; String url =""; try{ Files.copy(file.getInputStream(), Paths.get(basePath + location, fileName), StandardCopyOption.REPLACE_EXISTING); url = location + fileName; }catch (Exception e){ e.printStackTrace(); } PImage image = new PImage(); image.setId(String.valueOf(System.currentTimeMillis())); image.setUserId(userId); image.setImageName(fileName); image.setImageUrl(url); imageService.save(image); return url; } @RequestMapping(value="/{filePath}/{filename}",method = RequestMethod.GET) @ResponseBody public ResponseEntity> getFile(@PathVariable String filePath,@PathVariable String filename) { System.out.println("filePath----------------"+filePath); System.out.println("filename--------------"+filename); basePath = "all_image"+System.getProperty("file.separator"); System.out.println("basePath-------------"+ basePath); ResponseEntity.ok().contentType(MediaType.IMAGE_PNG); String os = System.getProperty("os.name"); if(os.toLowerCase().startsWith("win")){ return ResponseEntity.ok(resourceLoader.getResource("file:" + Paths.get(basePath +filePath+"\\"+ filename).toString())); }else{ File file = new File("/usr/photoalbum/all_image/2018-06-04/22.png"); return ResponseEntity.ok(resourceLoader.getResource("file:" + Paths.get("/usr/photoalbum/all_image/" +filePath+"/"+ filename).toString())); } } @RequestMapping(value="/getImageByUserId",method = RequestMethod.GET) @ResponseBody public ListgetImageByUserId(@RequestParam String userId){ return imageService.getImageByUserId(userId); } @RequestMapping(value="/getRandomImages",method = RequestMethod.GET) @ResponseBody public List getRandomImages(@RequestParam String userId,@RequestParam String model){ return imageService.getRandomImages(userId,model); } @RequestMapping(value="/editDesc",method = RequestMethod.GET) @ResponseBody public void editDesc(@RequestParam String id,@RequestParam String desc,@RequestParam String name){ imageService.editDesc(id,desc,name); } @RequestMapping(value="/deleteImageById",method = RequestMethod.GET) @ResponseBody public void deleteImageById(@RequestParam String id){ imageService.deleteImageById(id); } }
2.5 用户控制层,用来处理用户的注册,登录,登出,用户修改请求
@Controller @RequestMapping("/file") @Configuration public class FileController { @Resource private ResourceLoader resourceLoader; @Autowired private ImageService imageService; @Value("${basePath}") private String basePath; @RequestMapping("/upload") @ResponseBody public String handleFileUpload(@RequestParam("file")MultipartFile file, String userId){ if(file.isEmpty()){ return "FAIL"; } SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); String location =df.format(new Date()) + System.getProperty("file.separator"); // 判断文件夹是否存在,不存在则 basePath = "all_image"+System.getProperty("file.separator"); File targetFile = new File(basePath + location); if(!targetFile.exists()){ targetFile.mkdirs(); } String fileName = file.getOriginalFilename(); fileName = fileName.length()>10?fileName.substring(fileName.length()-10):fileName; String url =""; try{ Files.copy(file.getInputStream(), Paths.get(basePath + location, fileName), StandardCopyOption.REPLACE_EXISTING); url = location + fileName; }catch (Exception e){ e.printStackTrace(); } PImage image = new PImage(); image.setId(String.valueOf(System.currentTimeMillis())); image.setUserId(userId); image.setImageName(fileName); image.setImageUrl(url); imageService.save(image); return url; } @RequestMapping(value="/{filePath}/{filename}",method = RequestMethod.GET) @ResponseBody public ResponseEntity> getFile(@PathVariable String filePath,@PathVariable String filename) { System.out.println("filePath----------------"+filePath); System.out.println("filename--------------"+filename); basePath = "all_image"+System.getProperty("file.separator"); System.out.println("basePath-------------"+ basePath); ResponseEntity.ok().contentType(MediaType.IMAGE_PNG); String os = System.getProperty("os.name"); if(os.toLowerCase().startsWith("win")){ return ResponseEntity.ok(resourceLoader.getResource("file:" + Paths.get(basePath +filePath+"\\"+ filename).toString())); }else{ File file = new File("/usr/photoalbum/all_image/2018-06-04/22.png"); return ResponseEntity.ok(resourceLoader.getResource("file:" + Paths.get("/usr/photoalbum/all_image/" +filePath+"/"+ filename).toString())); } } @RequestMapping(value="/getImageByUserId",method = RequestMethod.GET) @ResponseBody public ListgetImageByUserId(@RequestParam String userId){ return imageService.getImageByUserId(userId); } @RequestMapping(value="/getRandomImages",method = RequestMethod.GET) @ResponseBody public List getRandomImages(@RequestParam String userId,@RequestParam String model){ return imageService.getRandomImages(userId,model); } @RequestMapping(value="/editDesc",method = RequestMethod.GET) @ResponseBody public void editDesc(@RequestParam String id,@RequestParam String desc,@RequestParam String name){ imageService.editDesc(id,desc,name); } @RequestMapping(value="/deleteImageById",method = RequestMethod.GET) @ResponseBody public void deleteImageById(@RequestParam String id){ imageService.deleteImageById(id); } }
2.6 pojo User set get 方法略,为了节省空间,不然
@Entity @Table(name = "p_user") public class PUser implements Serializable { private String id; private String password; private String name; private String sex; private String mobile; private Date registerDate; private String headUrl;
}
2.6 pojo PImage set get 方法略,为了节省空间,不然太多了
@Entity @Table(name = "p_image") public class PImage { private String id; private String userId; private String imageUrl; private String imageDesc; private String imageName;
}
2.7 UserRepository
@Service public class UserService { @Autowired private UserRepository userRepository; public void register(PUser user){ user.setId(String.valueOf(System.currentTimeMillis())); user.setRegisterDate(new Date()); userRepository.save(user); } public PUser login(String name,String password) throws Exception { PUser user = userRepository.findPUserByNameAndPassword(name,password); if(user == null){ throw new Exception("找不到用户"); } return user; } public PUser findPUserById(String id){ return userRepository.findPUserById(id); } public void saveEdit(PUser user){ userRepository.save(user); } }
2.8 ImageService
@Service public class ImageService { @Autowired private ImageRepository imageRepository; public void save(PImage image){ imageRepository.save(image); } public ListgetImageByUserId(String userId){ return imageRepository.findPImagesByUserId(userId); } public List getRandomImages(String userId,String model){ if(model.equals("SJZS")){ userId = "%"; } List list = imageRepository.getALLId(userId); int size = list.size(); if(size == 0){ return null; } List id = new ArrayList<>(); for(int i=0;i< 10;i++){ int x=(int)(Math.random()*size); id.add(list.get(x)); } return imageRepository.getRandomImages(id); } public void editDesc(String id,String desc,String name){ Optional optional = imageRepository.findById(id); PImage pImage = optional.get(); pImage.setImageDesc(desc); pImage.setImageName(name); imageRepository.save(pImage); } public void deleteImageById(String id){ imageRepository.deleteById(id); } }
2.9 UserRepository
@Repository @Table(name="p_user") public interface UserRepository extends CrudRepository{ PUser findPUserByNameAndPassword(String name,String password); PUser findPUserById(String id); }
2.10 ImageRepository
@Repository @Table(name="p_image") public interface ImageRepository extends CrudRepository{ List findPImagesByUserId(String userId); @Query("select image.id from PImage image where image.userId like ?1") List getALLId(String userId); @Query("select image from PImage image where image.id in ?1") List getRandomImages(List list); }
2.11 下面开始贴界面的html,js ,css 文件
index.html
html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Photo_indextitle>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/vue/dist/vue.js">script>
<script src="https://unpkg.com/element-ui/lib/index.js">script>
<script src="//cdn.bootcss.com/vue-resource/1.0.3/vue-resource.min.js">script>
head>
<body style="background-color: azure;">
<div style="text-align: center;">在线相册div>
<div id="vm1" style=" width: 100%;height: 137px;margin-top: 10px;">
<div v-if="register" style="margin-top: 300px;text-align: center;">
用户注册
<el-row>
<el-col :span="8" :offset="8">
<el-form :model="registerUser" status-icon :rules="registerRule" ref="registerUser">
<el-form-item label="姓名" prop="name">
<el-input v-model="registerUser.name" auto-complete="off" clearable maxlength="10">el-input>
el-form-item>
<el-form-item label="手机号码" prop="mobile">
<el-input v-model="registerUser.mobile" auto-complete="off" clearable maxlength="13">el-input>
el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="registerUser.password" auto-complete="off" clearable maxlength="10">el-input>
el-form-item>
<el-form-item label="确认密码" prop="password2">
<el-input type="password" v-model="registerUser.password2" auto-complete="off" clearable maxlength="10">el-input>
el-form-item>
<el-form-item>
<el-button type="success" @click="registerOk()">注册el-button>
<el-button type="success" @click="register=false;index=true">返回el-button>
<el-button type="success" @click="registerRest()">重置el-button>
el-form-item>
el-form>
el-col>
el-row>
div>
<div v-if="login" style="margin-top: 300px;text-align: center;">
用户登录
<el-row>
<el-col :span="8" :offset="8">
<el-form :model="loginUser">
<el-form-item label="姓名" >
<el-input v-model="loginUser.loginName" clearable maxlength="10"> el-input>
el-form-item>
<el-form-item label="密码" >
<el-input type="password" v-model="loginUser.loginPassword" clearable maxlength="10">el-input>
el-form-item>
<el-form-item>
<el-button type="success" @click="loginOk()">登录el-button>
<el-button type="success" @click="login=false;index=true">返回el-button>
<el-button type="success" @click="loginRest()">重置el-button>
el-form-item>
el-form>
el-col>
el-row>
div>
<div v-if="index" style="margin-top: 300px;text-align: center;">
<el-row>
<el-col :span="8" :offset="8">
<el-form>
<el-form-item>
<el-button type="success" @click="register = true;login = false;index=false">注册el-button>
<el-button type="success" @click="login=true;register = false;index=false">登录el-button>
el-form-item>
el-form>
el-col>
el-row>
div>
div>
<script th:src="@{/js/index.js}">script>
body>
html>
index.js
//Vue.http.options.emulateHTTP = true; var vm = new Vue({ el: '#vm1', data: { // index index:true, // login login : false, loginUser:{'loginName':'','loginPassword':''}, // register register:false, registerUser:{'name':'','password':'','password2':'','mobile':''}, //validateName1:this.validateName, registerRule:{ na: [{ validator: this.validateName1, trigger: 'blur' }], password: [{ validator: this.validatePassword, trigger: 'blur' }], password2: [{ validator: this.validatePassword2, trigger: 'blur' }], mobile: [{ validator: this.checkMobile, trigger: 'blur' }] } }, methods:{ registerOk:function(){ this.$http.post("/photo/user/register",this.registerUser) .then(function (response) { this.$message({ type: 'success', message: '注册成功,赶快去登录吧!' }); }) .catch(function (response) { console.error(response); }); }, registerRest:function(){ this.registerUser.name = ''; this.registerUser.password=''; this.registerUser.mobile='' }, loginOk:function(){ this.$http.get("/photo/user/login",{params: {name:this.loginUser.loginName,password:this.loginUser.loginPassword}}) .then(function (response) { console.log(response); var user = response.body; if(user ==null){ this.$message({ type: 'success', message: '用户名密码有误,登录失败!' }); }else{ window.location.href="/photo/index/main?id="+user.id; } }) .catch(function (response) { console.error(response); }); }, loginRest:function(){ this.loginName = ''; this.loginPassword = ''; }, // 注册校验方法 validateName:function(rule, value, callback){ if (value === '') { callback(new Error('请输入用户名')); } else { callback(); } }, validatePassword:function(rule, value, callback){ if (value === '') { callback(new Error('请输入密码')); } else { if (this.registerUser.password2 !== '') { this.$refs.registerUser.validateField('password2'); } callback(); } }, validatePassword2:function(rule, value, callback){ if (value === '') { callback(new Error('请再次输入密码')); } else { if (this.registerUser.password !== value) { callback(new Error('两次输入密码不一致!')); }else{ callback(); } } }, checkMobile:function(rule, value, callback){ if (value === '') { callback(new Error('请输入手机号')); } else { if(value.length !=11){ callback(new Error('手机号不合法')); }else { callback(); } } }, }, mounted: function () { var registerRule ={ name: [{ required: true, message: '请输入名称', trigger: 'blur' },{ validator: this.validateName, trigger: 'blur' }], password: [{ validator: this.validatePassword, trigger: 'blur' }], password2: [{ validator: this.validatePassword2, trigger: 'blur' }], mobile: [{ validator: this.checkMobile, trigger: 'blur' }] } this.registerRule = registerRule; }, watch:{ }, updated:function(){ //this.registerRule.name[0].validator=this.validateName }, })
main.html
html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Photo_maintitle>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/vue/dist/vue.js">script>
<script src="https://unpkg.com/element-ui/lib/index.js">script>
<script src="//cdn.bootcss.com/vue-resource/1.0.3/vue-resource.min.js">script>
<link th:href="@{/css/main.css}" rel="stylesheet" />
head>
<body>
<div id="vm2">
<el-row>
<el-col :span="8">
<p>当前用户:{{ user.name }}p>
el-col>
<el-col :span="8" :offset="8">
<el-button type="primary" @click="logout">退出登录el-button>
el-col>
el-row>
<el-row>
<el-tabs type="border-card" @tab-click="tabClick">
<el-tab-pane style="height: 500px;">
<span slot="label"><i class="el-icon-date">i>相册展示span>
<el-row :gutter="20">
<el-col :span="16">
<div style="width: 600px;">
<el-carousel :interval="5000" arrow="always" height="400px" @change="carouselChange">
<el-carousel-item v-for="item in pictures">
<img height="390px" width="600px" :src="base+item.imageUrl"/>
el-carousel-item>
el-carousel>
div>
el-col>
<el-col :span="8"><div class="grid-content bg-purple">{{pictureDesc}}div>el-col>
el-row>
<br/>
<el-form :inline="true" class="demo-form-inline">
<el-form-item>
<el-button type="primary" @click="getRandomImages('SJZS')">刷新图片el-button>
el-form-item>
<el-form-item label="查看模式">
<el-select v-model="showModel" placeholder="选择一种模式" @change="showModelSelect">
<el-option label="随机展示" value="SJZS">el-option>
<el-option label="只看自己" value="ZKZJ">el-option>
el-select>
el-form-item>
el-form>
el-tab-pane>
<el-tab-pane label="个人中心" style="height: 400px;">
<el-form ref="user" :model="user" label-width="80px">
<el-form-item label="用户标识"> <el-input v-model="user.id" :disabled="true">el-input> el-form-item>
<el-form-item label="用户名称"> <el-input v-model="user.name" maxlength="10">el-input> el-form-item>
<el-form-item label="用户密码"> <el-input v-model="user.password" maxlength="10">el-input> el-form-item>
<el-form-item label="手机号码"> <el-input v-model="user.mobile" maxlength="13">el-input> el-form-item>
<el-form-item label="用户性别">
<el-radio-group v-model="user.sex">
<el-radio label="男">el-radio>
<el-radio label="女">el-radio>
el-radio-group>
el-form-item>
<el-form-item>
<el-button type="primary" @click="saveUser">立即保存el-button>
<el-button type="primary" @click="editUserRest">重置el-button>
el-form-item>
el-form>
el-tab-pane>
<el-tab-pane label="图片上传" style="height: 400px;" >
<el-upload
:data={'userId':user.id}
action="../file/upload"
list-type="picture-card"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove">
<i class="el-icon-plus">i>
el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
el-dialog>
el-tab-pane>
<el-tab-pane label="我的资源" style="height: 400px;">
<div style="height: 390px;overflow-y: auto;">
<li v-for="item in myImages">
<div id="main">
<div style="margin-top: 10px; margin-bottom: 10px;">
<img :src="base + item.imageUrl" th:width="100" height="100" :id="item.id" @click="imageClick(item.id)" />
<p >{{item.imageName}}p>
div>
<div style="margin-top: 10px; margin-bottom: 10px;background: #00b8ff21;width: 762px;">描述:{{item.imageDesc}}div>
div>
li>
div>
el-tab-pane>
el-tabs>
el-row>
<el-dialog title="图片编辑" :visible="dialogFormVisible">
<el-form :model="dialogForm">
<el-form-item label="图片标识" :label-width="formLabelWidth">
<el-input v-model="dialogForm.id" :disabled="true"> el-input>
el-form-item>
<el-form-item label="图片名称" :label-width="formLabelWidth">
<el-input v-model="dialogForm.imageName" clearable maxlength="10"> el-input>
el-form-item>
<el-form-item label="描述文本" :label-width="formLabelWidth">
<el-input type="textarea" :rows="2" v-model="dialogForm.imageDesc" auto-complete="off" clearable maxlength="200">el-input>
el-form-item>
el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="deleteImage">删除这一张图片el-button>
<el-button @click="dialogFormVisible = false">取 消el-button>
<el-button type="primary" @click="dialogFormOk">保存修改el-button>
div>
el-dialog>
div>
<script th:src="@{/js/main.js}">script>
<script th:inline="javascript">
/* var user = [[${cUser}]];
console.log(user);
vm._data.user = user;
for(var key in user){
vm._data.userBack[key] = user[key];
}
/*]]>*/
script>
body>
html>
main.js
Vue.http.options.emulateHTTP = true; var vm = new Vue({ el: '#vm2', data: { // 图片展示 pictures:[], user:{'id':'','name':'','password':'','mobile':'','sex':'','registerDate':'','headUrl':''}, userBack:{}, showModel:'', pictureDesc:'', // 图片上传参数 dialogImageUrl: '', dialogVisible: false, // 我的资源 myImages:[], base:'../file/', dialogFormVisible:false, dialogForm:{'id':'','imageDesc':'','imageName':''}, formLabelWidth:'120px' }, methods:{ logout:function(){ var _this = this; this.$confirm('确定要退出当前系统吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', callback: function(id){ if(id == 'confirm'){ window.location.href="/photo/user/logout"; }else{ _this.$message({ type: 'info', message: '已取消' }); } } }); }, carouselChange:function(index){ this.pictureDesc = this.pictures[index].imageDesc; }, deleteImage:function(){ this.$http.get("/photo/file/deleteImageById",{params: {id:this.dialogForm.id}}) .then(function (response) { this.$message({ type: 'success', message: '删除成功!' }); this.dialogFormVisible = false; this.getMyImage(); }) .catch(function (response) { console.error(response); }); }, dialogFormOk:function(){ this.$http.get("/photo/file/editDesc", {params: {id:this.dialogForm.id,desc:this.dialogForm.imageDesc,name:this.dialogForm.imageName}}) .then(function (response) { this.$message({ type: 'success', message: '修改成功!' }); this.dialogFormVisible = false; //this.getMyImage(); }) .catch(function (response) { console.error(response); }); }, imageClick:function(id){ this.dialogFormVisible = true; for(index in this.myImages){ if(this.myImages[index].id == id){ this.dialogForm = this.myImages[index]; break; } } }, showModelSelect:function (model) { this.getRandomImages(model); }, getRandomImages:function(model){ this.$http.get("/photo/file/getRandomImages",{params: {userId:this.user.id,model:model}}) .then(function (response) { console.log(response); this.pictures = response.body; }) .catch(function (response) { console.error(response); }); }, tabClick:function(tab){ if(tab.index==3){ this.getMyImage(); } }, getMyImage:function(){ this.$http.get("/photo/file/getImageByUserId",{params: {userId:this.user.id}}) .then(function (response) { console.log(response); this.myImages = response.body; }) .catch(function (response) { console.error(response); }); }, handleRemove:function(file, fileList) { console.log(file, fileList); }, handlePictureCardPreview:function(file) { this.dialogImageUrl = file.url; this.dialogVisible = true; }, saveUser:function(){ this.$http.post("/photo/user/saveEdit",this.user) .then(function (response) { this.$message({ type: 'success', message: '保存成功!' }); }) .catch(function (response) { console.error(response); }); }, editUserRest:function(){ for(var key in this.userBack){ this.user[key] = this.userBack[key]; } } }, mounted: function () { // 加载首页随机图片 this.getRandomImages('SJZS'); }, watch:{ } })
main.css
.avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; } .avatar-uploader .el-upload:hover { border-color: #409EFF; } .avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 178px; height: 178px; line-height: 178px; text-align: center; } .avatar { width: 178px; height: 178px; display: block; } .el-upload--picture-card { background-color: #fbfdff; border: 1px dashed #c0ccda; border-radius: 6px; box-sizing: border-box; width: 148px; height: 148px; cursor: pointer; line-height: 146px; vertical-align: top; } el-upload--picture-card i { font-size: 28px; color: #8c939d; } #main { width: auto; height: 150px; border: 1px solid #c3c3c3; display: -webkit-flex; /* Safari */ -webkit-justify-content: space-around; /* Safari 6.1+ */ display: flex; justify-content: space-around; }
2.12 最后贴上 pom.xml
xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0modelVersion> <groupId>com.ryzgroupId> <artifactId>photoalbumartifactId> <version>0.0.1-SNAPSHOTversion> <packaging>jarpackaging> <name>photoalbumname> <description>Demo project for Spring Bootdescription> <parent> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-parentartifactId> <version>2.0.2.RELEASEversion> <relativePath/> parent> <properties> <project.build.sourceEncoding>UTF-8project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding> <java.version>1.8java.version> properties> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-data-jpaartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-thymeleafartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> dependency> <dependency> <groupId>mysqlgroupId> <artifactId>mysql-connector-javaartifactId> <version>5.1.44version> dependency> <dependency> <groupId>com.googlecode.log4jdbcgroupId> <artifactId>log4jdbcartifactId> <version>1.2version> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> <scope>testscope> dependency> dependencies> <build> <plugins> <plugin> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-maven-pluginartifactId> <executions> <execution> <goals> <goal>repackagegoal> goals> execution> executions> plugin> plugins> build> project>3 终于贴完代码了,总结一下吧,主要使用element ui 的 el-carousel 跑马灯,你可以监听他的change事件做你想做的事情,el-upload 文件上传控件,他是一个非常不错的空间,界面好看并且有预览功能,进度条。登录注册时使用了el-form 中的校验规则,是一个非常好用的功能。js 中大量的使用了 vuejs 的特性,以及它的什么周期调用的各种钩子。之前项目是运行在我本地的,后面又放在腾讯云服务器上去,所以在文件上传的地方稍微判断了一下是什么Windows系统还是Linux系统,因为两种系统的获取文件不同。发现在腾讯云上获取上传的图片是如果采用相对路径不能获取(权限都是777),后来改成绝对路径了。这里的文件存储在本地一定不是可以的方案,后面有时间找个文件服务器吧。