theme: nico
highlight: atelier-cave-light
el-checkbox
//三种情况
this.menulist.forEach((item) => {
//已经选择的项包括某一整行
if (
item.child.every((item) => {
return this.checkedCities.includes(item.id + '')
})
) {
item.checkAll = true
item.isIndeterminate = false
}
//已经选择的项不包括某一整行的任何一项
else if (
item.child.every((item) => {
return !this.checkedCities.includes(item.id + '')
})
) {
item.checkAll = false
item.isIndeterminate = false
}
//有一个以上都不是全包括
else {
item.checkAll = false
item.isIndeterminate = true
}
})
}
//Longhand
if (isLoggedin) {
goToHomepage();
}
//Shorthand
isLoggedin && goToHomepage();
set delete
this.$set(this.ruleForm, 'menuId', mm)
this.$delete(this.ruleForm, 'id')
el-table多选批量删除
handleSelectionChange1(val) {
this.multipleSelection=[]
val.forEach(item => {
this.multipleSelection.push(item.id)
})
},
数组去重
//去重
const handleRemoveRepeat = (arr) => arr.filter((item,index) => arr.indexOf(item,0) === index);
拼接两个对象
var target = {a : 1}; //目标对象
var source1 = {b : 2}; //源对象1
var source2 = {c : 3}; //源对象2
var source3 = {c : 4}; //源对象3,和source2中的对象有同名属性c
Object.assign(target,source1,source2,source3); //结果如下: //{a:1,b:2,c:4}
拼接两个数组
var c = a.concat(b);//并不会改变原数组,需要接收
其他方法
1: a=[...a,...b]
2: var a = [1, 2, 3, 4, 5]
var b = [6, 7, 8, 9]
a.splice(5, 0, ...b)//splice会改变原数组,
//splice中第一个数为插入的位置,第二个为要删除的项数,这里是插入所以是0,返回删除的元素数组。插入的位置为数组下标,会将原来在这个下标的元素向后挤一位。
//不能直接传数组,否则会在原数组里直接嵌套一个数组
对象外加一个数组符号[ ]
var a={name:'hhh',gender:'1'} =>[{name:'hhh',gender:'1'}]
a=[a]
//其实很简单吧,只是自己想复杂了(o(╥﹏╥)o)
数组方法findindex
this.index = this.membertableData.findIndex((item) => item == this.multipleSelection[0])
返回符合条件的数组下标
过滤所以符合条件的数组元素,
一个数组内删除和另一个数组相同的全部元素,filter不会改变原数组,filter里面返回为true的保留,some一直在找符合条件的值,一旦找到,返回true,不会继续迭代下去。
every从迭代开始,一旦有一个不符合条件,返回false,不会继续迭代下去。
this.readyright = this.readyright.filter(
(x) => !this.checkedright.some((item) => x === item)
)
判断一个数组是否是另一个元素子集
a.every((item) => {
return this.checkedCities.includes(item)
})//a是子集,返回false,true,1与'1'includes返回false
判断一个数组是否有一项与另一个数组相同
a.forEach((item) => {
if (this.checkedCities.includes(item)) {
this.$set(this.menulist[index], 'isIndeterminate', true)
}
})
forEach,split
a.forEach(item => {
item.name=item.name.split('')
})//空字符串使用split会生成一个长度为一的数组
箭头函数this指向
在函数外定义const that=this
that.声名的变量名=item.id
js给数组内的每一个对象添加一个属性
let arr = [
{
a:1,b:2},
{
a:3,b:4},
{
a:5,b:6},
{
a:7,b:8},
];
let newarr = [];
arr.map((item,index)=>{
newarr.push(Object.assign(item,{
c:9}))
})
arr = newarr;
console.log(arr)
# 后端返回数据中数字太大导致精度丢失问题解决方案
axios.defaults.transformResponse= [function (data) {
// Do whatever you want to transform the data
return JSONbig.parse(data)
}]
tips
vscode在指定部分内替换字段名
x号左边那个键,全部替换:最后一行最后一个
重置,预校验表单
@click="resetForm('addrolebottomruleForm','addroletopruleForm')"
resetForm(a, b) {
this.$refs[a].resetFields()
this.$refs[b].resetFields()
},
submitForm(formName)
{ this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); },
//要使用element ui 表单重置功能,form-item上一定要绑prop,
//与绑定数据字段名相同。
created里函数也有先后关系
修改css属性值在data内修改css属性值
:style="{color:activecolor,'background-color':bgc}"
data内定义activecolor,bgc
全屏
handleFullScreen() {
let element = document.documentElement
if (this.fullscreen) {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
}
} else {
if (element.requestFullscreen) {
element.requestFullscreen()
} else if (element.webkitRequestFullScreen) {
element.webkitRequestFullScreen()
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen()
} else if (element.msRequestFullscreen) {
// IE11
element.msRequestFullscreen()
}
}
this.fullscreen = !this.fullscreen
},
BUG(真的很喜欢bug,o(╥﹏╥)o)
Vue中Data数据相互赋值实时同步的问题
两个毫无关系的数据改一个其它一个也会被改。只取【[字符串]值】,而不取【地址】,这样就不会实时同步变化了。
this.mAges =JSON.parse(JSON.stringify(this.ages));//深拷贝
//如果数据同时变化,一定要把右边的数据深拷贝给左边
数据能用console打印出来,但在页面上无法渲染。
this.membertableData[this.index]=JSON.parse(JSON.stringify(this.addroletopruleForm));
因为Vue不能监听到数组下标变化,尽量不要给变量赋值,而是修改它,例如使用splice
this.$set(this.membertableData,this.index,JSON.parse(JSON.stringify(this.addroletopruleForm)))
//第一个参数是目标参数,第二个数据是需要修改的数组下标,第三个是用来替换的数据
this.membertableData.splice(this.index,1,JSON.parse(JSON.stringify(this.addroletopruleForm)))
element-ui 使用日期选择器时报错Avoid mutating a prop directly since the value will be overwritten whenever the
不要用2.15.9版本element ui
Error: error:0308010C:digital envelope routines::unsupported
上面提示node版本17,但是我的node是16的
在package.json修改
"scripts": {
"dev": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
"serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
"lint": "eslint --ext .js,.vue src",
"build:prod": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview",
"new": "plop",
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
"test:unit": "jest --clearCache && vue-cli-service test:unit",
"test:ci": "npm run lint && npm run test:unit"
}
data里定义了数据但控制台还是提示未定义
eightcato: [
{
name: 脱贫户, status: true },
{
name: 低收入农户, status: false },
{
name: '分散供养特困人员', status: false },
{
name: '农村低保对象', status: false },
{
name: '农村残疾家庭', status: false },
{
name: '多子女家庭', status: false },
{
name: '收入不稳定家庭', status: false },
{
name: '严重困难家庭', status: false },
],//忘了加引号了
v-for循环
<div v-for="o in this.eightcato"
:key="o.name"
:class="o.status?'addtopright tabs-view-item-active':'addtopright'"
@click="selecttype(o)">{
{
o.name }}//传入的o是用来循环的,不能随便取名字
</div>
小组件
穿梭框
//数据项
checkedleft: [],
checkedright: [],
itemsRight: ['在校生状况', '人员识别时间'],
itemsLeft: [
'易返贫致贫户',
'风险是否消除',
'风险识别时间',
'风险消除时间',
'联系电话',
'首次识别时间',
'户类型',
'人均纯收入',
'是否参加大病保险',
'贫致贫户',
'险否消除',
'风险别时间',
'风险消时间',
'联系电',
'首次别时间',
],
readyleft: [],
readyright: [],
left() {
this.readyright = this.readyright.filter(
(x) => !this.checkedright.some((item) => x === item)
)
this.readyleft = this.readyleft.concat(this.checkedright)
this.checkedright = []
},
right() {
this.readyleft = this.readyleft.filter(
(x) => !this.checkedleft.some((item) => x === item)
)
this.readyright = this.readyright.concat(this.checkedleft)
this.checkedleft = []
},
//全选
handleCheckAllChangeleft() {
if (this.allleft) this.checkedleft = this.readyleft
else this.checkedleft = []
},
handleCheckAllChangeright() {
if (this.allright) this.checkedright = this.readyright
else this.checkedright = []
},
//置顶/置底 找到这一项删除,在头或尾插入。
top() {
let a = this.checkedright
if (this.checkedright.length == 0) {
this.$message.error('未选择数据项')
return
}
if (this.checkedright.length !== 1) {
this.$message.error('每次只能移动一项')
return
}
if (a == this.readyright[0]) {
this.$message.error('已置顶')
return
}
this.readyright = this.readyright.filter(
(x) => !this.checkedright.some((item) => x === item)
)
this.readyright = a.concat(this.readyright)
},
bottom() {
let a = this.checkedright
if (this.checkedright.length == 0) {
this.$message.error('未选择数据项')
return
}
if (this.checkedright.length !== 1) {
this.$message.error('每次只能移动一项')
return
}
if (a == this.readyright[this.readyright.length - 1]) {
this.$message.error('已置底')
return
}
this.readyright = this.readyright.filter(
(x) => !this.checkedright.some((item) => x === item)
)
this.readyright = this.readyright.concat(a)
},
//上移/下移
up() {
let a = this.checkedright
if (this.checkedright.length == 0) {
this.$message.error('未选择数据项')
return
}
if (this.checkedright.length !== 1) {
this.$message.error('每次只能移动一项')
return
}
if (a == this.readyright[0]) {
this.$message.error('已经是第一项')
return
}
let i= this.readyright.findIndex(
(item) => item == this.checkedright[0]
)
this.readyright = this.readyright.filter(
(x) => !this.checkedright.some((item) => x === item)
)
this.readyright.splice( i- 1, 0, this.checkedright[0])
},
down() {
let a = this.checkedright
if (this.checkedright.length == 0) {
this.$message.error('未选择数据项')
return
}
if (this.checkedright.length !== 1) {
this.$message.error('每次只能移动一项')
return
}
if (a == this.readyright[this.readyright.length - 1]) {
this.$message.error('已经是最后一项')
return
}
let i = this.readyright.findIndex(
(item) => item == this.checkedright[0]
)
this.readyright = this.readyright.filter(
(x) => !this.checkedright.some((item) => x === item)
)
this.readyright.splice(i + 1, 0, this.checkedright[0])
},
//删除 o是传递参数
deleteleft(o) {
this.readyleft = this.readyleft.filter((x) => x !== o)
},
deleteright(o) {
this.readyright = this.readyright.filter((x) => x !== o)
},
标签
<!-- 历史标签栏 -->
HTML:
<div class="tabs-view-container">
<div class="tabs-wrapper">
<span
:class="isActive(item)"
v-for="item of this.$store.state.tabList"
:key="item.path"
@click="goTo(item)"
>
{
{
item.name }}
<i
class="el-icon-close"
v-if="item.path != '/homepage'"//首页不能删除
@click.stop="removeTab(item)"
/>
</span>
</div>
<div
class="tabs-close-item"
style="float: right"
@click="closeAllTab"
>
全部关闭
</div>
</div>
Css:
.tabs-view-container {
display: flex;
position: relative;
padding-left: 10px;
padding-right: 10px;
height: 33px;
background: #fff;
border-bottom: 1px solid #d8dce5;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
.tabs-wrapper {
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
width: 95%;
.tabs-close-item {
position: absolute;
right: 10px;
display: inline-block;
cursor: pointer;
height: 25px;
line-height: 25px;
border: 1px solid #d8dce5;
color: #495060;
background: #fff;
padding: 0 8px;
font-size: 12px;
margin-top: 4px;
margin-left: 5px;
}
.tabs-view-item-active {
display: inline-block;
cursor: pointer;
height: 26px;
line-height: 26px;
padding: 0 8px;
font-size: 12px;
margin-top: 4px;
margin-left: 5px;
background-color: #42b983;
color: #fff;
border-color: #42b983;
}
}
}
.el-icon-close:hover {
border-radius: 50%;
background: #b4bccc;
transition-duration: 0.3s;
}//删除图标悬浮效果
.tabs-view-item-active:before {
content: '';
background: #fff;
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
position: relative;
margin-right: 2px;
}//选中的白色圆圈
vuex中的数据:
state: {
tabList: [{
name: "首页", path: "/homepage" }],},要安装数据持久化插件。否者刷新变回原状。
//关闭所以页面
vuex中的方法
resetTab(state) {
state.tabList = [{
name: "首页", path: "/homepage" }];
},
closeAllTab() {
this.$store.commit('resetTab')
this.$router.push('/homepage')
},
页面中的方法:
closeAllTab() {
this.$store.commit('resetTab')
this.$router.push('/homepage')
},
//删除标签
vuex中的方法
removeTab(state, tab) {
let index = state.tabList.findIndex(item => item.name === tab.name);
state.tabList.splice(index, 1);
},
页面中的方法:
removeTab(tab) {
//删除标签
this.$store.commit('removeTab', tab)
//如果删除的是当前页则返回上一标签页
if (tab.path == this.$route.path) {
var tabList = this.$store.state.tabList
this.$router.push({
path: tabList[tabList.length - 1].path })
}
},
//跳转
页面中的方法
goTo(item) {
this.$router.push(item.path)
},
//保存标签
vuex中的方法
saveTab(state, tab) {
if (state.tabList.findIndex(item => item.path === tab.path) == -1) {
state.tabList.push({
name: tab.name, path: tab.path });
}
},
页面中的方法
updated() {
this.$store.commit('saveTab', this.$route)
},
Js:
computed: {
//标签是否处于当前页
isActive() {
return function (tab) {
//tab是循环元素中的一项
if (tab.path == this.$route.path) {
return 'tabs-view-item-active'
}
return 'tabs-view-item'
}
},
},
面包屑
<!-- 面包屑 -->
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/home' }"
>首页</el-breadcrumb-item
>
<el-breadcrumb-item
v-if="
breadcrumbList[this.$route.path.replace('/', '')][2] !==
'首页'
"
>{
{
breadcrumbList[this.$route.path.replace('/', '')][2]
}}</el-breadcrumb-item
>
<el-breadcrumb-item
v-if="
breadcrumbList[this.$route.path.replace('/', '')][0] !==
'首页'
"
>{
{
breadcrumbList[this.$route.path.replace('/', '')][1]
}}</el-breadcrumb-item
>
<el-breadcrumb-item
v-if="
breadcrumbList[this.$route.path.replace('/', '')][0] !==
'首页'
"
>{
{
breadcrumbList[this.$route.path.replace('/', '')][0]
}}</el-breadcrumb-item
>
</el-breadcrumb>
//数据
breadcrumbList: {
homepage: ['首页', '系统首页', '首页'],
log: ['登录日志', '系统首页', '首页'],
sysmessage: ['系统信息', '系统首页', '首页'],
newhousehold: ['新建户信息', '人员中心管理', '人员中心管理'],
importhousehold: ['导入户消息', '人员中心管理', '人员中心管理'],
verifyhousehold: ['户信息核查', '人员中心管理', '人员中心管理'],
datacontrast: ['数据反向对比', '人员中心管理', '人员中心管理'],
autiohousehold: ['户信息审核', '人员中心管理', '人员中心管理'],
checkhousehold: ['户信息查询', '人员中心管理', '人员中心管理'],
historydata: ['历史数据', '人员中心管理', '人员中心管理'],
powermanage: ['权限管理', '权限管理', '系统设置'],
membermanage: ['人员管理', '权限管理', '系统设置'],
},
装饰(全局样式)
html,body,#app{
height: 100%;
}
*{
margin: 0;
padding: 0;
}
.el-card.is-always-shadow,
.el-card.is-hover-shadow:focus,
.el-card.is-hover-shadow:hover {
box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
}//通用配置
.icon, .iconfont {
font-family:"iconfont" !important;
font-size:16px;
font-style:normal;
margin-right: 0.5rem;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
} //阿里图标库
.title {
position: absolute;
left: 0;
font-size: 16px;
font-weight: bold;
color: #202a34;
top: 1rem;
}
.title::before {
content: '';
width: 24px;
height: 16px;
border-left: 3px solid #0081ff;
margin-right: 20px;
}//小竖线
分页
<!-- 分页 -->
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="query.page "
:page-sizes="[10, 20, 30, 40]"
:page-size="query.page_size"
layout="total, sizes, prev, pager, next, jumper"
:total="pageTotal">
</el-pagination>
pageTotal:'',
query:{
page:'',
page_size:''
}
handleSizeChange(val) {
console.log(`每页 ${
val} 条`); }, handleCurrentChange(val) {
console.log(`当前页: ${
val}`); }
Switch开关在table里显示
<el-table-column label="状态" >
<template slot-scope="scope">
<el-switch v-model="scope.row.mg_ state'
@change="userStateChanged(scope.row)">
</el-switch>
</template>
</el-table- column>
const {
data: res } = await this.$http.put(users/${
userinfo.id}/state/${
userinfo.mg_ state}
//接口路径需要传对应的用户id
输入框clearable属性,有一个对应的方法clear,可以绑定在此重新发送菜单请求,dialog关闭有一个close事件。
element ui 表单自定义验证规则
{
validator: checkAge, trigger: 'blur' }//使用
//在data里定义
// 验证邮箱的规则
var checkEmail = (rule, value, cb) => {
//验证规则,需要验证的值,回调函数
// 验证邮箱的正则表达式
const regEmail = /^([a-zA-Z0-9_ -])+@(
[a-zA-Z0-9_ - ])+(\.[a-zA-Z0-9_ -])+/
if (regEmail.test(value)) {
//合法的邮箱
return cb()
}
cb(new Error('请输入合法的邮箱'))
table展开行
<!--展开列-->
<el-table-column type="expand">
<template slot-scope="scope">
<pre>{
{
scope. row}}</pre>
</template>
</el-table-column>
按条件添加css类名
:class="['a',i===0?'b':'']"
级联选择器
<el-cascader
v-model="value" //数组
:options="options"//数据源
:props="{ expandTrigger: 'hover' }" //配置项
@change="handleChange">//级联框变化触发的函数
</el-cascader>
树组件
<el-tree
:data="data" //数据项
:props="defaultProps"
//defaultProps: { children: 'children'//用来嵌套的属性, label: 'label'//数据中的名字 }
show-checkbox
node-key="id"
default-expand-all
:default-checked-keys="defKeys"//默认选中,数组
</el-tree>