Skip to content

ElementUI常见案例

<el-tree
ref="tree"
:data="cateTreeData"
//给节点一个id,cateTreeData中的字段
node-key="id"
//默认展开,参数需要展开的节点id
:default-expanded-keys="[$route.query.id ?? 0]"
//默认选中,参数需要展开的节点id
:default-checked-keys="[$route.query.id ?? 0]"
//定义子节点和标题字段
:props="defaultPick"
@node-click="trigger"
highlight-current
>
</el-tree>
const defaultPick = reactive({
children: 'children',
label: 'articleCateName'
})
if (this.dataForm.id ) this.$refs.tree.setCurrentKey(this.dataForm.id );

触发整个表单的校验:this.$refs.queryForm.validate(); 触发对表单部分字段的校验:this.$refs.queryForm.validateField('propname');

dataRule: {
articleCateName: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ validator:(rule, value, callback) => {
console.log(!/^[^\u4e00-\u9fa5]+$/.test(value), Boolean(this.dataForm.cateUrl));
if (!(/^[^\u4e00-\u9fa5]+$/.test(value)) && !this.dataForm.cateUrl) {
callback(new Error("如果分类名称为中文,需要自定义url"))
}
//正确情况下要加回调,否则校验函数一直是pending状态不会执行
callback()
}, trigger: 'blur' }
],
cateUrl: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ pattern: /^[^\u4e00-\u9fa5]+$/, message: "url需要是英文格式", trigger: 'blur' },
]
}

合并 row ,上一行和下一行相同的 td 合并成一行

//合并单元格方法
<el-table
:span-method="formatCol"
>
data() {
return {
colIdx: 0
}
}
formatCol({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
const _row = this.spanArr[rowIndex]
const _col = _row > 0 ? 1 : 0
const res ={
rowspan: _row,
colspan: _col
}
console.log(res);
return res
}
},
{/*获取数据的时候调用*/}
getSpan() {
this.tableData.forEach((item, index) => {
if (index === 0) {
this.spanArr.push(1)
} else {
if ( this.tableData[index].name === this.tableData[index - 1].name ) {
//如果和上一个属性一致的话累加要合并的行或者列
//返回 {rowspan:0, colspan:0} 代表当前单元格不显示
this.spanArr[this.colIdx] += 1
this.spanArr.push(0)
} else {
//如果和不一致的话返回 {rowspan:1, colspan:1} 代表一行一列展示
this.spanArr.push(1)
this.colIdx = index
}
}
})
},

说明:3个方法即可,要保存对象的情况下也可以使用 Map

1、模板

<el-table
:data="dataList"
v-loading="loading"
ref="tableRef"
@select="selectionChange"
@select-all="selectionAll"
>

2、方法

export default {
data() {
return {
loading: false,
dataList: [],
multipleSelection: new Set([])
}
},
methods: {
selectionChange(rows, row) {
if (!this.multipleSelection) {
this.multipleSelection = new Set([])
}
if (rows.find(val => val.prdId === row.prdId)) {
this.multipleSelection.add(row.prdId)
} else {
this.multipleSelection.delete(row.prdId)
}
this.pickCount = this.multipleSelection.size
},
selectionAll(e) {
if (!this.multipleSelection) {
this.multipleSelection = new Set([])
}
if (e.length) {
e.forEach(val => {
this.multipleSelection.add(val.prdId)
})
} else {
this.dataList.forEach(val => {
this.multipleSelection.has(val.prdId) && this.multipleSelection.delete(val.prdId)
})
}
this.pickCount = this.multipleSelection.size
},
},
queryDataList() {
this.loading = true
this.$axios.post('/api/data-genius/product-analysis-data').then(res => {
this.loading = false
if (!Object.keys(res.data).length) return
if ( res.data.code !== 0) {
this.$message({
type: 'error',
message: res.data.msg
});
} else {
this.dataList = res.data.data.list
//回显数据
if (this.multipleSelection.size) {
this.$nextTick(e => {
this.dataList.forEach(val => {
if (this.multipleSelection.has(val.prdId)) {
this.$refs.tableRef.toggleRowSelection(val, true)
}
})
})
}
}
});
},
}

1、模板

<el-table
:data="dataList"
v-loading="loading"
ref="tableRef"
@select="handleSelect"
@select-all="handleSelectionAll"
>

2、方法

