1.el-upload
1.1基本配置
<el-upload
class="upload-demo"
accept="image/jpeg, image/jpg, image/png"// 可上传类型
ref="myUpload"//类似id名,可用this.$refs.myUpload获取refs对象
action="http://api.qx121.net/api/Rikaze/UploadFile"//图片上传地址
:on-preview="handlePreview"//图片预览
:before-upload="beforeAvatarUpload"//上传之前
:on-remove="handleRemove"//删除之前
:on-success="handleSucess"//成功后
:file-list="fileList"//储存上传的img
list-type="picture"//上传预览分割
:auto-upload="false"//是否自动上传
:on-change="imgBroadcastChange"//发生改变的钩子
v-model="form.fmsrc"//数据绑定
>
<el-button size="small" type="primary">上传图片</el-button>
<div slot="tip" class="el-upload__tip">支持上传image/jpeg,image/jpg,image/png文件,且不超过500kb</div>
</el-upload>
export default {
name: 'Wtable',
components: {
quillEditor
},
data() {
return {
form: {
btitle: '',
lxtypename: '特色产品',
fmsrc: '',
description: ''
},
//上传
fileList: [] //这个是上传图片的信息
};
},
methods: {
saveEdit(form) {
console.log('表单提交', this.form);
this.$refs.myUpload.submit(); //上传图片
this.editVisible = false;
},
handleRemove(file, fileList) {},
handlePreview(file) {},
handleSucess(response, file, fileList) {// 上传成功
console.log(response, file, fileList);
//图片上传成功后提交form表单
},
beforeAvatarUpload(file) {
},
// 上传列表发生变化
imgBroadcastChange(file, fileList) {
}
}
}
1.2限制上传
复制代码
<template>
<div class="select_invoice">
<el-upload
class="upload-demo"
:multiple="true"
:action="uploadPath"
:data="uploadData"
accept="bmg,.png,.jpg,.jpeg"
:before-upload="beforeUpload"
:on-success="handleSuccess"
:on-error="hanldeError"
multiple
:limit="20">
<el-button size="small" type="primary">添加图片</el-button>
</el-upload>
</div>
</template>
复制代码
压缩的方法放在before-upload中,这个方法可以接受一个promise,提一下,最好下载新版本的element-UI,以前的旧版本可能不支持返回promise
js
复制代码
<script>
// 引入image-conversion
import imageConversion from 'image-conversion'
methods: {
// 第一种,不考虑图片长宽,只考虑图片大小的情况,图片超过4M就压缩
beforeUpload (file) {
return new Promise((resolve, reject) => {
let isLt2M = file.size / 1024 / 1024 < 4 // 判定图片大小是否小于4MB
if (isLt2M) {
resolve(file)
}
console.log(file)
// 压缩到400KB,这里的400就是要压缩的大小,可自定义
imageConversion.compressAccurately(file, 400).then(res => {
// console.log(res)
resolve(res)
})
})
},
//第二种,图片大小超过4M,长度超过2000就压缩
beforeUpload2 (file) {
// 图片不大于4m,宽度不大于2000
return new Promise((resolve, reject) => {
let _URL = window.URL || window.webkitURL
let isLt2M = file.size / 1024 / 1024 > 4 // 判定图片大小是否小于4MB
// 这里需要计算出图片的长宽
let img = new Image()
img.onload = function () {
file.width = img.width // 获取到width放在了file属性上
file.height = img.height // 获取到height放在了file属性上
let valid = img.width > 2000 // 图片宽度大于2000
// console.log(11, file)
// 这里我只判断了图片的宽度,compressAccurately有多个参数时传入对象
if (valid || isLt2M) {
imageConversion.compressAccurately(file, {
size: 400,
width: 2000
}).then(res => {
// console.log(33, res)
resolve(res)
})
} else resolve(file)
}
// 需要把图片赋值
img.src = _URL.createObjectURL(file)
})
},
}
</script>
复制代码
这样就实现了图片的自动压缩功能,这个组件还有一些其他功能,使用的时候如果有其他需求,可以看下文档https://github.com/WangYuLue/image-conversion
1.3图片回显
2.el-pagination
分页的两种方式。前端分页,后端分页。两种方式各有个的优缺点吧。
2.1前端分页
前端分页:后台只需将数据返回,不需要做过多处理,前端一次请求拿到所有数据后做分页处理。但数据量不能太大,因为前端是先一次性加载所有数据,然后在做分页处理。在数据量多的情况下,加载相对应的会变慢。所有在前端做分页时要先考虑一下后期的数据量。
<template>
<div class="app">
<!-- 将获取到的数据进行计算 -->
<el-table :data="tableData.slice((currentPage-1)*PageSize,currentPage*PageSize)" style="width: 100%">
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
</el-table>
<div class="tabListPage">
<el-pagination @size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="pageSizes"
:page-size="PageSize" layout="total, sizes, prev, pager, next, jumper"
:total="totalCount">
</el-pagination>
</div>
</div>
</template>
<script>
export default {
data(){
return {
// 总数据
tableData:[],
// 默认显示第几页
currentPage:1,
// 总条数,根据接口获取数据长度(注意:这里不能为空)
totalCount:1,
// 个数选择器(可修改)
pageSizes:[1,2,3,4],
// 默认每页显示的条数(可修改)
PageSize:1,
}
},
methods:{
getData(){
// 这里使用axios,使用时请提前引入
axios.post(url,{
orgCode:1
},{emulateJSON: true},
{
headers:{"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",}
}
).then(reponse=>{
console.log(reponse)
// 将数据赋值给tableData
this.tableData=data.data.body
// 将数据的长度赋值给totalCount
this.totalCount=data.data.body.length
})
},
// 分页
// 每页显示的条数
handleSizeChange(val) {
// 改变每页显示的条数
this.PageSize=val
// 注意:在改变每页显示的条数时,要将页码显示到第一页
this.currentPage=1
},
// 显示第几页
handleCurrentChange(val) {
// 改变默认的页数
this.currentPage=val
},
},
created:function(){
this.getData()
}
}
</script>
2.2后端分页
后端分页:因为是后端分页,前端在每点击一次分页时,便向后台请求一次数据。其实就是避免前端一次性从数据库获取大量数据
<template>
<div class="app">
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
</el-table>
<div class="tabListPage">
<el-pagination @size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="pageSizes"
:page-size="PageSize" layout="total, sizes, prev, pager, next, jumper"
:total="totalCount">
</el-pagination>
</div>
</div>
</template>
<script>
export default {
data(){
return {
// 总数据
tableData:[],
// 默认显示第几页
currentPage:1,
// 总条数,根据接口获取数据长度(注意:这里不能为空)
totalCount:1,
// 个数选择器(可修改)
pageSizes:[1,2,3,4],
// 默认每页显示的条数(可修改)
PageSize:1,
}
},
methods:{
// 将页码,及每页显示的条数以参数传递提交给后台
getData(n1,n2){
// 这里使用axios,使用时请提前引入
axios.post(url,{
orgCode:1,
// 每页显示的条数
PageSize:n1,
// 显示第几页
currentPage:n2,
},{emulateJSON: true},
{
headers:{"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",}
}
).then(reponse=>{
console.log(reponse)
// 将数据赋值给tableData
this.tableData=data.data.body
// 将数据的长度赋值给totalCount
this.totalCount=data.data.body.length
})
},
// 分页
// 每页显示的条数
handleSizeChange(val) {
// 改变每页显示的条数
this.PageSize=val
// 点击每页显示的条数时,显示第一页
this.getData(val,1)
// 注意:在改变每页显示的条数时,要将页码显示到第一页
this.currentPage=1
},
// 显示第几页
handleCurrentChange(val) {
// 改变默认的页数
this.currentPage=val
// 切换页码时,要获取每页显示的条数
this.getData(this.PageSize,(val)*(this.pageSize))
},
},
created:function(){
this.getData(this.PageSize,this.currentPage)
}
}
</script>
3.el-input
3.1的密码显隐
- 使用
<el-form-item label="密码" prop="password">
<el-input
v-model="LoginformData.password"
maxlength="16"
placeholder="密码"
prefix-icon="el-icon-lock"
show-password
clearable
></el-input>
</el-form-item>
- 问题
- 眼睛点击前后状态一样
- 眼睛点击后鼠标光标跑到内容最前面
- 解决办法,自己写显示隐藏
<el-form-item label="密码" prop="password">
<el-input :type="passw" v-model="adduser.password" style="width: 300px;" >
<%-- input中加图标必须要有slot="suffix"属性,不然无法显示图标 --%>
<i slot="suffix" :class="icon" @click="showPass"></i>
</el-input>
</el-form-item>
<script type="text/javascript">
var app = new Vue({
el:"#app",
data:{
users:[],
total:100,
pageSize:5,
pageNum:1,
//用于显示或隐藏添加修改表单
add:false,
//用于改变Input类型
passw:"password",
//用于更换Input中的图标
icon:"el-input__icon el-icon-view",
adduser:{
id:null,
name:null,
password:null,
dept_id:null
},
},
methods:{
//密码的隐藏和显示
showPass(){
//点击图标是密码隐藏或显示
if( this.passw=="text"){
this.passw="password";
//更换图标
this.icon="el-input__icon el-icon-view";
}else {
this.passw="text";
this.icon="el-input__icon el-icon-loading";
};
}
},
})
</script>
3.2有时input无法输入
原因,
其实已经输入,但是由于嵌套太深数据没更新出来
解决办法
```javascript
- 缺点
可能会造成验证失效
<a name="tA6Rq"></a>
## 4.el-form
<a name="S7UHM"></a>
### 4.1表单清空
- 方法一
```javascript
handleReset(formName) {
console.log('清空表单');
this.$refs[formName].resetFields();
this.form = this.$options.data().form;
},
- 方法二
重置表单数据,使用的地方特别多,我们封装为全局方法
//重置表单,formRef为表单的ref值,excludeFields为要排除重新初始化值得属性
Vue.prototype.$reset = function (formRef, ...excludeFields) {
this.$refs[formRef].resetFields();
let obj1 = this.$data;
let obj2 = this.$options.data.call(this);
if (!excludeFields || excludeFields.length === 0) {
excludeFields = ["ruleValidate"];
}
for (let attrName in obj1) {
if (excludeFields && excludeFields.includes(attrName)) {
continue;
}
obj1[attrName] = obj2[attrName];
}
};
使用
<template>
<el-dialog
v-el-drag-dialog
:close-on-click-modal="false"
:visible.sync="dialogVisible"
:title="model.id === 0 ? '新增车辆' : '编辑车辆'"
class="car-edit"
width="450px"
top="5vh"
@close="$reset('form')">//关闭后调用封装的表单清空方法
<el-form ref="form"
:model="model"
:rules="ruleValidate"
class="formFillWidth"
label-width="50px">
<el-form-item label="车牌" prop="carCard">
<el-input v-model="model.carCard" placeholder="请输入"/>
</el-form-item>
<el-form-item label="司机" prop="driver">
<el-input v-model="model.driver" placeholder="请输入"/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="model.remark" placeholder="请输入"/>
</el-form-item>
</el-form>
<span slot="footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button :loading="submitLoading" type="primary" @click="handleSubmit">保存</el-button>
</span>
</el-dialog>
</template>
复制代码
- 如果验证报错
data () {
return {
dialogVisible: false,
submitLoading: false,
model: {
id: 0,
carCard: "",
driver: "",
remark: "",
},
ruleValidate: {
carCard: {required: true, message: "不能为空", trigger: "blur"},
},
};
},
5.el-checkbox
5.1 实现全选
<el-checkbox v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
<el-checkbox-group v-model="checkedList">
<el-checkbox :class="'type-item' + index" v-for="(item, index) in types" :label="item.value" :key="item.val" @change="handleCheckedCitiesChange">{{ item.label }}</el-checkbox>
</el-checkbox-group>
<script>
export default {
data() {
return {
checkedList: [],
checkAll: false,
types:[
{
label: '区域站',
value: 1
},
{
label: '国家站',
value: 2
}
]
};
},
methods: {
handleCheckAllChange(val) {
console.log('全选', val);
this.checkAll = val;
if (val) this.checkedList = [1, 2, 3, 4, 5, 6];
else this.checkedList = [];
},
handleCheckedCitiesChange(val) {
console.log('单选', this.checkedList);
}
},
created() {},
mounted() {}
};
5.2单选互斥
<el-checkbox-group v-model="checkRangeList" @change="handleCheckedRange">
<el-checkbox label="5公里">5公里</el-checkbox>
<el-checkbox label="10公里">10公里</el-checkbox>
<el-checkbox label="20公里">20公里</el-checkbox>
</el-checkbox-group>
<script>
export default {
data() {
return {
checkRangeList: [],
checkStationsList: []
};
},
methods: {
handleCheckedRange(val) {
if (this.checkRangeList.length > 1) {
this.checkRangeList.splice(0, 1);
}
console.log(this.checkRangeList);
},
},
};
</script>
6.el-radio
6.1 可取消
<el-radio-group v-model="radio2">
<el-radio @click.native.prevent="clickitem(3)" :label="3"> 备选项</el-radio>
<el-radio @click.native.prevent="clickitem(6)" :label="6"> 备选项</el-radio>
<el-radio @click.native.prevent="clickitem(9)" :label="9"> 备选项</el-radio>
</el-radio-group>
clickitem (e) {
e === this.radio2 ? this.radio2 = '' : this.radio2 = e
},
7.el-dialog
7.1可拖拽
- 创建自定义指令 ```javascript // directives.js import Vue from ‘vue’;
// v-dialogDrag: 弹窗拖拽 Vue.directive(‘dialogDrag’, { bind(el, binding, vnode, oldVnode) { // 获取拖拽内容头部 const dialogHeaderEl = el.querySelector(‘.el-dialog__header’); // 获取拖拽内容整体 这个rrc-dialog是我自己封装的组件 如果使用element的组件应写成.el-dialog const dragDom = el.querySelector(‘.rrc-dialog’); dialogHeaderEl.style.cursor = ‘move’;
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
// 鼠标按下事件
dialogHeaderEl.onmousedown = (e) => {
// 鼠标按下,计算当前元素距离可视区的距离 (鼠标点击位置距离可视窗口的距离)
const disX = e.clientX - dialogHeaderEl.offsetLeft;
const disY = e.clientY - dialogHeaderEl.offsetTop;
// 获取到的值带px 正则匹配替换
let styL, styT;
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
if (sty.left.includes('%')) {
styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100);
styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100);
} else {
styL = +sty.left.replace(/\px/g, '');
styT = +sty.top.replace(/\px/g, '');
};
// 鼠标拖拽事件
document.onmousemove = function (e) {
// 通过事件委托,计算移动的距离 (开始拖拽至结束拖拽的距离)
const l = e.clientX - disX;
const t = e.clientY - disY;
let finallyL = l + styL
let finallyT = t + styT
// 边界值判定 注意clientWidth scrollWidth区别 要减去之前的top left值
// dragDom.offsetParent表示弹窗阴影部分
if (finallyL < 0) {
finallyL = 0
} else if (finallyL > dragDom.offsetParent.clientWidth - dragDom.clientWidth - dragDom.offsetParent.offsetLeft) {
finallyL = dragDom.offsetParent.clientWidth - dragDom.clientWidth - dragDom.offsetParent.offsetLeft
}
if (finallyT < 0) {
finallyT = 0
} else if (finallyT > dragDom.offsetParent.clientHeight - dragDom.clientHeight - dragDom.offsetParent.offsetLeft) (
finallyT = dragDom.offsetParent.clientHeight - dragDom.clientHeight - dragDom.offsetParent.offsetLeft
)
// 移动当前元素
dragDom.style.left = `${finallyL}px`;
dragDom.style.top = `${finallyT}px`;
//将此时的位置传出去
//binding.value({x:e.pageX,y:e.pageY})
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
}
} })
- 引入
```javascript
//在main.js中全局引入
import './directives'
- 使用
// call.center.detail.vue
<el-dialog v-dialogDrag title="呼出结果" :visible.sync="dialogOutVisible">
...
</el-dialog>
8.el-menu
8.1刷新选中
<el-menu
:default-active="defaultActiveIndex"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
background-color="#0f1f43"
text-color="#fff"
active-text-color="#ef4873"
:default-openeds="['1', '2']"
>
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>用户</span>
</template>
<el-menu-item-group>
<el-menu-item index="/admin/user">
<router-link to="/admin/user">
用户管理
</router-link>
</el-menu-item>
<el-menu-item index="/admin/account">
<router-link to="/admin/account">
账号管理
</router-link>
</el-menu-item>
<el-menu-item index="/admin/agent">
<router-link to="/admin/agent">
三方公司
</router-link>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
<el-submenu index="2">
<template slot="title">
<i class="el-icon-location"></i>
<span>房屋</span>
</template>
<el-menu-item-group>
<el-menu-item index="/admin/home">
<router-link to="/admin/home">房屋管理</router-link>
</el-menu-item>
<el-menu-item index="/admin/image">
<router-link to="/admin/image">图片管理</router-link>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
export default {
data() {
return {
defaultActiveIndex: ''
};
},
mounted() {
this.defaultActiveIndex = window.location.href.replace(new RegExp('#', 'g'), '---').split('---')[1];
console.log(this.defaultActiveIndex);
},
}