1.Vue中的watch与computed
":转义字符双引号" "
location.href: 当前页面打开URL页面
computed-计算属性
-
computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;
-
computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化,举例:购物车里面的商品列表和总金额之间的关系,只要商品列表里面的商品数量发生变化,或减少或增多或删除商品,总金额都应该发生变化。这里的这个总金额使用computed属性来进行计算是最好的选择
watch-监听
-
watch主要用于监控vue实例的变化,它监控的变量当然必须在data里面声明才可以,它可以监控一个变量,也可以是一个对象
-
watch一般用于监控路由、input输入框的值特殊处理等等,它比较适合的场景是一个数据影响多个数据
2.$router.options.routes与$route
this.$router.options.routes 可以拿到初始化时配置的路由规则
this.$route 可以拿到当前路由信息 (包括路由路径,参数0)
3.Vue.mixins和vuex的区别
Vue.minxins可用于封装,提取公共部分
与vuex的区别:
- vuex:用来做状态管理的,里面定义的变量在每个组件中均可以使用和修改,在任一组件中修改此变量的值之后,其他组件中此变量的值也会随之修改。
- Mixins:可以定义共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。
与公共组件的区别:
- 组件:在父组件中引入组件,相当于在父组件中给出一片独立的空间供子组件使用,然后根据props来传值,但本质上两者是相对独立的。
- Mixins:则是在引入组件之后与组件中的对象和方法进行合并,相当于扩展了父组件的对象与方法,可以理解为形成了一个新的组件。
————————————————
【Vue原理】Mixin - 白话版_神仙朱的博客-优快云博客_vue.mixin
4.@click与@click.native
如果是普通的html,使用@click就可以触发。
如果使用组件和路由,在router-link标签中就需要使用@click.native。不然就只会跳转而不会触发事件。
5.Vue树形菜单展开与折叠
// 是否展开table(展开与折叠切换)
handleExpand() {
this.isExpand = !this.isExpand
this.$nextTick(() => {
this.forArr(this.tableData, this.isExpand)
})
},
// 遍历
forArr(arr, isExpand) {
arr.forEach(i => {
// toggleRowExpansion(i, isExpand)用于多选表格,切换某一行的选中状态,如果使用了第二个参数,则是设置这一行选中与否(selected 为 true 则选中)
this.$refs.tableData.toggleRowExpansion(i, isExpand)
if (i.children) {
this.forArr(i.children, isExpand)
}
})
},
6.Element表格相同列合并
<template>
<el-table
:data="tableData"
:span-method="objectSpanMethod"
border
style="width: 100%; margin-top: 20px"
>
</el-table>
</template>
<script>
//合并列
mergeCol({ row, column, rowIndex, columnIndex }){undefined
let data = this.tableData; //拿到当前table中数据
let cellValue = row[column.property]; //当前位置的值
let noSortArr = ["province"]; //不需要合并的字段(不进行合并行的prop)
if (cellValue && !noSortArr.includes(column.property)) {undefined
let prevRow = data[rowIndex - 1]; //获取到上一条数据
let nextRow = data[rowIndex + 1]; //下一条数据
if (prevRow && prevRow[column.property] === cellValue) { //当有上一条数据,并且和当前值相等时
return { rowspan: 0, colspan: 0 };
} else {undefined
let countRowspan = 1;
while (nextRow && nextRow[column.property] === cellValue) { //当有下一条数据并且和当前值相等时,获取新的下一条
nextRow = data[++countRowspan + rowIndex];
}
if (countRowspan > 1) {undefined
return { rowspan: countRowspan, colspan: 1 };
}
}
}
},
</script>
7.Vue表格样式封装
/* 表格样式 */
.tabData {
width: 100%;
border: 2px solid #00ffff;
text-align: center;
/* height:500px; */
}
.tabData thead tr, tbody tr {
width:100%;
table-layout:fixed;/* 列宽由表格宽度和列宽度设定 */
height: 40px;
}
.tabData td {
border: 2px solid #00ffff;
}
.table_body{
height:630px;
overflow-y:scroll;
overflow-x:hidden;
}
/* .tabData tbody{
height:300px;
width:100%;
overflow-y:scroll;
overflow-x:hidden;
} */
/* 打印样式 */
.table_bottom {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
}
.table_bottom button {
color: #fbfcfc;
background: #054f65;
}
8.数据封装
handLerdatas(arr){
let obj = {};
arr.forEach((item,index)=>{
let {gnm} = item
if(!obj[gnm]){
obj[gnm] = {
gnm,
children:[]
}
}
obj[gnm].children.push(item)
})
let data = Object.values(obj); // 最终输出
return data;
},
9.Vue文件下载
/**
* 文件流转换 主要代码块,可自定义下载文件名称
* @param {} data
*/
export function download (data,titName) {
if(!data){
return
}
const content = data
const blob = new Blob([content],{type: "application/vnd.ms-excel"})
const fileName = titName?titName: '报废卡号.xlsx'
if ('download' in document.createElement('a')) { // 非IE下载
const elink = document.createElement('a')
elink.download = fileName
elink.style.display = 'none'
elink.href = URL.createObjectURL(blob)
document.body.appendChild(elink)
elink.click()
URL.revokeObjectURL(elink.href) // 释放URL 对象
document.body.removeChild(elink)
} else { // IE10+下载
navigator.msSaveBlob(blob, fileName)
}
}
一定要加 responseType: ‘blob’。
// 引入方法
import { download } from '../../../api/apiStock'
// 数据请求
getDownload(){
this.$axios({
url:'接口地址(get参数最好拼接在url上)',
methods:'get',
responseType: 'blob',
}).then(res=>{
download(res.data,'卡号卡密.xlsx')
})
}
//给按钮绑定click 事件 = getDownload()即可
10.Element文件上传下载
<template>
<div class="app-container">
<el-form :model="queryParams" :rules="rules" ref="queryForm" :inline="true" v-show="showSearch" >
<el-form-item label="行政区划">
<el-cascader
:style="{ width: '90%' }"
v-model="addvcd"
:options="addvcdList"
:props="addvcdProps"
@change="handleChangeAddvcdQy"
></el-cascader>
</el-form-item>
<el-form-item label="水库选择" prop="rscd">
<el-select
:style="{ width: '90%' }"
v-model="queryParams.rscd"
placeholder="请选择"
filterable
@change="handleChangeOfrsvrcd"
>
<el-option
v-for="item in rsvbListQy"
:key="item.rscd"
:label="item.rsnm"
:value="item.rscd"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="资料类型" prop="filetype">
<el-select v-model="queryParams.filetype" placeholder="请选择资料类型" :style="{ width: '90%' }" clearable size="small">
<el-option
v-for="dict in dict.type.projectdocument_filetype"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="年份" prop="year">
<el-date-picker clearable size="small"
:style="{ width: '90%' }"
v-model="queryParams.year"
type="year"
format="yyyy"
value-format="yyyy"
placeholder="选择年份">
</el-date-picker>
</el-form-item>
<el-form-item label="文件名称" prop="title">
<el-input
:style="{ width: '90%' }"
v-model="queryParams.title"
placeholder="标题"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['oam:tprojectdocumentr:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['oam:tprojectdocumentr:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['oam:tprojectdocumentr:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['oam:tprojectdocumentr:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="tprojectdocumentrList" @selection-change="handleSelectionChange" border>
<el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="主键ID" align="center" prop="id" /> -->
<el-table-column label="标题" align="left" prop="title" width="260" show-overflow-tooltip/>
<el-table-column label="资料类型" align="center" prop="filetype" width="120">
<template slot-scope="scope">
<dict-tag :options="dict.type.projectdocument_filetype" :value="scope.row.filetype"/>
</template>
</el-table-column>
<el-table-column label="年份" align="center" prop="year" width="120" />
<!-- <el-table-column label="资料路径" align="center" prop="path" show-overflow-tooltip/> -->
<el-table-column label="上传人" align="center" prop="username" width="100" />
<el-table-column label="上传时间" align="center" prop="uploadtm" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.uploadtm, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<!-- <el-table-column label="资料大小(KB)" align="center" prop="size" /> -->
<!-- <el-table-column label="下载量" align="center" prop="downloads" /> -->
<el-table-column label="资料" align="center" prop="path" show-overflow-tooltip>
<template slot-scope="scope">
<div v-if="scope.row.filetype==1" class="imageStyle1">
<a title="文件" href="javascript:;" v-for="(item,index) in scope.row.fileNames" :key="index+item+1" :src="item.path" >{{item.name}}</a>
</div>
<div v-if="scope.row.filetype==2" class="imageStyle2">
<el-image title="预览" v-for="(item,index) in scope.row.fileLists" :key="index+item+2" :src="item" fit="cover" :style="imgStyle" :preview-src-list="scope.row.fileLists" />
</div>
<div v-if="scope.row.filetype==3" class="imageStyle2">
<!-- <el-image title="预览" v-for="(item,index) in scope.row.fileLists" :key="index+item+2" :src="item" fit="cover" :style="imgStyle" :preview-src-list="scope.row.fileLists" /> -->
<video title="播放" :style="imgStyle" v-for="(item,index) in scope.row.fileLists" :key="index+item+3" :src="item" controls>
<source src="movie.ogg" type="video/ogg">
<source src="movie.mp4" type="video/mp4">
<source src="movie.webm" type="video/webm">
<object data="movie.mp4" width="320" height="240">
<embed width="320" height="240" src="movie.swf">
</object>
</video>
</div>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="nt" width="260" show-overflow-tooltip/>
<el-table-column label="操作" align="center" width="180" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['oam:tprojectdocumentr:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['oam:tprojectdocumentr:remove']"
>删除</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleLookup(scope.row)"
>查看</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改工程资料管理对话框 -->
<el-dialog :title="title" :visible.sync="open" width="700px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="标题" prop="title">
<el-input v-model="form.title" placeholder="请输入资料名称" :style="{ width: '90%' }"/>
</el-form-item>
<el-form-item label="资料类型" prop="filetype">
<el-select v-model="form.filetype" placeholder="请选择资料类型" :style="{ width: '90%' }" @change="selectFiletype">
<el-option
v-for="dict in dict.type.projectdocument_filetype"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="年份" prop="year">
<el-date-picker
:style="{ width: '90%' }"
v-model="form.year"
type="year"
value-format="yyyy"
format="yyyy"
placeholder="选择年份">
</el-date-picker>
</el-form-item>
<el-form-item label="资料" prop="path">
<!-- <el-input v-model="form.path" placeholder="请输入资料路径" :style="{ width: '90%' }" /> -->
<el-upload
ref="upload"
:limit="9"
multiple
:accept="upload.accept"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:action="upload.url"
:headers="upload.headers"
:file-list="upload.fileList"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false">
<el-button slot="trigger" size="small" type="primary">选取资料</el-button>
<el-button style="margin-left: 10px;" size="small" type="success" :loading="upload.isUploading" @click="submitUpload">上传到服务器</el-button>
<div slot="tip" class="el-upload__tip">{{upload.msg}}</div>
</el-upload>
</el-form-item>
<el-form-item label="上传人" prop="username">
<el-input v-model="form.username" placeholder="请输入上传人" :style="{ width: '90%' }" />
</el-form-item>
<el-form-item label="上传时间" prop="uploadtm">
<el-date-picker clearable size="small"
:style="{ width: '90%' }"
v-model="form.uploadtm"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择上传时间">
</el-date-picker>
</el-form-item>
<!-- <el-form-item label="资料大小" prop="size">
<el-input v-model="form.size" placeholder="请输入资料大小" :style="{ width: '90%' }" />
</el-form-item> -->
<el-form-item label="备注" prop="nt">
<el-input v-model="form.nt" type="textarea" rows="5" placeholder="请输入内容" :style="{ width: '90%' }" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
<el-dialog
:title="form.title"
:visible.sync="lookupShow"
width="30%"
center>
<el-row>
<el-col :span="12">
<span class="front1">年 份:</span>{{form.year}}
</el-col>
<el-col :span="12">
<span class="front1">上 传 人:</span>{{form.username}}
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<span class="front1">上传时间:</span>{{form.uploadtm}}
</el-col>
<el-col :span="12">
<span class="front1">资料类型:</span>
<span v-if="form.filetype==1">文档</span>
<span v-if="form.filetype==2">图片</span>
<span v-if="form.filetype==3">视频</span>
</el-col>
</el-row>
<el-row>
<el-col :span="24"><span class="front2">简介:</span></el-col>
</el-row>
<el-row>
<el-col :span="24">
<div style="margin-left:10%"><span v-html="form.nt" class="descrt"></span></div>
</el-col>
</el-row>
<el-row>
<el-col :span="24"><span class="front2">资料:</span></el-col>
</el-row>
<el-row>
<el-col :span="24">
<div style="margin-left:10%" class="descrt2">
<div v-if="form.filetype==1" class="imageStyle1">
<a title="下载" href="javascript:;" v-for="(it,index) in form.fileNames" :key="index+it+1" :src="it.path" >{{it.name}}</a>
</div>
<div v-if="form.filetype==2" class="imageStyle2">
<el-image title="预览" v-for="(it,index) in form.fileLists" :key="index+it+2" :src="it" fit="cover" :style="imgStyle2" :preview-src-list="form.fileLists" />
</div>
<div v-if="form.filetype==3" class="imageStyle2">
<!-- <el-image title="预览" v-for="(item,index) in scope.row.fileLists" :key="index+item+2" :src="item" fit="cover" :style="imgStyle" :preview-src-list="scope.row.fileLists" /> -->
<video title="播放" :style="imgStyle2" v-for="(it,index) in form.fileLists" :key="index+it+3" :src="it" controls>
<source src="movie.ogg" type="video/ogg">
<source src="movie.mp4" type="video/mp4">
<source src="movie.webm" type="video/webm">
<object data="movie.mp4" width="320" height="240">
<embed width="320" height="240" src="movie.swf">
</object>
</video>
</div>
</div>
</el-col>
</el-row>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="cancel2">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { listTprojectdocumentr, getTprojectdocumentr, delTprojectdocumentr, addTprojectdocumentr, updateTprojectdocumentr } from "@/api/oam/basic/tprojectdocumentr";
import { getToken } from "@/utils/auth";
import { loadAddvcd, getRsrbDropdown } from "@/api/oam/basic/wrprsrbsin";
export default {
name: "Tprojectdocumentr",
dicts: ['projectdocument_filetype'],
data() {
return {
//图片样式
imgStyle2:{
width:'180px',
height:'100px',
},
//默认图片地址
defaultImgUrl:'http://127.0.0.1:9300/statics/2022/03/10/83490f24-1cf8-45c4-8bae-53afdcf3acd6.png',
//查看
lookupShow:false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 工程资料管理表格数据
tprojectdocumentrList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
filetype: null,
year: null,
title: null,
rscd: null,
},
addvcd:null,
// 表单参数
form: {},
//水库列表
rsvbListQy: [],
// 行政区划列表
addvcdList: [],
addvcdProps: {
emitPath: false,
checkStrictly: true,
// expandTrigger: 'hover'
},
// 表单校验
rules: {
filetype: [
{required: true, message: "资料类型不能为空", trigger: "change"}
],
},
// 上传参数
upload: {
// 是否禁用上传
isUploading: false,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
// 上传的地址
url: process.env.VUE_APP_BASE_API + "/file/upload",
// 上传的资料列表
fileList: [],
//资料上传的类型
accept:'.xls,.xlsx,.doc,.docx,.rar,.zip,.wps,.wpt',
//文字描述
msg:'只能上传文件,且不超过20M',
//文件上传大小:20M
size:20971520,
},
//图片样式
imgStyle:{
width:'70px',
height:'50px',
},
//文件地址List
filePathList:[],
//文件名List
fileNameList:[],
};
},
created() {
this.loadAddvcdList();
// this.getList();
},
methods: {
//获取行政区划数据
loadAddvcdList() {
loadAddvcd({ isTree: true }).then((res) => {
this.addvcdList = res.data;
this.addvcd=res.data[0].value;
this.getRsrbDropdownQy(this.addvcd);
this.getList();
});
},
// 查询区域行政区划选择事件
handleChangeAddvcdQy(value) {
this.queryParams.rscd = null;
this.getRsrbDropdownQy(value);
},
//根据行政区划查询水库
getRsrbDropdownQy(val) {
getRsrbDropdown({ addvcd: val }).then((res) => {
this.rsvbListQy = res.data;
});
},
//查询水库
handleChangeOfrsvrcd(value) {
this.queryParams.rscd=value;
this.getList();
},
/** 查询工程资料管理列表 */
getList() {
this.loading = true;
listTprojectdocumentr(this.queryParams).then(response => {
this.tprojectdocumentrList = response.rows;
this.tprojectdocumentrList.forEach((item,index)=>{
let lisPth = item.path.split(',');
let lisNam = item.filename.split(',');
if(lisPth.length>0){
let temp=[];
for(var i=0;i<lisPth.length;i++){
temp.push({name:lisNam[i]==null?'':lisNam[i],path:lisPth[i]==null?'':lisPth[i]});
}
this.tprojectdocumentrList[index].fileNames=temp;
}
this.tprojectdocumentrList[index].fileLists=item.path==null?'':item.path.split(',');
// this.tprojectdocumentrList[index].fileNames=item.title==null?'':item.title.split(',');
})
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 取消按钮
cancel2() {
this.lookupShow = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
id: null,
title: null,
filetype: '1',
filename: null,
year: null,
path: null,
username: null,
uploadtm: null,
size: null,
nt: null,
type: null,
downloads: null
};
this.fileNameList=[];
this.filePathList=[];
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.filePathList=[];
this.fileNameList=[];
this.addvcdList=[];
this.rsvbListQy=[];
this.loadAddvcdList();
},
//查看
handleLookup(row){
this.lookupShow=true;
this.form=row;
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加工程资料管理";
this.upload.fileList = [];
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.selectUploadType(row.filetype);
const id = row.id || this.ids
getTprojectdocumentr(id).then(response => {
this.form = response.data;
this.fileNameList=response.data.filename.split(',');
this.filePathList=response.data.path.split(',');
this.open = true;
this.title = "修改工程资料管理";
var tempList=[];
for(var i=0;i<this.fileNameList.length;i++){
tempList.push({name:this.fileNameList[i],url:this.filePathList[i]});
}
this.upload.fileList = tempList;
});
},
/**根据选项改变上传类型 */
selectUploadType(value){
switch(value){
case '1':
this.upload.accept='.xls,.xlsx,.doc,.docx,.rar,.zip,.wps,.wpt';
this.upload.msg='只能上传文件,且不超过20M';
break;
case '2':
this.upload.accept='.jpg,.png,.gif,.bmp';
this.upload.msg='只能上传图片,且不超过20M';
break;
case '3':
this.upload.accept='.mp4,.wmv,.m4v,.avi,.dat,.mkv,.flv,.vob';
this.upload.msg='只能上传视频,且不超过20M';
break;
default:
this.$modal.msgError("类型异常");
break;
}
},
/** 提交按钮 */
submitForm() {
if(this.filePathList.length<1){
this.$modal.msgError("上传资料不能为空");
return false;
}
this.$refs["form"].validate(valid => {
if (valid) {
this.form.path=this.filePathList.toString();
this.form.filename=this.fileNameList.toString();
if (this.form.id != null) {
updateTprojectdocumentr(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
this.filePathList=[];
this.fileNameList=[];
});
} else {
addTprojectdocumentr(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
this.filePathList=[];
this.fileNameList=[];
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除工程资料管理号为"' + ids + '"的数据项?').then(function() {
return delTprojectdocumentr(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
handleRemove(file, fileList) {
this.filePathList.forEach((item, index) => {
if (item == file.url){
this.filePathList.splice(index,1);
this.fileNameList.splice(index,1);
}
})
// if (this.fileList != null) {
//
// this.fileList.map((item, index) => {
// if (item.uid == file.uid) {
// this.fileList.splice(index, 1)
// }
// })
// }
},
/** 导出按钮操作 */
handleExport() {
this.download('oam/basic/tprojectdocumentr/export', {
...this.queryParams
}, `tprojectdocumentr_${new Date().getTime()}.xlsx`)
},
/**下载 */
handleDownload(row){
var name = row.title;
var url = row.path;
const a = document.createElement('a')
a.setAttribute('download', name)
a.setAttribute('target', '_blank')
a.setAttribute('href', url)
a.click()
},
//选择文件类型
selectFiletype(value){
this.form.filetype=value;
switch(value){
case '1':
this.upload.accept='.xls,.xlsx,.doc,.docx,.rar,.zip,.wps,.wpt';
this.upload.msg='只能上传文件,最多9个';
break;
case '2':
this.upload.accept='.jpg,.png,.gif,.bmp';
this.upload.msg='只能上传图片,最多9个';
break;
case '3':
this.upload.accept='.mp4,.wmv,.m4v,.avi,.dat,.mkv,.flv,.vob';
this.upload.msg='只能上传视频,最多3个';
break;
default:
this.$modal.msgError("类型异常");
break;
}
},
/**文件上传模块 */
// 文件提交处理
beforeUpload(file) {
if(this.form.filetype==null){
this.$modal.msgError("请选择上传资料类型");
return false;
}
if(file.size>this.upload.size){
this.$modal.msgError("上传文件过大");
return false;
}
var fileType = file.name.substring(file.name.lastIndexOf('.')+1).trim();
switch(this.form.filetype){
case '1':
this.upload.msg='';
if(fileType!='xls'&&fileType!='xlsx'&&fileType!='docx'&&fileType!='doc'&&fileType!='rar'&&fileType!='zip'&&fileType!='wps'&&fileType!='wpt'){
this.$modal.msgError("只能上传文件类型");
return false;
}
break;
case '2':
if(fileType!='jpg'&&fileType!='png'&&fileType!='gif'&&fileType!='bmp'){
this.$modal.msgError("只能上传图片类型");
return false;
}
break;
case '3':
if(fileType!='mp4'&&fileType!='wmv'&&fileType!='m4v'&&fileType!='avi'&&fileType!='dat'&&fileType!='mkv'&&fileType!='flv'&&fileType!='vob'){
this.$modal.msgError("只能上传视频类型");
return false;
}
break;
default:
this.$modal.msgError("类型异常");
break;
}
return true;
},
submitUpload() {
this.$refs.upload.submit();
},
// 文件上传中处理
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
// 文件上传成功处理
handleFileSuccess(response, file, fileList) {
// this.form.filename = response.data.name;
var si=0;
if(this.form.size){
si=this.form.size;
}
fileList.forEach(item=>{
si+=(item.size/1024/1024);
})
this.form.size=si;
this.form.uploadtm=this.$moment().format('YYYY-MM-DD');
this.form.type=file.name.substring(file.name.lastIndexOf('.')+1);
this.filePathList.push(response.data.url);
this.fileNameList.push(file.name.replace(/,/g, ""));
this.upload.isUploading = false;
this.$modal.msgSuccess("上传成功!");
}
}
};
</script>
<style scoped>
/* 文档样式 */
.imageStyle1{
display: flex;
flex-direction:column;
align-items:flex-start;
align-content:center;
justify-content:flex-start;
}
.imageStyle1 a{
color: #515a6e;
}
/* 图片样式 */
.imageStyle2{
display: flex;
flex-direction:row;
flex-wrap:wrap;
justify-content:flex-start;
align-content:center;
}
.imageStyle2 .el-image{
display: inline-block;
margin: 2px 10px;
}
.imageStyle2 video{
display: inline-block;
margin: 2px 10px;
}
/* 表格超出隐藏 */
.el-table__row{
height: 60px;
overflow:hidden;
}
/**简介样式 */
.descrt{
text-overflow: -o-ellipsis-lastline;
height: 260px;
overflow: auto;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 7;
-webkit-box-orient: vertical;
border: 1px solid #e6ebf5;
text-indent: 2em; /*缩进*/
padding: 6px;
}
.descrt::-webkit-scrollbar{
display: none;
}
/**资料样式 */
.descrt2{
display: flex;
justify-content: space-between;
height:150px;
overflow: auto;
border: 1px solid #e6ebf5;
padding:10px ;
}
.descrt2::-webkit-scrollbar{
display: none;
}
.front1{
font-weight: bold;
font-size: 14px;
padding: 10px;
line-height: 30px;
}
.front2{
font-weight: bold;
font-size: 14px;
padding: 10px;
line-height: 30px;
}
</style>
11.Vue全局变量
1.config.json
{
"BASE_URL" : "http://192.168.0.119:8081",
"BASE_YT": "http://192.168.0.119:8088/cloud/getCloudByPage/E99/1/24",
"BASE_HQ": "http://192.168.0.119:8088/cloud/getCloudByPage/HQ/1/24"
}
2.request.js
// 云图
export function request_yt(config){
const instance1 = new axios.create({
baseURL:Vue.prototype.$baseUrl.BASE_YT,
timeout:5000
});
return instance1(config)
}
3.main.js
import url from "./assets/config.json"
Vue.prototype.$baseUrl = url //根路径
4.erquest.js
import Vue from 'vue'
// 云图
export function request_yt(config){
const instance1 = new axios.create({
baseURL:Vue.prototype.$baseUrl.BASE_YT,
timeout:5000
});
return instance1(config)
}
12.Vue视频dplayer使用Hls
教程地址:http://www.inner-peace.cn/blog/vue_dplayer_hls/
13.$nextTick
定义:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
this.$nextTick(() => {
})
14.vue+element-ui Select 选择器获取选择项
<el-select v-model="value" filterable placeholder="请选择" @change="select">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
data() {
return {
options: [
{ label: '选项1', value: '1' },
{ label: '选项2', value: '2' },
{ label: '选项3', value: '3' },
{ label: '选项4', value: '4' }
],
value: '',
// 选中的选项
item: {}
}
},
methods: {
select(value) {
this.item = this.options.find((item) => {
return item.value === value
})
}
}
15.Element时间范围控件
<template>
<el-date-picker
v-model="tmval"
type="daterange"
align="right"
unlink-panels
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
:editable="false"
:clearable="false"
:picker-options="pickerOptions">
</el-date-picker>
</template>
<script>
pickerOptions: {
shortcuts: [{
text: '最近一周',
onClick(picker) {
const end = self.$moment();
const start = self.$moment().subtract(7, 'days');
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = self.$moment();
const start = self.$moment().subtract(30, 'days');
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = self.$moment();
const start = self.$moment().subtract(90, 'days');
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一年',
onClick(picker) {
const end = self.$moment();
const start = self.$moment().subtract(365, 'days');
picker.$emit('pick', [start, end]);
}
}]
</script>
16.Js生成随机数
//获取数据
getData () {
//数据
this.echartData = [
this.mockData(12),
this.mockData(12),
this.mockData(12),
this.mockData(12)
]
this.$nextTick(_ => {
this.drawChart()
})
},
//模拟数据
mockData (len) {
let arr = []
for (var i = 0; i < len; i++) {
arr.push(this.randomNum(200, 500))
}
return arr
},
//随机数生成
randomNum (minNum, maxNum) {
switch (arguments.length) {
case 1:
return parseInt(Math.random() * minNum + 1);
break;
case 2:
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum);
break;
default:
return 0;
break;
}
//获取数据
getData () {
//请求数据
this.seriesData = this.mockData(8)
this.$nextTick(_ => {
this.drawBar()
})
},
//模拟数据
mockData (len) {
let arr = []
for (var i = 0; i < len; i++) {
arr.push(this.randomNum(0, 100))
}
return arr
},
//随机数生成
randomNum (minNum, maxNum) {
switch (arguments.length) {
case 1:
return parseInt(Math.random() * minNum + 1);
break;
case 2:
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum);
break;
default:
return 0;
break;
}
},
17.他人写的Echarts规范
<template>
<div>
<div id="chartgroup" style="
width: 96%;
height: 78%;
position: relative;
display: flex;
top: 20%;
left: 2.5%;
text-align: center;
">
<div ref="barCahrt" style="flex: 10; height: 24vh"></div>
</div>
</div>
</template>
<script>
import { EleResize } from "../../assets/js/esresize";
export default {
//水量平衡
name: "WATERBALANCE",
data () {
return {
xAxisData: [
'1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'
],
//柱条颜色
barColor1: ["#0095da", "#035682", "#073a5a"],
barColor2: ["#7be450", "#448b46", "#194447"],
};
},
mounted () {
this.initData();
window.addEventListener("resize", () => {
this.drawBar();
});
},
created () { },
methods: {
//随机数生成
randomNum (minNum, maxNum) {
switch (arguments.length) {
case 1:
return parseInt(Math.random() * minNum + 1);
break;
case 2:
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum);
break;
default:
return 0;
break;
}
},
//模拟数据
mockData (len) {
let arr = []
for (var i = 0; i < len; i++) {
arr.push(this.randomNum(0, 100))
}
return arr
},
// 初始化数据
initData () {
this.getData();
},
//获取数据
getData () {
//请求数据
this.drawBar()
},
//绘图
drawBar () {
var that = this;
var barChart = this.$echarts.init(this.$refs.barCahrt);
let chartgroup = document.getElementById("chartgroup");
barChart.setOption({
//背景色
// backgroundColor: "#001f36",
//提示框组件
tooltip: {
show: true,
trigger: "item", //触发类型
},
//缩放
dataZoom: {
start: 0,
end: 100,
type: "inside",
disabled: true,
},
legend: {
show: true,
top: 10,
right: 0,
textStyle: {
color: '#fff',
fontSize: this.$echartsFont(12),
},
itemWidth: 10,
itemHeight: 10,
itemStyle: {
borderWidth: 1
}
},
xAxis: {
type: "category",
data: that.xAxisData,
//标签文字颜色
axisLabel: {
show: true,
textStyle: {
color: "#fcf9f1",
},
fontSize: this.$echartsFont(12),
// rotate: 20
},
//x轴样式
axisLine: {
lineStyle: {
color: "#d2dfe7",
width: 1,
},
// fontSize: 5,//字体大小
},
axisTick: {
show: false, // 去除刻度线
},
},
//网格位置
grid: {
top: "15%",
bottom: "15%",
left: "10%",
},
yAxis: {
name: "(亿m³)", //标签名字
nameTextStyle: {
color: "#c2d0db",
fontSize: this.$echartsFont(12),
},
type: "value",
//坐标轴在 grid 区域中的分隔线
splitLine: {
show: true,
lineStyle: {
color: "#34526a",
type: "dashed",
},
},
//标签文字颜色
axisLabel: {
show: true,
textStyle: {
color: "#c2d0db",
},
fontSize: this.$echartsFont(12),
},
//最大最小
// min: 0,
// max: 50,
},
series: [
{
name: "供水",
data: that.mockData(12),
type: "bar",
barWidth: "20%", //柱条宽度
itemStyle: {
// 颜色渐变
normal: {
borderWidth: 0.5, //柱条描边宽度
borderColor: this.barColor1[0], //柱条描边颜色
//柱条渐变色:左、下、右、上
color: new this.$echarts.graphic.LinearGradient(
0,
1,
0,
0,
[
{
offset: 0,
color: this.barColor1[0], // 0% 处的颜色
},
{
offset: 0.5,
color: this.barColor1[1], // 40% 处的颜色
},
{
offset: 1,
color: this.barColor1[2], // 90% 处的颜色
},
],
false
),
},
},
},
{
name: "需水",
data: that.mockData(12),
type: "bar",
barWidth: "20%", //柱条宽度
itemStyle: {
// 颜色渐变
normal: {
borderWidth: 0.5, //柱条描边宽度
borderColor: this.barColor2[0], //柱条描边颜色
//柱条渐变色:左、下、右、上
color: new this.$echarts.graphic.LinearGradient(
0,
1,
0,
0,
[
{
offset: 0,
color: this.barColor2[0], // 0% 处的颜色
},
{
offset: 0.5,
color: this.barColor2[1], // 40% 处的颜色
},
{
offset: 1,
color: this.barColor2[2], // 90% 处的颜色
},
],
false
),
},
},
}
],
});
//让图表跟随屏幕自动适应
let listener = function () {
barChart.resize();
};
EleResize.on(chartgroup, listener);
},
},
};
</script>
<style lang="less" scoped>
.ul {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
font-size: 1vh;
}
.ul li {
list-style-type: none; /*去掉项目符号*/
clear: both;
width: 100px;
display: inline; /*li {display: inline} 让 li 不再独占一行, 宽度上只会得到必要的而不是占有所在容器的全宽*/
font-size: larger;
text-decoration: none;
cursor: pointer;
}
//图例样式
#grad1,
#grad2,
#grad3,
#grad4 {
height: 1.2vh;
width: 1.2vh;
display: inline-block;
}
#grad1 {
background-image: linear-gradient(#073a5a, #044f78, #035682);
border: #0095da 1px solid;
}
#grad2 {
background-image: linear-gradient(#194447, #2f6947, #448b46);
border: #7be450 1px solid;
}
#grad3 {
background-image: linear-gradient(#1f3052, #3e3961, #533e6b);
border: #8e5390 1px solid;
}
</style>
18.知识点
- reduce:条件统计(一群人里面男生有几个,es6写法)
- filter:可以用在删除里
- || :如果前面有,用前面的,否则用后面的
- watch(监视):完整写法:watch(){deep:true,handler(value){}}
- compute(计算):完整写法:compute(){set(value){};get(){}}
- getStudentName(childValue,...a) {console.log('App收到了学生名',name,a);}
- this.$emit():绑定自定义事件
- this.$off():解绑自定义事件,解绑多个参数用数组,解绑所有不传参
- this.$destroy():销毁了当前组件的实例,销毁后所有自定义事件全部不奏效
- @click.native=“”:给vue组件绑定事件时候,必须加上native ,不然不会生效
- this.$set(this.student,'sex','男'); 添加响应式数据
- @blur:input框失去焦点事件
- .hasOwnProperty(‘' '):某个对象什么有没有某个属性
- e.target.value:获取目标对象e的值
19.Vue判断是否定义
-
typeof (obj) == ’undefined‘
-
obj == undefined
null与undefined区别:JS 中的 undefined 和 null 的区别_C澒的博客-优快云博客_js null和undefined 区别
19.Vue全局过滤器
filters/index.js
// 1. 导入dayjs
import dayjs from 'dayjs';
// 2. dayjs 默认语言是英文,我们这里配置为中文
import 'dayjs/locale/zh-cn';
// 3. 引入 relativeTime
import rTime from 'dayjs/plugin/relativeTime';
// 4. 加载中文语言包
dayjs.locale('zh-cn');
// 5. 加载相对时间插件
dayjs.extend(rTime);
/**
* 6. 定义过滤器,通过 dayjs().to(dayjs(val)) 方法把【当前时间】处理为【相对时间】
*/
export function relativeTime(val) {
return dayjs().to(dayjs(val));
}
/**
* 将字符转化为以千为单位的字符
* @param {*} val 待转换字符
* @returns
*/
export function hotNumber(val) {
const num = parseInt(val);
if (num < 1000) return val;
// 将 val 转为字符串
val = val + '';
// 获取以 千 为单位的值
return val.substring(0, val.length - 3) + 'k';
}
main.js
// 导入过滤器
import * as filters from './filters';
// 注册过滤器
Object.keys(filters).forEach((key) => {
Vue.filter(key, filters[key]);
});
使用
<!-- 热度 -->
<view class="hot-box">
<image class="hot-icon" src="@/static/images/hot-icon.png" />
<text class="hot-text">{{ data.views | hotNumber }} 热度</text>
</view>
20.Vue打包后生成一个可修改接口地址的配置文件
先给几个参考:
webpack 打包vue项目后生成一个可修改接口地址的配置文件
感谢!!!
再来贴我自己的代码:
(普通版)第一步:在 static 静态文件中新建一个 serverconfig.js 文件,js 代码如下:
window.global_url = {
Base_url: "https:www.rioyi.com:50000/inhouse"
};
注意是src下面的static文件夹 不是打包后dist里面的!
第二步:在 未打包的 index.html 中引入 static 文件夹下的 serverconfig.js 文件 (vue-element-admin:public/index.html)
<script src="./static/serverconfig.js"></script>
第三步:在需要的地方使用:(我是在单独的https里面或者main.js里面) (vue-element-admin:request.js中引入)
import axios from 'axios'
// 生成一个可以修改服务器地址的配置文件
var serverbaseUrl = window.global_url.Base_url;
console.log(serverbaseUrl, 'serverbaseUrl')
// 修改配置的地址
axios.defaults.baseURL = serverbaseUrl;
Vue.prototype.$ = $
Vue.prototype.$http = axios
// Vue.prototype.$message = Message
Vue.prototype.$echarts = echarts
// 挂载echarts水球图
// Vue.prototype.echartsliquidfill = echartsliquidfill
Vue.use(ElementUI);
// // 设置请求拦截器,为请求对象添加token,这是后续权限api要求的
// Vue.prototype.$http.interceptors.request.use(req => {
// // req就是请求对象
// // console.log(req)
// // 基于请求拦截器显示响应进度条
// NProgress.start();
// // 为请求对象设置携带token的属性
// req.headers.Authorization = sessionStorage.getItem('token');
// // 最后必须返回req
// return req;
// });
// // 设置响应拦截器
// Vue.prototype.$http.interceptors.response.use(
// res => {
// // 基于响应拦截器隐藏响应进度条
// NProgress.done();
// return res;
// },
// err => {
// // 当服务器离线无法登录,给一下提示信息
// Vue.prototype.$message.error('服务器网络错误!');
// console.log('服务器网络错误!');
// return Promise.reject(err);
// }
// );
Vue.config.productionTip = false
第四步:打包生成
在我们打包之后 可以看到 config 文件会原样输出并没有被打包,部署人员可以直接通过该文件来修改config.js里面的接口地址就可以啦!
21.Vue.set()方法
21.Vue判断是否存在某属性
Do not access Object.prototype method 'hasOwnProperty' from target object 解析
编写代码时,如果你使用eslint的话,写下如下代码:
let obj = {}
obj.hasOwnProperty('xxx')
此时会在编辑器中提示你一个错误警告:
Do not access Object.prototype method 'hasOwnProperty' from target object,发现是新版本的ESLint使用了禁止直接调用 Object.prototypes
的内置属性开关,可以发现ESLint 配置文件中的 "extends": "eslint:recommended"
属性启用了此规则。
你可以使用如下形式:
Object.prototype.hasOwnProperty.call(obj, 'xxx')
22.Vue路由传参
vue路由传参
一、router-link路由导航
父组件: 使用<router-link to = "/跳转路径/传入的参数"></router-link>
例如:<router-link to="/a/123">routerlink传参</router-link>
<router-link to="/a/123">routerlink传参</router-link>
子组件: this.$route.params.num接收父组件传递过来的参数
mounted () {
this.num = this.$route.params.num
}
路由配置::{path: '/a/:num', name: A, component: A}
地址栏中的显示::http://localhost:8080/#/a/123
二、调用$router.push实现路由传参
父组件: 绑定点击事件,编写跳转代码
<button @click="deliverParams(123)">push传参</button>
methods: {
deliverParams (id) {
this.$router.push({
path: `/d/${id}`
})
}
}
子组件: this.$route.params.id接收父组件传递过来的参数
mounted () {
this.id = this.$route.params.id
}
路由配置::{path: '/d/:id', name: D, component: D}
地址栏中的显示::http://localhost:8080/#/d/123
三、通过路由属性中的name匹配路由,再根据params传递参数
父组件: 匹配路由配置好的属性名
<button @click="deliverByName()">params传参</button>
deliverByName () {
this.$router.push({
name: 'B',
params: {
sometext: '一只羊出没'
}
})
}
子组件:
<template>
<div id="b">
This is page B!
<p>传入参数:{{this.$route.params.sometext}}</p>
</div>
</template>
路由配置: 路径后面不需要再加传入的参数,但是name必须和父组件中的name一致{path: '/b', name: 'B', component: B}
地址栏中的显示: 可以看出地址栏不会带有传入的参数,且再次刷新页面后参数会丢失http://localhost:8080/#/b
四、通过query来传递参数
父组件:
<button @click="deliverQuery()">query传参</button>
deliverQuery () {
this.$router.push({
path: '/c',
query: {
sometext: '这是小羊同学'
}
})
}
子组件:
<template>
<div id="C">
This is page C!
<p>这是父组件传入的数据: {{this.$route.query.sometext}}</p>
</div>
</template>
路由配置: 不需要做任何修改{path: '/c', name: 'C', component: C}
地址栏中的显示: (中文做了转码)http://localhost:8080/#/c?sometext=%E8%BF%99%E6%98%AF%E5%B0%8F%E7%BE%8A%E5%90%8C%E5%AD%A6
编辑于 2020-05-28 12:06
2.CSS样式
1.隐藏滚动条
.descrt2{
height:110px;
overflow: auto;
}
.descrt2::-webkit-scrollbar{
display: none;
}
2.显示2行,超出省略号
CSS实现div内文字显示两行,超出两行部分省略号显示
用的是-webkit-私有属性。
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
3.v-deep
地址:element-ui中el-input需要改变placeholder的字体颜色 - 苏小落 - 博客园
4.Element table表格样式设置
/* 修改头部背景和字体颜色 */
.el-table th{background: #344067;color: #fff;font-weight: 500;}
/* 修改表头字体颜色 */
.el-table thead {color: #8EB7FA;}
/* 修改头部单元格边框颜色 */
.el-table th.is-leaf {border: 1px solid #114696}
/* 修改【基数】行背景 */
.el-table tr{background: #1f284c;}
/* 修改【基数】行单元格边框 */
.el-table tr td{border: 1px solid #114696}
/* 修改【偶数】行背景和单元格边框颜色 */
.el-table--striped .el-table__body tr.el-table__row--striped td {background: #1f284c;border: 1px solid #114696}
/* 修改表格最底部颜色*/
.el-table::before{background:#1f284c;z-index: 0;}
/* 修改表格内容部分字体颜色 */
.el-table{color: #fff;}
/* 修改表格无数据背景,字体颜色 */
.el-table__empty-block{background: #16203C;}
.el-table__empty-text{color: #ccc}
/* 修改表格鼠标悬浮hover背景色和字体样式 */
.el-table--enable-row-hover .el-table__body tr:hover>td {background-color: #114695;color: red;}
/* 修改表格单元格样式*/
::v-deep .el-table--border {
border: 1px solid blue !important;
}
::v-deep.el-table--border td,
.el-table th, .el-table tr{
border: 1px solid red !important;
border-collapse: collapse;
}
/*设置背景颜色*/
vue+Element-Ui表格(Table)组件中鼠标(hover)悬停、悬浮时样式的修改
element悬停本身的样式:
修改后的效果
颜色可以换成你自己需要的颜色,我写的这个颜色是真的难看,哈哈哈哈
scss中写法(不会影响其他页面中的表格样式)
<style lang="scss" scoped>
//表格鼠标悬停的样式(背景颜色)
/deep/ {
.el-table {
tbody tr {
&:hover {
td {
background-color: #2cce34;
}
}
}
}
}
//表格鼠标悬浮时的样式 (高亮)
/deep/ {
.el-table--enable-row-hover {
.el-table__body tr {
&:hover {
background: rgb(184, 224, 250);
border: 1px solid #313463;
}
}
}
}
</style>
css写法(会影响其他页面中的表格样式),可以用一个div把表格包起来给个class名,然后应该就不会影响其他页面中的表格样式了
<style>
/* 表格鼠标悬浮时的样式(高亮) */
.el-table--enable-row-hover .el-table__body tr:hover {
background: rgb(184, 224, 250);
border: 1px solid #313463;
}
/*表格鼠标悬停的样式(背景颜色)*/
.el-table tbody tr:hover > td {
background-color: #2cce34 !important;
}
</style>
5.clear:both
博客地址:CSS中clear:both的作用_lywyb112的博客-优快云博客_clear:both
clear: both;
6.生成随机字符串
data:{
return{
charStr:''//字符串
}
}
methods:{
//点击左侧
leftClickHandle(item, index) {
this.active = index;
var randomStr = this.getRandomString(30);
console.log('随机字符串',randomStr);
},
//随机生成字符串
RandomStr() {
this.getRandomString(30);
},
/**
* 随机生成字符串
* @param len 指定生成字符串长度
*/
getRandomString(len) {
const charStr = this.charStr;
var _str = '';
//判断是否指定长度,否则默认长度为15
// len = len || 15;
len = Math.floor(Math.random() * len + 1) || Math.floor(Math.random() * 20 + 1);
//循环生成字符串
for (var i = 0, index; i < len; i++) {
index = Math.floor(Math.random() * len);
_str += charStr[index];
}
return _str;
}
}
3.jquery知识点
1.获取属性
分页:
$(".page_a").click(function(){
var pn = $(this).attr("pn");
var href = location.href;
if(href.indexOf("pageNum")!=-1){
//替换pageNum的值
location.href=replaceParamVal(href,pageNum,pn);
}else{
location.href=location.href+"&pageNum="+pn;
}
return false;
})
//替换
function replaceParamVal(url,paramName,replaceVal){
val oUrl=url.toString();
var re=eval('/('+paramName+'=)([^&]*)/gi');
var nUrl=oUrl.replace(re,paramName+'='+replaceVal);
return nUrl;
}
排序:
//排序
$(".sort_a").click(function(
//改变当前元素以及兄弟元素的样式
changeStyle(this);
//排序 sort=skuPrice_asc/desc
var sort = $(this).attr("sort");
sort = $(this).hasClass("desc")?sort+"_desc":sort+"_asc";
replaceAndAddParamVal(location.href,"sort",sort);
return false; //禁用默认行为,比如a标签跳转行为
)};
function changeStyle(ele){
//1、其他未选中状态,兄弟
$("sort_a").css({"color":"#333","border-color":"#CCC","background":"#FFF"}});
$(".sort_a").each(function(){ //去掉兄弟的箭头
var text = $(this).text().replace("↓","").replace("↑","");
$(this).text(text);
})
//2、当前被点击的元素变为选中状态
$(".sort_a").css({"color":"#FFF","border-color":"#e4393c","background":"#e4393c"})
//3、改变升降序,升序:<a class="sort_a">销量</a>
// 降序:<a class="sort_a desc">销量</a>
$(ele).toggleClass("desc");//加上desc表示降序,不加升序
//某个元素是否拥有desc样式
if($(ele).hasClass("desc")){
var text=$(ele).text().replace("↓","").replace("↑","");
text=text+"↓";
$(ele).text(text);//降序
}else{
var text=$(ele).text().replace("↓","").replace("↑","");
text=text+"↑";
$(ele).text(text);//升序
}
}
改造替换方法
//替换和添加
function replaceAndAddParamVal(url,paramName,replaceVal){
val oUrl=url.toString();
//1、如果没有就添加,有就替换
if(oUrl.indexOf(paramName)!=-1){
var re=eval('/('+paramName+'=)([^&]*)/gi');
var nUrl=oUrl.replace(re,paramName+'='+replaceVal);
return nUrl;
}else{
var nUrl="";
if(oUrl.indexOf("?")!=-1){
nUrl = oUrl +"&"+paramName+ '=' + replaceVal;
}else{
nUrl = oUrl +"?"+paramName+ '=' + replaceVal;
}
}
return nUrl;
}
选项框
$("#showHasStock").change(function(){
if($(this).prop("chected")){
//选中状态
location.href = replaceAndAddParamVal(location.href,"hasStock",1);
}else{
//未选中
var re=eval('/(hasStock=)([^&]*)/gi');
location.href=(location.href+"").replace(re,"");
}
return false;
})
[[$strings.equals(param.hasStock,"1")]]
<!--从地址路径的值-->
<a href="#" th:width="chect=${param.hasStock}">
<!--单选框回显-->
<input id="showhasStock" type="checkbox" th:chected="${#strings.equals(chect,'1')}">
仅显示有货
</a>
利用fastjson进行逆转
//利用fastjson进行逆转
public <T> getData(String key,TypeReference<T> typeReference){
Object data = get(key);//默认是map
String s = JSON.toJSONString(data);
T t = JSON.parseObject(s,typeReference);
return t;
}
导航参数取消
private String replaceQueryString(SearchParam param,String value,String key){
String encode =null;
try{
encode = URLEncoder.encode(value,"UTF-8");
//浏览器对空格编码和java不一样,浏览器将空格变为%20,java变为+
encode = encode.replace("+","%20");
}catch(UnsupportedEncodingException e){
e.printStack();
}
return param.get_queryString().replace("&"+key+"="+encode,"");
}
品牌id是否为空,如果空不显示
<!--品牌-->
<div th:width="brandid=${param.barndId}" th:if="${#strings.isEmpty(brandid)}"></div>