1、项目中用到了Echars图表,需要把页面显示的Echars图表,下载下来
- (1) 需要下载第三方包:html2canvas
npm install --save html2canvas
- (2) 在vue页面使用,代码如下
第一步:导入下载的包
// import html2canvas from 'html2canvas'
第二步:开始使用,点击下载按钮,下载Echars图片
// 下载echars图片到本地电脑
// 找到echaers图表对应的dom元素
const echartsIdDom = this.$children[1].$refs.echartsId
// 将echarts图表转换为canvas,并将canvas下载为图片
// 图表转换成canvas
// html2canvas(document.getElementById('download')).then(function(canvas) {
html2canvas(echartsIdDom).then(function(canvas) {
const img = canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream')
// 创建a标签,实现下载
const creatIMg = document.createElement('a')
creatIMg.download = '页面图表.png' // 设置下载的文件名,
creatIMg.href = img // 下载url
document.body.appendChild(creatIMg)
creatIMg.click()
creatIMg.remove() // 下载之后把创建的元素删除
})
2、项目中用到了用到了element ui 中的table组件,发现数据已经更新了,但是页面还是之前的老数据,页面不刷新
(1)用this.forceUpdate() 不管用
(3)最后使用暴力的手段,先把组件删除掉,等新的数据更新后,再把组件重新创建加载出来
data(){
hackReset: false // 关键点在这里
}
<template v-if="hackReset"> // 关键点在这里
<el-table-column v-for="(column, colIdx) in tabData[item.name].indicatorDataList" :key="column.key" :prop="column.id" :label="column.name" sortable align="center" width="173">
<template slot="header">
<span>{{ column.name }}</span>
<span v-show="tableArgFlag" class="argFlag">
<br v-show="column.paramList.length > 0">
<span v-for="i in column.paramList">{{ i.name }}:{{ i.value }}<br></span>
</span>
</template>
<!-- 动态列的值-->
<template v-if="tabData[item.name].valueDataList.length > colIdx" slot-scope="scope">
{{ tabData[item.name].valueDataList[colIdx][scope.$index] }}
</template>
</el-table-column>
</template>
methods: {
myFun(){
this.$api.indexBrowser.BatchqueryIndicatorValueData(paramsData).then((res) => {
if (res.code === '200') {
// 为了解决修改参数按钮中的item位置互换后,表格动态列不刷新的现象,数据修改的时候,删除动态列组件
this.hackReset = false // 关键点在这里
this.$nextTick(() => {
这里处理数据更新成后台返回的数据。。。。。。
this.hackReset = true // 关键点在这里
})
}
}
}
}
3、使用elementui,第一个table在父组件,第二个table在子组件,最终实现2个table表格的横向联动
父组件的table 和 子组件的table 都是第一列固定的情况,不固定应该也可以实现
在父组件中的代码如下:
<template>
<子组件 :tableWrapAllRowsData="tableWrapAllRowsData"></子组件>
</template>
<script>
data() {
return {
tableWrapAllRowsData: 0, // 页面包裹table表格所有行的div,距离屏幕左侧距离
}
},
mounted() {
// 给window添加一个滚动监听事件 ==> 实现页面表格和统计特征表格的联动效果需要的代码
window.addEventListener('scroll', this.handleScroll, true)
},
methods: {
handleScroll() {
// 找到父组件对应的table表格,获取滚动的时候,滚动的距离
this.tableWrapAllRowsData = document.querySelector('.el-table__body').getBoundingClientRect().left
},
}
</script>
在子组件中的代码如下:
props: {
// 页面和统计特征页面的表格联动,传递的是页面table内容数据滚动的距离
tableWrapAllRowsData: {
type: Number,
default: 0
}
},
watch: {
tableWrapAllRowsData: {
deep: true,
immediate: true,
handler(newVal, oldVal) {
// 找到当前子组件对应的table表格
const needMoveDOM = document.querySelectorAll('.el-table__body')
if (needMoveDOM.length >= 3) {
// 父组件table表格滚动的距离 + 统计特征页面tables表格前3列的值+中间的间隙的距离,才是统计特征页面tables表格动态列滚动的距离
needMoveDOM[2].style.left = (Number(newVal) - 498) + 'px' // 为子组件table表格进行赋值操作
needMoveDOM[2].style.position = 'relative' // 为子组件table表格进行赋值
}
}
}
},
mounted(){
/** 子组件初始化的时候,设置子组件不滚动 **/
const needMoveDOM = document.querySelectorAll('.el-table__body')
if (this.tableWrapAllRowsData === 0) {
// 父组件table表格滚动的距离 才是统计特征页面tables表格动态列滚动的距离
needMoveDOM[2].style.left = (Number(this.tableWrapAllRowsData)) + 'px'
needMoveDOM[2].style.position = 'relative'
} else {
// 解决父组件表格滚动一定距离后,关闭统计特征页面,然后在打开统计页面,统计特征页面的动态列,动态列显示位置错位的问题
// 父组件table表格滚动的距离 + 统计特征页面tables表格前3列的值+中间的间隙的距离,才是统计特征页面tables表格动态列滚动的距离
needMoveDOM[2].style.left = (Number(this.tableWrapAllRowsData) - 498) + 'px'
needMoveDOM[2].style.position = 'relative'
}
}
4、git中如何将一个分支的某几个文件合并到另一个分支
例如:我需要把test分支上的2个文件,合并到stage分支上
例如执行命令:
git checkout test --src/views/.../.../a.vue src/views/.../.../b.vue
5、elementUI组件表格排序的重置与清除
<template>
<div id="rank">
<el-button @click="resetTable">重置排序</el-button>
<el-button @click="clearTable">清除排序</el-button>
<el-table
ref="tableList"
:data="tableData"
style="width: 100%"
:default-sort = "{prop: 'date', order: 'descending'}"
>
<el-table-column
prop="date"
label="日期"
sortable
width="180">
</el-table-column>
<el-table-column
prop="age"
label="年龄"
sortable
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址"
:formatter="formatter">
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: 'rank',
data(){
return {
tableData: [{
date: '2016-05-02',
age: '11',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
age: '12',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
age: '13',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
age: '14',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
},
methods:{
formatter(row, column) {
return row.address;
},
resetTable(){
this.$refs.tableList.sort('date','descending')
},
clearTable(){
this.$refs.tableList.clearSort()
}
}
}
</script>
官方文档方法
6、elementUI中,表格数据需要用for循环出来,方便加减节点的方法(动态表格)
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column
:prop="item.porp"
:label="item.label"
width="180"
v-for="item in data"
:key="item.key"></el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
// 表格表头的值,其中porp是和下面表格列的值中对象的key一一对应的
data: [
{ label: "编码1日期", porp: "date"},
{ label: "编码2名字", porp: "name"},
{ label: "编码3住址", porp: "address"},
],
// 表格列的值
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
}
}
</script>
<style lang="scss" scoped>
</style>
7、Echars中堆叠柱状图,鼠标划过默认显示全部,实现只显示鼠标位置的柱状图信息
// 在option选项中加入下面的代码即可,老板本的Echars这么调整
option = {
tooltip:{
trigger: 'item'
},
}
8、elementUI中,点击按钮,实现tree控件上移和下移
<template>
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick" ref="tree"></el-tree>
<el-button type="primary" @click="moveUp">上移</el-button>
<el-button type="primary" @click="moveDown">下移</el-button>
</template>
<script>
export default {
data() {
return {
data: [
{ label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1' }]
}]
},
{ label: '一级 2',
children: [{
label: '二级 2-1',
children: [{
label: '三级 2-1-1'
}]
},
{ label: '二级 2-2',
children: [{
label: '三级 2-2-1'
}]
}]
},
{ label: '一级 3',
children: [{
label: '二级 3-1',
children: [{ label: '三级 3-1-1' }]
},
{ label: '二级 3-2',
children: [{ label: '三级 3-2-1' }]
}]
}
],
defaultProps: {
children: 'children',
label: 'label' }
};
},
methods: {
handleNodeClick(data) {
console.log(data);
},
//节点上移
moveUp: function () {
let node = this.$refs.tree.getCurrentNode();
console.log(node.id);
if (!node) {
this.$message({
message: '请先点击选择节点',
type: 'warning'
})
return
}
// 获取当前点击的节点的父节点中,所有的子节点
let pchildNodes = this.$refs.tree.getNode(node.assetId).parent.childNodes
let currentId = -1
// 获取当前点击的节点在父节点的位置,即索引
for (let i = 0; i < pchildNodes.length; i++) {
if (pchildNodes[i].data.assetId == node.assetId) {
currentId = i
}
}
// 当前点击的节点是第一个
if(currentId == 0){
this.$message({
message: '处于顶端,不能继续上移',
type: 'warning'
})
return
}
let upid = currentId - 1 // 当前节点需要向上移动的位置,即索引
pchildNodes.spliece(upid, 0, pchildNodes[currentId])
// 对当前点击的节点,他的父节点中包含的所有子节点,进行位置的互换
pchildNodes.spliece(currentId + 1, 1)
},
//节点下移
moveUp: function () {
let node = this.$refs.tree.getCurrentNode();
console.log(node.id);
if (!node) {
this.$message({
message: '请先点击选择节点',
type: 'warning'
})
return
}
let pchildNodesLength = this.$refs.tree.getNode(node.assetId).parent.childNodes.length - 1
if (node.level === 1 && node.orderNo === pchildNodesLength) {
this.$message({
message: '禁止向下移动最后一个根节点',
type: 'warning'
})
} else {
// 获取当前点击的节点的父节点中,所有的子节点
let pchildNodes = this.$refs.tree.getNode(node.assetId).parent.childNodes
let currentId = -1
// 获取当前点击的节点在父节点的位置,即索引
for (let i = 0; i < pchildNodes.length; i++) {
if (pchildNodes[i].data.assetId == node.assetId) {
currentId = i
}
}
// 当前点击的节点是最后一个
if(currentId == pchildNodesLength){
this.$message({
message: '处于底端,不能继续下移',
type: 'warning'
})
return
}
let upid = currentId + 2 // 当前节点需要向下移动的位置,即索引
pchildNodes.spliece(upid, 0, pchildNodes[currentId])
// 对当前点击的节点,他的父节点中包含的所有子节点,进行位置的互换
pchildNodes.spliece(currentId, 1)
}
},
}
</script>
9、elementUI中, 为Table动态列动态设置宽度
element UI中的table设置列的宽度是width属性,如下:
<el-table-column prop="date" label="日期" width="180"> </el-table-column>
但是我的列是动态的,不能直接这样设置
解决办法如下图所示:
10、elementUI中, 为Table表格无数据的时候,显示一张图片的办法
<template>
<el-table
:data="tableData"
style="width: 100%">
<!-- 主要代码在这里,写在table里面,第一个el-table-column的上面 ==> 开始 -->
<template>
<div style="height: 300px; padding-top: 50px;">
<img src="../../../assets/images/nodata.png" alt="暂无数据">
<span>暂无数据</span>
</div>
</template>
<!-- 主要代码在这里 ==> 结束 -->
<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>
</template>
<script>
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
}
</script>
11、Vue3.0 setup 里使用 vuex,需要用到component才行
import { useStore } from '@store' // 默认去找store文件夹下的index.js文件
import { getCurrentInstance, computed } from "vue"
setup () {
const store = useStore() // 获取store 实例
// const { ctx } = getCurrentInstance() // 获取当前组件实例,
// console.log(ctx.$router.currentRoute.value)
// 使用state和getter,需要computed来保持响应性
const count = computed( () => store.state.count) // 获取到vuex中的值,给组件使用
return {
count // 组件中 count 会随着其他的地方的 count 变化而自动相应变化
}
}
12、Elementui中,Pagination 分页 实现左右各一半的布局,默认都是在左侧
13、elementUI中, Table表格显示的是树形数据,实现第一层级显示索引号
<tempalte>
<!-- 表格中索引的列 -->
<el-table-column prop="oneIndex" label="序号" width="50" align="center"> </el-table-column>
</template>
watch:{
// 监视表格数据的变化,为第一层级添加左侧的展示索引,data是父组件传递过来的表格数据
data(newVal){
for (i=0; i< newVal.length; i++) {
// 数据在第一次层级展示
if (newVal[i]._level === 1) {
// 为第一次层级添加一个属性:oneIndex,用来显示索引
newVal[i].oneIndex = i + 1
}
}
}
}
<style lang="scss">
// .first__column__center__only是在table上新增的属性,防止全局污染,实现序列号这一列,表头和列都居中显示
.first__column__center__only{
.el-table__fixed {
.el-table__fixed-header-wrapper {
table {
thead {
tr:first-child th:first-child {
padding-left: 0px;
}
}
}
}
.el-table__fixed-body-wrapper {
table {
tbody {
tr {
td:first-child {
padding-left: 0px;
}
}
}
}
}
}
}
</style>
14、动态实现elementUI中的el-table某列数据不同样式(比如颜色动态展示)
<template>
<div id="app">
<!-- 需求:三国人物表格,要求不同的国别展示不同的颜色(魏国红色、蜀国黑色、吴国蓝色) -->
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="name" label="姓名" width="180"> </el-table-column>
<el-table-column prop="nation" label="国别" width="180">
<!-- 思路通过模板插槽,获取对应的数据,通过vue动态style的方法,动态显示不同的颜色,这种方式更加灵活 -->
<template scope="scope">
<!-- 意思是:给这个div绑定动态样式,
颜色color的属性值为getColorByNation()这个方法的返回值,
所以只需要通过传过去的scope 对方法的返回值做动态设置即可
关键点就在这里-->
<div :style="{color:getColorByNation(scope),fontSize:getSizeByNation(scope),fontWeight:'bold'}">{{scope.row.nation}}</div>
</template>
</el-table-column>
<el-table-column prop="bornPlace" label="出生地方"> </el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: "app",
data() {
return {
tableData: [
{
name: "刘备",
nation: "蜀国",
bornPlace: "涿郡涿县(河北省涿州市)",
},
{
name: "曹操",
nation: "魏国",
bornPlace: "沛国谯县(安徽省亳州市)",
},
{
name: "孙权",
nation: "吴国",
bornPlace: "吴郡富春县(浙江省杭州市富阳区)",
},
{
name: "关羽",
nation: "蜀国",
bornPlace: "河东郡解县(山西省运城市盐湖区解州镇)",
},
],
};
},
methods: {
// 关键点就在这里 ==》 动态设置颜色
getColorByNation(scope){
console.log(scope); // 打印一下传过来的scope是对应表格不同行的整行的数据,如下有图片:
if(scope.row.nation == "魏国"){
return "red"
}else if(scope.row.nation == "蜀国"){
return "black"
}else if(scope.row.nation == "吴国"){
return "blue"
}
},
// 关键点就在这里 ==》 动态设置字体大小
getSizeByNation(scope){
if(scope.row.nation == "魏国"){
return "14px"
}else if(scope.row.nation == "蜀国"){
return "18px"
}else if(scope.row.nation == "吴国"){
return "24px"
}
}
},
};
</script>
15、ElementUI -- 表单嵌套表格,v-for生成的表单项实现表单验证
参考一:ElementUI -- 表单嵌套表格,v-for生成的表单项实现表单验证。
参考二:elementui中的form表单中嵌套表格,表格中又校验input框
参考三:Vue中对From表单中的Table表格中的输入项进行验证
1、截图实现的效果是 第一个表单里面 又套了 第二个表单,在第二个表单中套入了表格
2、在最外面写了一个clss样式累,为了防止全局污染而写的
3、实现表单中嵌套表格的时候,为了显示验证,保证表格的美观,修改的css代码如下:
<style lang="scss">
secondFormAndTable {
.el-form-item__content {
display: flex !important;
width: 100% !important;
// 主要代码在这里 开始
.el-table__header tr, el-table__header th {
padding: 0;
height: 35px;
line-height: 35px;
}
.el-table__body tr, el-table__body td {
padding: 20px 0 3px 0;
height: 40px;
line-height: 40px;
}
// 主要代码在这里 结束
}
}
</style>
16、element UI tabel表格改变边框颜色
1.改变最外层边框
style中不能有scoped 为了防止全局污染,可以用一个父css样式包裹住
.el-table td, .el-table th.is-leaf,.el-table--border, .el-table--group{
border-color: black;
}
.el-table--border::after, .el-table--group::after, .el-table::before{
background-color: black;
}
2.添加属性:cell-style=“cellStyle” 改变表格里面的边框颜色
3.添加属性:header-cell-style="{color:‘black’,borderColor:‘black’}",改变表头的边框颜色
<el-table :cell-style="cellStyle" :header-cell-style="{ color: 'black', borderColor: 'black' }" height="200" :data="tableData" style="width: 100%" border >
<el-table-column prop="date" label="序号" width="180" align="center">
</el-table-column>
<el-table-column prop="name" label="参数名称" width="180" align="center">
</el-table-column>
</el-table>
methods: {
cellStyle({ row, column, rowIndex, columnIndex }) {
return "height:35px!important; border-color:black!important; color:#000000!important; padding:0px!important; height:40px!important";
},
}
17、element UI tabel表格中表格列是动态的,设置动态表格列的宽度
例子是带有2级表头的,1级表头的也是可以一样的操作
html代码:
js代码:
18、js 递归实现过滤数组
过滤要求:让数组元素中isShow为false的过滤掉,如果第一级的isShow为false,就直接不递归了
- 数据如下
let a = [{
id: 1,
isShow: false,
child: [{
id: 2,
isShow: true
}]
},
{
id: 3,
isShow: true,
child: [{
id: 4,
isShow: true
}, {
id: 5,
isShow: false
}]
}
]
- 解决方法如下:
const detailChild = (child) => {
if (!child) return []
return child.filter((item) => {
if (item.isShow) {
item.child = detailChild(item.child)
}
return item.isShow
})
}
let b = a.filter((item) => {
if (item.isShow && item.child && item.child.length) {
item.child = detailChild(item.child)
}
return item.isShow
})
console.log(b)
19、element UI中 DatePicker 日期选择器,只有T-1的日期可以点击,T和T++后的日期禁止点击
T是今天的当前时间
<el-date-picker
v-model="value1"
type="date"
placeholder="选择日期"
:picker-options="limitData">
</el-date-picker>
<script>
export default {
data() {
return {
value1: '',
limitData: {
disabledDate (time) {
return time.getTime() > Date.now() - 3600 * 1000 * 24
}
},
}
}
} </script>
20、element UI中 DatePicker 日期选择器,需要选择一个时间范围【设置选择的开始时间不能大于结束时间,同时2个时间中只有T-1的日期可以点击,T和T++后的日期禁止点击
T是今天的当前时间
- 代码如下:
<el-form-item>
<el-date-picker
v-model="startTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="开始日期"
:picker-options="pickerOptionsStart"
clearable
></el-date-picker>
</el-form-item>
<el-form-item>
<el-date-picker
v-model="endTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="结束日期"
:picker-options="pickerOptionsEnd"
clearable
></el-date-picker>
</el-form-item>
data() {
return {
startTime: '', // 时间段开始时间
endTime: '', // 时间段结束时间
pickerOptionsStart: {
/** 禁止选择 */
disabledDate: time => {
let endDateVal = this.endTime;
if (endDateVal) {
return time.getTime() > new Date(endDateVal).getTime()
} else {
return time.getTime() > Date.now() - 3600 * 1000 * 24
}
}
},
pickerOptionsEnd: {
/** 禁止选择 */
disabledDate: time => {
let beginDateVal = this.startTime;
if (beginDateVal) {
return time.getTime() < new Date(beginDateVal).getTime() || time.getTime() > Date.now() - 3600 * 1000 * 24
} else {
return time.getTime() > Date.now() - 3600 * 1000 * 24
}
}
},
},
}
- 页面效果如下:
21、element UI中 Table表格组件中表格显示索引,同时索引随着分页一起变动,例如:表格每页显示10条,点击了第二页,表格索引显示为11-20,这是只有一个层级的实现方法
currentPage是点击点击的页数, pageSize是每页显示多少条数据
22、element UI中 Table表格组件中,前端自己实现排序的时候,只支持number类型的数值来进行排序,对于字符串的排序会出现表格数据排序后,错乱的问题,所以后台只需要把带有%的数据,直接返回为number类型的,由前端自己进行添加%的操作
23、后台接口返回Blob类型数据,如何转换Json数据类型,拿到里面的url,然后单独打开一个浏览器页面
// 定义JSON数据
let data = { "name": "小明" };
// 转换成字符串数组
let string = JSON.stringify(data);
// 转换成Blob类型数据
let blobData = new Blob([string]);
console.log(blobData) // 打印Blob结果: Blob { size: 17, type: "" }
// 将blob类型的数据转变成 json数据类型
let reader = new FileReader(); // 创建读取文件对象
reader.readAsText(blobData, 'utf-8'); // 设置读取的数据以及返回的数据类型为utf-8
reader.addEventListener("loadend", function () { //
let res = JSON.parse(reader.result); // 返回的数据
console.log(res,'返回结果数据') // { name: "小明" }
// 如果返回的是url,单独打开一个浏览器页面
// window.open(url)
});
24、使用elementui中的【Collapse 折叠面板】,可以让其在页面拖着跑,用自定义指令实现
html页面
vue自定义指令
25、在vue项目中使用svg图标
svg图标可以随字体一样变色、大小可更改且不失真;应用在项目中不仅可以摆脱img图片占用内存大的问题,还可以减少代码量,优化系统。
使用字体图标的步骤如下:
- 安装
svg-sprite-loader插件
npm install svg-sprite-loader
- 自定义
svg-icon组件
在componets文件夹下建立一个svgIcon组件,内容如下:
<template>
<svg :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName" />
</svg>
</template>
<script>
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true,
},
className: {
type: String,
default: '',
},
},
computed: {
// 图标名称
iconName() {
return `#icon-${this.iconClass}`;
},
// 样式类名
svgClass() {
if (this.className) {
return `svg-icon ${this.className}`;
}
return 'svg-icon';
},
},
data() {
return {
};
},
};
</script>
<style scoped>
.svg-icon{
width: 1em;
height: 1em;
fill: currentColor; /* 图标填充颜色,currentColor是一个变量,表示当前元素的color值,如当前无指定,则从父元素继承 */
overflow: hidden;
}
</style>
3、在src目录下新建文件夹icons放置svg图标文件,并在index.js中注册svgIcon为全局组件
建目录如下:svg图标及index.js
index.js文件代码
// 引入vue
import Vue from 'vue';
// 引入svgIcon组件
import SvgIcon from '@/components/SvgIcon.vue';
// 注册为全局组件
Vue.component('svg-icon', SvgIcon);
// 引入当前svg目录下的文件、不遍历子目录、匹配以'.svg'为结尾的文件
const req = require.context('./svg', false, /\.svg$/);
// 相当于 req.keys().forEach(key => req(key)), req.keys()是匹配到的svg文件的路径数组
const requireAll = (requireContext) => requireContext.keys().map(requireContext);
// 得到一个完整解析的module数组
requireAll(req);
这个打印req和req.keys()的结果
- 配置
vue.config.js
const path = require('path');
// 在vue.config.js中没有配置 resolve 方法, 需要自定义一个
function resolve(dir) {
return path.join(__dirname, dir);
}
module.exports = {
chainWebpack: (config) => {
// set svg-sprite-loader
config.module.rules.delete('svg'); // 重点:删除默认配置中处理svg
config.module
.rule('svg-sprite-loader')
.test(/\.svg$/)
.include
.add(resolve('src/icons')) // 处理svg目录
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]',
});
},
};
- 在页面中使用svg图标
<svg-icon :iconClass="'alarm'"></svg-icon>
26、ElementUI -表单嵌套表格,实现表单和表格都能验证,第15项也有相同功能
<template>
<div>
<el-form :model="forms" ref="forms" :rules="rules">
<el-table :data="forms.voList">
<el-table-column
label="商品名称">
<template slot-scope="scope">
<el-form-item :prop="'voList.'+scope.$index+'.goodsName'">
<el-input v-model="scope.row.goodsName"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column
label="商品编码">
<template slot-scope="scope">
<el-form-item :prop="'voList.'+scope.$index+'.goodsCode'">
<el-input v-model="scope.row.goodsCode"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column
label="价格">
<template slot-scope="scope">
<el-form-item :prop="'voList.'+scope.$index+'.unitPrice'" :rules="rules.unitPrice">
<el-input v-model="scope.row.unitPrice"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column
label="数量">
<template slot-scope="scope">
<el-form-item :prop="'voList.'+scope.$index+'.num'" :rules="rules.unitPrice">
<el-input v-model="scope.row.num"></el-input>
</el-form-item>
</template>
</el-table-column>
</el-table>
</el-form>
<el-button type="primary" @click="save">批量开票</el-button>
</div>
</template>
<script>
export default {
name: "table",
data(){
return {
// 表单数据
forms:{
id:1,
documentNo:null,
buyerName:"服务技术",
buyerDp:"42118XXXXXXXXXX72X",
buyerBankAccount:"招商银行4890284",
buyerAddressPhone:"深圳市宝安区110112",
buyerEmail:null,
buyerPhone:null,
buyerType:"01",
remarks:"这是备注",
total:350.9,
// 表单里面要有表格数据才行
voList:[
{
goodsName:"黄金",
goodsCode:"44021940",
specification:null,
unit:"克",
num:1,
unitPrice:291.37,
taxRate:0.17,
taxAmount:49.53,
favouredPolicy:"0",
zeroTaxRate:"",
hsbz:"1"
},
{
goodsName:"花生",
goodsCode:"4574511",
specification:null,
unit:"斤",
num:1,
unitPrice:8.55,
taxRate:0.17,
taxAmount:1.45,
favouredPolicy:"0",
zeroTaxRate:"",
hsbz:"1"
}
]
},
// 表单验证,验证的是表单里面表格的数据
rules:{
num:[{required:true,message:'数量不能为空',trigger:'blur'}],
unitPrice:[{required:true,message:'单价不能为空',trigger:'blur'}]
}
}
},
methods:{
save(){
this.$refs['forms'].validate((valid)=>{
if(valid){
console.log(1)
}
})
}
}
}
</script>
<style scoped lang="scss">
</style>
27、vue中后端返回文件流,前端全部下载或者部分下载
28、elementUI 表格刷新后保持行高亮显示
29、vue+element ui实现表格拖拽功能
30、vue中实现下载,前端调用接口,后端返回的是流,前端处理办法
接口的写法:
// 前提是调用接口后,接口返回的数据格式是2进制流,前端把流处理成文件,进行下载
// res是接口返回的数据
// let blob = new Blob([res.data], {type: ''})
let blob = new Blob([res.data])
// 或者指定下载的文件类型,例如:excel文件
//let blob = new Blob([res.data],{
// type: 'application/vnd.ms-excel'
//})
// 判断方式一: 先判断非IE下载
if('download' in document.createElement('a')){
// 动态加载a标签,实现下载
let aDom = document.createElement('a')
let href = window.URL.createObjectURL(blob) // 下载链接
aDom.href = href
aDom.download = XXXX // XXXX是下载的文件名字
document.body.appendChild(aDom)
aDom.click() // 强制触发a标签的点击事件
document.body.removeChild(aDom) // 移除a标签
window.URL.revokeObjectURL(href)// 释放blob对象
} else {
// IE下载
navigator.msSaveBlob(blob, XXXX) // XXXX是下载的文件名字
}
// 判断方式二: 先判断IE下载
if(window.navigator.msSaveOrOpenBlob){
// IE下载
navigator.msSaveBlob(blob, XXXX) // XXXX是下载的文件名字
} else{
// 动态加载a标签,实现下载
let aDom = document.createElement('a')
let href = window.URL.createObjectURL(blob) // 下载链接
aDom.href = href
aDom.download = XXXX // XXXX是下载的文件名字
document.body.appendChild(aDom)
aDom.click() // 强制触发a标签的点击事件
document.body.removeChild(aDom) // 移除a标签
window.URL.revokeObjectURL(href)// 释放blob对象
}
31、element中table表格跨分页多选及回显的实现
<template>
<div>
<!-- 表格 -->
<el-table @selection-change="handleSelectionChange" :row-key="getRowKeys">
<el-table-column type="selection" width="50" align="center" :reserve-selection="true">
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination>...</el-pagination>
</div>
</template>
<script>
export default {
data() {
return {
multipleSelection: [], // 表格选中
getRowKeys(row) {//记录每行的key值
return row.id;
},
select_number: -1, //表格select选中的数据的总条数
select_Id: [], //表格select复选框选中的id
}
},
methods: {
handleSelectionChange(rows) {
this.multipleSelection = rows;
this.select_number = this.multipleSelection.length;
this.select_Id = [];
if (rows) {
rows.forEach((row) => {
if (row) {
this.select_Id.push(row.id);
}
});
}
},
}
}
32、element中form表单中嵌套table表格,同时table表格是动态的
33、element中修改日期选择框的样式
日期组件中必须有 popper-class="date_style"这个属性
这个属性可以用来包裹改变日期下拉框的样式,防止样式污染
日期组件中输入框样式的调整,.all_echars_date_picker 是包裹日期组件的div的类名,上图有标明
日期组件中下拉库框样式的调
单独写一个style样式,因为日期组件中下拉库,默认挂在了body下面
最终效果如下
34、css 边框添加四个角效果
html部分
<div class="loginbody">
<div class="border_corner border_corner_left_top"></div>
<div class="border_corner border_corner_right_top"></div>
<div class="border_corner border_corner_left_bottom"></div>
<div class="border_corner border_corner_right_bottom"></div>
<--other……………………-->
</div>
css部分
.loginbody{
border: 1px solid #21a7e1;
box-shadow: 5px 5px 10px 10px rgba(24,68,124,0.4);
padding-top:20px;
border-radius: 6px;
position: relative;
}
/*四个角框*/
.border_corner{
z-index: 2500;
position: absolute;
width: 19px;
height: 19px;
background: rgba(0,0,0,0);
border: 4px solid #1fa5f1;
}
.border_corner_left_top{
top: -2px;
left: -2px;
border-right: none;
border-bottom: none;
border-top-left-radius: 6px;
}
.border_corner_right_top{
top: -2px;
right: -2px;
border-left: none;
border-bottom: none;
border-top-right-radius: 6px;
}
.border_corner_left_bottom{
bottom: -2px;
left: -2px;
border-right: none;
border-top: none;
border-bottom-left-radius: 6px;
}
.border_corner_right_bottom{
bottom: -2px;
right: -2px;
border-left: none;
border-top: none;
border-bottom-right-radius: 6px;
}
最终效果
35、vue2中实现禁止浏览器的前进后退按钮点击跳转页面
- vue2中main.js的入口文件中:
- vue2中路由中的index.js文件中:(或者路由的全局前置守卫borferEach钩子中设置也可以)
36、vue2中实现element ui table scrollTop 滚动到行头或行尾
滚动到第一行:
this.$refs.table.bodyWrapper.scrollTop =0
滚动到最后一行:
this.$refs.table.bodyWrapper.scrollTop =this.$refs.table.bodyWrapper.scrollHeight
32、vue2中实现elementUI Table 合并第一列相同的数据
// template部分
<el-table :data="indexShardLocation"
border
:span-method="objectSpanMethod"
style="width: 100%">
<el-table-column
prop="index_name"
label="索引名"
width="240">
</el-table-column>
</el-table>
// mothod部分
flitterData (arr) {
let spanOneArr = []
let concatOne = 0
arr.forEach((item, index) => {
if (index === 0) {
spanOneArr.push(1);
} else {
// 第一列中 name同名,就是要进行合并
if (item.name === arr[index - 1].name) { //第一列需合并相同内容的判断条件
spanOneArr[concatOne] += 1;
spanOneArr.push(0);
} else {
spanOneArr.push(1);
concatOne = index;
};
}
});
return {
one: spanOneArr,
}
},
// 合并表格列的方法
objectSpanMethod ({ row, column, rowIndex, columnIndex }) {
// 第一列合并
if (columnIndex === 0) {
// this.tableData 修改
const _row = (this.flitterData(this.indexShardLocation).one)[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col
};
}
},