目录
一、运行环境
1.1 安装vue router及axios
1.2 安装及引入element
二、elemnet实现增删除改查代码
三、运行效果
后端写了,现在写前端使用vue+vue router+element实现代码。
在《hualinux 进阶 vue 5.1:用Element实现增删改查(一)需求及分析》已经做了分析了,在这里我就不再讲了,直接上代码。
前端element实现代码,这个是基于《hualinux 进阶 vue 3.1:vue cli手工创建Vue router》的基础上安装了axios,为了解决cors在根目录创建了一个vue.config.js,内容如下:
module.exports = { devServer: { proxy: 'http://192.168.3.200/index.php' } }
我这里使用npm方式安装element ui,只要有webstorm终端terminal执行上面给出的命令即可。
安装完之后还不行,还要引入vue插件,我这里使用引入element全部组件,在src/main.js,添加如下代码
import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI)
element之后把实现代码写在about页中,代码如下:
<template> <div class="width_100 height_100" style="padding:50px 20px"> <!-- 一定要 highlight-current-row 选项,要不span和input标签切换不了--> <el-table :data="info" stripe style="width: 100%" ref="multipleTable" :row-class-name="tableRowClassName" @selection-change="handleSelectionChange" highlight-current-row> <el-table-column type="selection" width="80"></el-table-column> <el-table-column type="index"></el-table-column> <!-- 如果要隐藏此页用 v-if=false --> <el-table-column prop="picid" label="图片ID" width="80"> <template v-slot="scope"> <span>{{ scope.row.picid }}</span> </template> </el-table-column> <el-table-column prop="picurl" label="图片" width="150"> <template v-slot="scope"> <span v-if="scope.row.isSet"> <el-upload class="avatar-uploader" :data="{'picid':scope.row.picid}" action="http://192.168.3.200/index.php/index/upload" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload"> <img v-if="imageUrl" :src="imageUrl" class="avatar"> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> </span> <span v-else><el-image class="img" :src="scope.row.picurl"></el-image></span> </template> </el-table-column> <el-table-column prop="lable" label="图片名" width="100"> <template v-slot="scope"> <span v-if="scope.row.isSet"> <el-input size="mini" placeholder="请输入内容" v-model="rowSelect.lable"> </el-input> </span> <span v-else>{{ scope.row.lable }}</span> </template> </el-table-column> <el-table-column prop="describe" label="说明" width="200"> <template v-slot="scope"> <span v-if="scope.row.isSet"> <el-input size="mini" placeholder="请输入内容" v-model="rowSelect.describe"> </el-input> </span> <span v-else>{{ scope.row.describe }}</span> </template> </el-table-column> <el-table-column label="操作" width=""> <template v-slot="scope"> <span v-if="scope.row.isSet" class="el-tag el-tag--success el-tag--small" style="cursor: pointer;" @click.stop="saveRow(scope.row,scope.$index)"> 保存 </span> <span v-else class="el-tag el-tag--primary el-tag--small" style="cursor: pointer;" @click="editRow(scope.row,scope.$index)"> 编辑 </span> <span class="el-tag el-tag--danger el-tag--small" style="cursor: pointer;" @click="deleteRow(scope.row,scope.$index)"> 删除 </span> </template> </el-table-column> </el-table> <div v-show="isShow" style="margin-top:20px;width: 200px"> <el-button type="primary" icon="el-icon-delete" @click="delSel()">删除</el-button> <el-button type="primary" @click="toggleSelection()">取消选择</el-button> </div> <div v-show="!isShow" style="margin-top:20px;width: 200px"> <el-button type="primary" @click="add()">添加</el-button> </div> <div> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes=[5,10,20,30,50] :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" hide-on-single-page :total="pageTotal" > </el-pagination> </div> </div> </template> <script> import axios from "axios"; export default { name: 'element-curl', data() { return { //总条目数 pageTotal: 7, //总页数 pageCount: 10, //每页条数 pageSize: 5, //当前页 currentPage: 1, //get获取数据的信息 info: null, //所选择的行 rowSelect: null, //图片Url,这个是上传头像功能 imageUrl: '', //所上传没保存之前PHP返回的的临时目录, picTempPath: '0', //多选 multipleSelection: [], //是否jjofi isShow: false, //axios请示返回的数据 axiosres: null } }, methods: { // row-class-name 处理函数 // eslint-disable-next-line no-unused-vars tableRowClassName(row, index) { // 给每条数据添加一个索引,方便批量删除 row.row.index = row.rowIndex; }, // 行编辑按钮对应的方法 editRow(row) { //alert(JSON.stringify(row)); for (let i of this.info) { // 为每行添加一个isSet=属性,否则点保存,会保存不了,1为true,0为false if (i.isSet) return this.$message.warning("请先保存当前编辑项"); } this.rowSelect = row //1为真,0为假 row.isSet = 1; this.imageUrl = row.picurl; // 先清空上次只在的 picTemp 内容,这个picTemp是图片的保存路径 this.picTempPath = '0'; }, //保存功能 // eslint-disable-next-line no-unused-vars saveRow(row, index) { let flag = true; //更新row的url,如果是原来的则不变。 row.picurl = this.imageUrl; //alert(JSON.stringify(this.rowSelect)); if ((!this.rowSelect['lable'].trim()) || (!this.rowSelect['describe'].trim())) { flag = false; console.log('flag is false', false); } if (flag) {//判断主要字段是否填写,名字和描述,图片是不必须的 let data = JSON.parse(JSON.stringify(this.rowSelect)); for (let k in data) row[k] = data[k]; let urlStr = '/vue/' + row.picid; //判断是新增加的字段 if (row.picid == null) { //alert('这是新添加字段'); axios .post('/vue', { picrow: { savename: this.picTempPath, lable: row.lable, describe: row.describe } }) .then(response => (this.axiosres = response.data)); } else { axios .put(urlStr, { picrow: { savename: this.picTempPath, lable: row.lable, describe: row.describe } }) .then(response => (this.axiosres = response.data)); } this.$message.success("保存成功!" + this.axiosres); row.isSet = false;//点击保存后该为false值,隐藏保存按钮,显示编辑按钮 } else { this.$message({ type: 'warning', message: "请全部填写" }) } }, //图片成功on-success 对应事件。 handleAvatarSuccess(res, file) { this.imageUrl = URL.createObjectURL(file.raw); this.picTempPath = res; }, // 上传前处理 before-upload beforeAvatarUpload(file) { const isImg = file.type === 'image/jpg' || file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif'; const isLt2M = file.size / 1024 / 1024 < 2; if (!isImg) { this.$message.error('上传头像图片只能是 JPG,png,gif 格式!'); } if (!isLt2M) { this.$message.error('上传头像图片大小不能超过 2MB!'); } return isImg && isLt2M; }, // 取消选择 toggleSelection(rows) { if (rows) { rows.forEach(row => { this.$refs.multipleTable.toggleRowSelection(row); }); } else { this.$refs.multipleTable.clearSelection(); } }, //多选 selection-change 事件 handleSelectionChange(rows) { this.multipleSelection = rows; //没有被选中 if (this.multipleSelection.length < 1) { this.isShow = false; } else { this.isShow = true; } }, //删除行 deleteRow(row, index) { let delstr = '/vue/' + row.picid; axios .delete(delstr) .then(response => (this.axiosres = response.data)) .catch(error => (this.mydata = error)); if (this.axiosres === 1) { this.info.splice(index, 1); this.$message.success("删除成功!") } }, //批量删除,删除选项的行 delSel() { //打印所选的行 //alert(JSON.stringify(this.multipleSelection)); let rows = this.multipleSelection //放删除的id let selPicids = []; if (rows.length === 1) { alert("你只选择一条数据!") this.deleteRow(rows[0], rows[0].index); } /* * 注意,这里不能直接在for of中,使用数组的splice方法进行删除多个元素,因为会变的,会出问题。 * 因为删除一个元素数组的下标就会发生变化,这样就会产生错乱 * 要用Set集合的delete方法进行删除 * */ let mySet = new Set(this.info) for (let row of rows) { selPicids.push(row.picid); //删除vue展示 mySet.delete(row); } //alert(JSON.stringify(selPicids)); //alert(JSON.stringify(...mySet)); //删除数据库 axios // delete第二个参数为config,所以传值时需要借助config中data字段,用data携带过去 // 注意:data的格式为: data:对象,如 data:{picid:'001'} .delete('/index/dels', {data: {picids: JSON.stringify(selPicids)}}) .then(response => (this.axiosres = response.data)) .catch(error => (this.axiosres = error)); if (this.axiosres != 0) { this.$message.success("成功删除记录::" + selPicids.length); // 使用 ... 把Set转为数组 this.info = [...mySet]; } else { this.$message.error("出错了:" + this.dlerss); } }, //添加一行 add() { for (let i of this.info) { if (i.isSet) return this.$message.warning("请先保存当前编辑项"); } let emptyRow = { picurl: null, lable: '', describe: '', // 这个一定要设置 isSet: 1 } this.info.push(emptyRow); this.rowSelect = emptyRow; }, //分页,size-change事件,pageSize 改变时会触发 handleSizeChange(val) { //每页 val 条 this.pageSize = val; this.listDataByPage(); }, // 分页,current-change 事件,currentPage 改变时会触发 handleCurrentChange(val) { // 当前页: val //alert(val); this.currentPage = val; this.listDataByPage(); }, // axios get 获取当前页数据 listDataByPage() { axios //默认第1页,5条,可以修改一下currentPage 和 pageSize 的值 .get('/vue?page=' + this.currentPage + '&pageSize=' + this.pageSize) .then( response => { let res = response.data; this.axiosres = res; this.pageTotal = this.axiosres['list']['total']; this.pageCount = this.axiosres['list']['last_page']; this.info = res['list']['data']; return this.info; } ); } }, mounted() { this.listDataByPage(); } , } </script> <style scoped> .img { max-height: 80px; max-width: 80px; } .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 { max-width: 80px; max-height: 80px; display: block; } /* /deep/ 深度选择器 有兴趣可以搜索一下 https://www.love85g.com/?p=1879*/ /deep/ .el-table__header-wrapper .el-checkbox__input::after { content: '全选'; position: absolute; margin-left: 5px; } </style>
打开 http://<ip地址>8080/about,我这里为http://192.168.3.10:8080/about
完成之后可以测试一下这些功能,应该是正常的。