//回显
showSelectRow() {
this.$nextTick(() => {
this.tableList.forEach(val => {
if (this.productsMap.has(val.productId)) {
this.$refs.tableRef.toggleRowSelection(val, true)
}
})
})
},
// 点击单选
handleSelect(selection, row) {
if (this.productsMap.has(row.productId)) {
this.productsMap.delete(row.productId)
} else {
this.productsMap.set(row.productId, row)
}
},
handleSelectionAll(e) {
if (e.length) {
e.forEach(val => this.productsMap.set(val.productId, val))
} else {
this.tableList.forEach(val => {
this.productsMap.has(val.productId) && this.productsMap.delete(val.productId)
})
}
},
trigger() {
this.$emit('getGoodsInfo', Array.from(this.productsMap.values()))
}
<div class="login-account">
<!-- model 表单数据对象 -->
<!-- rules 表单验证规则 -->
<el-form label-width="60px" :rules="rules" :model="account" ref="formRef">
<!-- prop 当前 input 的name -->
<el-form-item label="账号" prop="name">
<!-- 双向绑定 input 的value -->
<el-input v-model="account.name" />
</el-form-item>
<el-form-item label="密码" prop="password">
<!-- 显示是否查看密码 -->
<el-input v-model="account.password" show-password />
</el-form-item>
</el-form>
</div>
//有父组件登录时点击后调用该函数
const loginAction = (isKeepPassword: boolean) => {
//执行form 表单校验
formRef.value?.validate((valid) => {
if (valid) {
// 1.判断是否需要记住密码
if (isKeepPassword) {
// 本地缓存
localCache.setCache('name', account.name)
//通常加密保存密码
localCache.setCache('password', account.password)
} else {
localCache.deleteCache('name')
localCache.deleteCache('password')
}
// 2.开始进行登录验证
store.dispatch('login/accountLoginAction', { ...account })
}
})
}
// 编写好规则
export const rules = {
//name 字段可以添加多个校验规则
//第一个规则,必填在没有填的情况下会提示 message
//第二个规则,在没有盘组pattern 的情况下会提示 message
name: [
{
required: true,
message: '用户名是必传内容~',
trigger: 'blur'
},
{
pattern: /^[a-z0-9]{5,10}$/,
message: '用户名必须是5~10个字母或者数字~',
trigger: 'blur'
}
],
password: [
{
required: true,
message: '密码是必传内容~',
trigger: 'blur'
},
{
pattern: /^[a-z0-9]{3,}$/,
message: '用户名必须是3位以上的字母或者数字~',
trigger: 'blur'
}
]
}
  • index: 用于判断菜单是否是选中状态,不设置的话默认全部选中

  • collapse: boolean 属性 默认不折叠菜单。

    开启折叠之后 会有1px的 border-right ,通过覆盖 el-menu 属性来取消border

  • default-active:默认选中第几个菜单

  • active-text-color:文本选中的颜色

<template>
<div class="nav-menu">
<div class="logo">
<img class="img" src="~@/assets/img/logo.svg" alt="logo" />
<span v-if="!collapse" class="title">Vue3+TS</span>
</div>
<el-menu
default-active="2"
class="el-menu-vertical"
:collapse="collapse"
background-color="#0c2135"
text-color="#b7bdc3"
active-text-color="#0a60bd"
>
<template v-for="item in userMenus" :key="item.id">
<!-- 二级菜单 -->
<template v-if="item.type === 1">
<!-- 二级菜单的可以展开的标题,不添加index 属性,默认全部选中 -->
<el-submenu :index="item.id + ''">
<!-- 菜单标题放入 title 具名插槽中插槽 -->
<template #title>
<i v-if="item.icon" :class="item.icon"></i>
<span>{{ item.name }}</span>
</template>
<!-- 遍历里面的item,item 是放入默认插槽 -->
<template v-for="subitem in item.children" :key="subitem.id">
<el-menu-item
:index="subitem.id + ''"
@click="handleMenuItemClick(subitem)"
>
<i v-if="subitem.icon" :class="subitem.icon"></i>
<span>{{ subitem.name }}</span>
</el-menu-item>
</template>
</el-submenu>
</template>
<!-- 一级菜单 -->
<template v-else-if="item.type === 2">
<el-menu-item :index="item.id + ''">
<i v-if="item.icon" :class="item.icon"></i>
<span>{{ item.name }}</span>
</el-menu-item>
</template>
</template>
</el-menu>
</div>
</template>