回首3月做过的功能以及遇到的问题点,话不多说,上代码瞅瞅~~
1. el-table + vue 实现 table 拖拽
效果图如下:
功能描述:
点击table表中的行数据,然后用鼠标就可以实现拖拽效果
具体实现:
// html
<el-table
row-key="tableNumber" // 设置table表中的唯一标识
:row-class-name="tableRowClassName" // 这个是设置表中某行数据的背景颜色
>
<el-table-column label="序号">
<template slot-scope="scope">{{scope.$index + 1}}</template>
</el-table-column>
<el-table-column prop="name" label="姓名">
<template slot-scope="scope">
<el-input v-model="scope.row.name"></el-input>
</template>
</el-table-column>
<el-table-column prop="age" label="年龄">
<template slot-scope="scope">
<el-input v-model="scope.row.age"></el-input>
</template>
</el-table-column>
<el-table-column prop="phone" label="手机号">
<template slot-scope="scope">
<el-input v-model="scope.row.phone" maxlength="11"></el-input>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="text" @click="deleteRow(scope.$index)">删除</el-button>
<el-button type="text" @click="addRow">新增</el-button>
</template>
</el-table-column>
</el-table>
// js
<script>
import Sortable from 'sortablejs'; // 这步很重要哈,要用这个拖拽功能需要npm这个哟
export default {
name: 'demo',
data(){
return {
tableData: [],
count: 0
}
},
mounted(){
this.dropRow();//一进入界面就需要调用拖拽方法就可以了
this.count = this.tableData.length; // 初始化,如果是请求了接口,tableData进行了赋值操作的话,那么也需要给count进行重新赋值!
},
methods: {
// 这里设置table表格,高亮行背景颜色
tableRowClassName({row, rowIndex}){
if(row.xx==='xxx'){
return 'highlight-color';
}
return '';
},
addRow(){
this.tableData.push({
name:'',
age:'',
phone:'',
tableNumber: this.count+=1
})
},
deleteRow(index){
this.tableData.splice(index,1);
},
// 这里是 行拖拽 方法
dropRow(){
const tbody = document.querySelector('.el_table__body-wrapper tbody');
const _this = this;
Sortable.create(tbody,{
onEnd({ newIndex, oldIndex }){
const currRow = _this.tableData.splice(oldIndex,1)[0];
_this.tableData.splice(newIndex, 0, currRow)
}
})
}
}
}
</script>
顺便还说一下关于 el-time-select 这个组件的小用法:
类似效果:
<el-form>
<el-form-item label="开始时间" required>
// picker-options: 这里是甚至 固定时间范围供用户选择,从0点开始,以1逐步递增,23点结束,开始时间的最大值要小于结束时间,结束时间的最小值要大于开始时间
<el-time-select v-model="timeObj.start" placeholder="请选择开始时间" :picker-options="{start:'00:00', step:'01:00', end:'23:00', maxTime: timeObj.end}"></el-time-select>
</el-form-item>
<el-form-item label="结束时间" required>
<el-time-select v-model="timeObj.end" placeholder="请选择结束时间" :pick-options="{start:'00:00', step:'01:00', end:'23:00', minTime: timeObj.start}"></el-time-select>
</el-form-item>
</el-form>
2. tooltip 文字提示用法
<span class="hover-tips">
<el-tooltip class="item" effect="dark" content="这里是提示内容哦" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
</span>
效果如下:
3. 自定义confirm提示内容
methods: {
handTips(){
const h = this.$createElement;
this.$confirm('',{
distinguishCancelAndClose: true,
confirmButtonText: 'YES',
cancelButtonText: 'CANCEL',
type: 'success',
customClass: 'xxxx', // 这里可以自定义className
message:h('div', null, [
h('div', null, '这里是第一行文本内容'),
h('div', { style: 'margin-top: 20px' }, '这里是第二行文本内容')
])
})
.then(()=>{})
.catch(()=>{})
}
}
效果如下:【还需要写css样式哈,设置一下图标的大小以及定位位置即可】
4. 上传图片
上传图片:
<el-upload
class="upload-content"
action="上传图片接口地址"
multiple
:show-file-list="false"
:headers="headers"
:data="uploadData"
:before-upload="handleBeforeUpload"
:on-success="handleSuccess"
:on-error="handleError"
:limit="1"
:file-list="fileList"
:on-exceed="handleExceed"
>
<el-button>上传图片</el-button>
<span>
<el-tooltip effect="dark" content="一次只能上传一张" placement="top">
<i class=""el-icon-question></i>
</el-tooltip>
</span>
</el-upload>
<script>
export default{
name:'upload',
data(){
return {
headers:{
token:'xx',
},
uploadData:{
fileExtension:'',
accessType:'',
needReviewUrl: true,
},
fileList:[]
}
},
methods:{
handleBeforeUpload(file){
const lastPoint = file.name.lastIndexOf('.');
this.uploadData.fileExtension = file.name.slice(lastPoint+1);
return true;
},
handleSuccess(response){
this.fileList = [];
const { reviewUrl } = response.data[0];
// 这里可以获取到上传成功的图片了,然后可以进行图片回显或者请求ocr接口识别图片
},
handleError(err){
this.fileList = [];
},
// 上传图片最大张数限制
handleExceed(files){
if(files.length > 1) {
this.$message.error('一次只能上传一张图片')
}
},
}
}
</script>
5. 通过a标签下载pdf文件
当后端小哥返回一个pdf文件的url地址,前端需要点击这个url把pdf文件下载下来的操作
<el-button type="text" @click="handleDownloadPdf">下载pdf文件</el-button>
methods:{
handleDownloadPdf(){
const pdfUrl = 'xxxx';// 假设这个是pdf文件的url地址
const fileName = 'xxx.pdf';//假设这个是pdf下载后的文件名字
const xhr = new XMLHttpRequest();
xhr.open('GET', pdfUrl, true);
xhr.responseType = 'blob';
xhr.onload = ()=>{
const blob = xhr.response;
const link = document.createElement('a');
link.download = fileName;
link.href = URL.createObjectURL(blob);
document.body.appendChild(link);
link.click();
document.body.appendRemove(link);
}
xhr.send();
}
}
6. el-tree 权限树结构可以进行 过滤数据
效果如下:
<div class="tree-container">
<el-input v-model="filterText" placeholder="请输入关键字进行过滤"></el-input>
<el-tree
ref="tree"
v-loading="treeLoading"
:data="dataTree"
:props="defaultProps"
highlightCurrent
:check-strictly="false"
default-expand-all
node-key="id"
:filter-node-method="filterNode"
@node-click="nodeClick"
>
</el-tree>
</div>
<script>
export default {
name:'tree',
data(){
return {
dataTree:[],
defaultProps:{
children:'children',
label:'name'
},
filterText: '',
treeLoading: false,
nodeClickData: null,//被选中的节点
}
},
watch:{
filterText(val){
this.$refs.tree.filter(val);
}
},
methods:{
nodeClick(data){
this.nodeClickData = data;
},
filterNode(value, data){
if(!value) return true;
return data.name.indexOf(value) !== -1;
}
}
}
</script>
7. table复选框设置禁用状态以及表头设置红色星号
<el-table
ref="table"
:data="tableData"
border
:header-cell-class-name="setHeaderCellClassName"
@selection-change="selectionChange"
<el-table-column type="selection" :selectable="selectable"></el-table-column>
<el-table-column type="index" label="序号"></el-table-column>
<el-table-column label="姓名"></el-table-column>
</el-table>
<script>
export default {
name:'table',
data(){
return {
tableData:[]
}
},
methods:{
// 设置table表格复选框是否禁用
selectable(row){
const arrs = ['aa','bb'];//这里放用来判断的条件
const {status} = row;
if(arrs.includes(status)){
return false;
}
return true;
},
// 给table表格设置表头
setHeaderCellClassName(obj){
const columnIndex = [2,3,4,5,6,7,8...]; // 这里是根据table表里面的列index值作为判断条件来处理的,也可以换其他条件哈,根据业务需求来即可。
if(columnIndex.includes(obj.columnIndex)){
return 'class类名';
}
return '';
}
}
}
</script>
<style lang="scss" scoped>
</style>
8. 数字转化为金额形式(千分位)
效果如下:
export function numTurnThousands(val, digit = 2){
let res = '';
if(val === 0){
return parseFloat(val).toFixed(digit);
}
if(!val){
return '';
}
if(val !== ''){
// 如果val传进来的是number类型,需要先转化为string类型
let strVal = val+'';
strVal = parseFloat(strVal.replace(/,/g,'')).toFixed(digit);
if(strVal.indexOf('.')===-1){
res = strVal.replace(/\d{1,3}(?=(\d{3}+$))/g,'$1,');
}else{
res = strVal.replace(/(\d)(?=(\d{3})+\.)/g,'$1,');
}
}else{
res = '';
}
return res;
}
9. 判断用户输入的是手机号还是文字?
场景描述:
在一个input输入框中,根据用户输入的内容来传递参数,例如:
假设用户输入 135xxxxxxxx, 那么请求接口所传的参数为 param.mobile = '135xxxxxxx';
假设用户输入 135你好哈哈哈哈,那么请求接口所传的参数为 param.name = '135你好哈哈哈哈哈哈';
searchVal(val){
if(!val || val==='') return;
var content = val.replace(/(^\s+)|(\s+$)/g,'');
var regPhone = /^1[3458][0-9]\d{8}$/;
const param = {};
if(!Number.isNaN(Number(content)) && regPhone(content)){ // Number.isNaN(Number(xxx)) 这个是判断内容是否全是数字,如果全是数字的话,则返回false,反之,则为true。
param.mobile = content;
}else{
param.name = content;
}
// 请求接口...
}