<template>
<el-table
:row-class-name="tableRowClassName"
>
</el-table>
</template>
<script setup>
const tableRowClassName = ({ rowIndex }) => {
const index = rowIndex + 1
if (index % 2 === 0) {
return 'even-number'
} else if (index % 2 === 1) {
return 'odd-number'
}
}
</script>
<style lang="scss" scoped>
:deep(.odd-number) {
background-color: #F3F3F5;
}
</style>
<template>
<el-table
:header-cell-style="headerName">
</el-table>
</template>
<script setup>
const headerName = () => {
return 'background: linear-gradient(180deg, #E8E8E8 0%, #CCCCCC 100%)'
}
</script>
:deep(.el-table) {
.el-table__row>td{
border: none;
}
.el-table__inner-wrapper::before{ // 取消td的border之后,若最下方还有一个边框,则需要此代码
content: unset;
}
}
直接展示当前字段时会把’[’ ']'也显示出来
<el-table-column
property="free_param"
label="自由参数定制">// 假设scope.row.free_param为[1,3,4,5,6]
<template #default="scope">
<template v-if="scope.row.free_param.length">
<p v-for="itemin scope.row.free_param">
{{ item }}
</p>
</template>
<template v-else>
—
</template>
</template>
</el-table-column>
<el-table
:data="sliceTableData"
v-loading="loading"
>
<el-table-column type="selection" width="55" :selectable="isSelectTable"/>
</el-table>
function isSelectTable(row: any, index: number) {
return row.auditStatus === '条件判断'
}
<template>
<el-date-picker
:prefix-icon="customPrefix">
</el-date-picker>
</template>
<script setup>
const customPrefix = shallowRef({
render () { // class为自定义的图标类名
return h('p', { class: 'icon-rili-01 font_family icon-size' })
}
})
</script>
<style> // 不需要修改图标定位的不用写
:deep(.el-input__prefix) { // element plus 日历中图标的类名是el-input__prefix
right: 5px;
left: unset; // element设置的定位,left为5px,这里取消默认的left
}
</style>
<template>
<div class="side-bar">
<el-menu
class="el-menu-vertical-demo"
:default-active="$route.path" // 记得绑定
router>
<el-sub-menu v-for="(item, key) in menuList"
:key="key"
:index="key+''">
<template #title>
<span>{{ item.menuName }}</span>
</template>
<el-menu-item-group v-for="(childItem, childKey) in item.children" :key="childKey">
<el-menu-item :index="childItem.url">
{{ childItem.menuName }}
</el-menu-item>
</el-menu-item-group>
</el-sub-menu>
</el-menu>
</div>
</template>
<script setup>
import { reactive } from 'vue'
const menuList = reactive([
{
menuName: 'slurm可视化',
children: [{ menuName: '工作列表', url: '/slurm'}]
},
{
menuName: '显卡列表',
children: [{ menuName: '录入显卡', url: '/graphicsCard'}]
},
{
menuName: '录入算法任务',
children: [{ menuName: '录入任务', url: '/algorithm'}]
},
{
menuName: '设置',
children: [
{ menuName: '权限分配', url: '/setting/permissions', name: 'permissions' },
{ menuName: '用户列表', url: '/setting/userList', name: 'user' },
{ menuName: '角色分配', url: '/setting/role', name: 'role' }
]
}
])
$ npm install @element-plus/icons-vue
或
$ yarn add @element-plus/icons-vue
或
$ pnpm install @element-plus/icons-vue
// --------template
<el-form
ref="formRef"
:model="form"
:rules="rules"
label-position="left"
label-width="120px"
>
<el-form-item
label="自由参数定制"
class="free-param"
prop="free_param"
>
<!-- v-for="item in form.free_param" -->
<div class="free-param-one">
<el-input v-model="form.free_param[0]"></el-input>
<span @click="addFreeParam">
<el-icon size="20px"><Plus /></el-icon>
</span>
</div>
<template v-if="form.free_param.length > 1">
<div
class="free-param-one"
v-for="(item, index) in form.free_param.length - 1"
>
<el-input v-model="form.free_param[index+1]">
</el-input>
<span @click="minusFreeParam(index+1)">
<el-icon><Minus /></el-icon>
</span>
</div>
</template>
</el-form-item>
</el-form>
// ---------js
import { reactive } from 'vue'
const form = reactive({
free_param: []
})
const validateName = (rule, value, callback) => { // 只允许输入英文/标点符号/数字
const title= /^[0-9\a-\z\A-\Z]|["',,.。/、\]\[【】\\n\s!!??——_<>%;‘’;)《()》(&+=`“”·*#@@]/
const zh = /[\u4e00-\u9fa5]$/
const data = value.every((item) => {
if (!title.test(item) || zh.test(item)) {
callback(new Error('仅支持输入英文、标点符号、数字'))
} else {
return true
}
})
if (data) callback()
}
const rules = reactive({
free_param: [
{ required: true, message: '仅支持输入英文、标点符号、数字', trigger: 'blur' },
{ max: 10, validator: validateName, trigger: 'blur' }
]
})
const addFreeParam = (val) => {
// 若有空值,则不允许再次添加输入框
let flag = true
form.free_param.forEach((item) => {
if (!item.trim()) flag = false
})
if (!flag) return
form.free_param.push('')
}
const minusFreeParam = (index) => {
form.free_param.splice(index, 1)
}
// ---------------css
.free-param {
.el-form-item__content {
.free-param-one {
display: flex;
width: 100%;
}
.free-param-one+.free-param-one {
margin-top: 10px;
}
.el-icon {
font-size: 22px;
margin-left: 5px;
height: 100%;
cursor: pointer;
}
}
}
因需求需要,对element-plus select选择器做了一点改动
<!-- 全选选择器组件 -->
<template>
<el-select v-model="selectValue"
:filterable="filterable" // 可搜索
:multiple="multiple" // 可多选
:collapse-tags="collapseTags" // 多选时是否将选中值按文字的形式展示
:collapse-tags-tooltip="collapseTags && collapseTagsTooltip" // 当鼠标悬停于折叠标签的文本时,是否显示所有选中的标签。 要使用此属性,collapse-tags属性必须设定为 true
:default-first-option="defaultFirstOption && filterable" // 是否在输入框按下回车时,选择第一个匹配项。 需配合 filterable 或 remote 使用
@change="$emit('selectChange', selectValue)" // 选择器改变触发父组件方法以传更改后的值
>
<el-checkbox v-model="checkedBoxValue" style="width: 100%;padding-left:15px;"
label="全选" @change="handleAllChange" />
<el-option
v-for="item in options"
:key="item.key"
:label="item.value"
:value="item.key"
>
<span>{{ item.value }}</span>
</el-option>
</el-select>
</template>
<script setup>
const props = defineProps({
options: {
type: Array,
default: []
},
filterable: {
type: Boolean,
default: true
},
multiple: {
type: Boolean,
default: true
},
collapseTags: {
type: Boolean,
default: true
},
collapseTagsTooltip: {
type: Boolean,
default: true
},
defaultFirstOption: {
type: Boolean,
default: true
}
})
const checkedBoxValue = ref(true) // 【全选】默认为选中状态
const selectValue = ref([])
const emits = defineEmits(['selectChange'])
const handleAllChange = (val) => {
if (checkedBoxValue.value) {
selectValue.value = props.options.map(item => {
return item.key // 可以修改【全选】时下方选项的状态
})
// 点击【全选】触发更改事件
emits('selectChange', selectValue.value)
} else {
selectValue.value = []
emits('selectChange', selectValue.value)
}
}
watchEffect((val) => { // 初始监听数据
if(checkedBoxValue.value) {
selectValue.value = props.options.map(item => {
return item.key
})
}
})
watch(
selectValue,
(newValue) => {
checkedBoxValue.value = newValue.length === props.options.length
}
)
</script>
使用:
<el-form-item label="病理指标">
<pathology-select
:options="pathologyOptions"
ref="projectSelectRef"
@selectChange="pathologyChange"
/>
</el-form-item>
const pathologyOptions = reactive([{key: 0, value: '第一个'},{key: 1, value: '第二个'},{key: 2, value: '第三个'},{key: 3, value: '第四个'},{key: 4, value: '第五个'},{key: 5, value: '第六个'}])
const pathologyChange = (val) => {
console.log(val)
}
效果如下
QQ录屏20220714150507
<el-tooltip
effect="light"
content="快捷键说明"
placement="left"
:append-to-body="false">
<el-icon :size="18"
class="button"
ref="ShortcutKeyRef" // 为了popover中的virtual-ref字段
@click.stop="ShortcutKey = true">
<QuestionFilled />
</el-icon>
</el-tooltip>
<el-popover
effect="light" trigger="click"
placement="left"
:virtual-ref="ShortcutKeyRef" // 需与tooltip中的ref组合使用
virtual-triggering // 加上该字段可以不显示ElementPlusError: [ElOnlyChild] no valid child node found的警告
>
<div>
<b>快捷键说明</b>
<el-icon @click="ShortcutKey = false"><Close /></el-icon>
</div>
</el-popover>
const ShortcutKey = ref(false)
const ShortcutKeyRef = ref()
场景:表格内,每个步骤条单独的颜色显示。(使用Step 属性的 status)
html:
<el-table
:data="sliceList"
v-loading="loading"
>
<el-table-column label="新切片编号" prop="newSliceId" width="100"></el-table-column>
<el-table-column label="项目名称" prop="projectName" width="150"></el-table-column>
<el-table-column label="分析诊断进度" prop="progress">
<template #default="scope">
<el-steps align-center >
<template v-for="item in scope.row.progress">
<el-step :title="item.stayName"
:status="item.color"/>
</template>
</el-steps>
</template>
</el-table-column>
</el-table>
js:
step的status属性对应颜色'wait灰色' | 'process黑色' | 'finish蓝色' | 'error红色' | 'success绿色'
sliceList.value = [
{ newSliceId: '新切片编号1', projectName: '项目名称1', progress: [
{ stayName: '待分析', color: 'finish' },
{ stayName: 'AI分析中', color: 'wait' },
{ stayName: 'AI分析成功', color: 'wait' },
{ stayName: '人工诊断', color: 'wait' },
] },
{ newSliceId: '新切片编号2', projectName: '项目名称1', progress: [
{ stayName: '待分析', color: 'finish' },
{ stayName: 'AI分析中', color: 'finish' },
{ stayName: 'AI分析成功', color: 'wait' },
{ stayName: '人工诊断', color: 'wait' },
] },
{ newSliceId: '新切片编号3', projectName: '项目名称1', progress: [
{ stayName: '待分析', color: 'finish' },
{ stayName: 'AI分析中', color: 'finish' },
{ stayName: 'AI分析成功', color: 'success' },
{ stayName: '人工诊断', color: 'wait' },
] },
{ newSliceId: '新切片编号4', projectName: '项目名称1', progress: [
{ stayName: '待分析', color: 'finish' },
{ stayName: 'AI分析中', color: 'finish' },
{ stayName: 'AI分析失败', color: 'error' },
{ stayName: '人工诊断', color: 'wait' },
] },
{ newSliceId: '新切片编号5', projectName: '项目名称1', progress: [
{ stayName: '待分析', color: 'finish' },
{ stayName: 'AI分析中', color: 'finish' },
{ stayName: 'AI分析成功', color: 'success' },
{ stayName: '人工诊断', color: 'process' },
] },
{ newSliceId: '新切片编号6', projectName: '项目名称1', progress: [
{ stayName: '待分析', color: 'finish' },
{ stayName: 'AI分析中', color: 'finish' },
{ stayName: 'AI分析失败', color: 'error' },
{ stayName: '人工诊断', color: 'process' },
] },
{ newSliceId: '新切片编号7', projectName: '项目名称1', progress: [
{ stayName: '待分析', color: 'finish' },
{ stayName: '人工诊断', color: 'process' },
] }
]
css:(把process默认的黑色改为黄色了)
:deep(.el-table) {
.el-step {
.el-step__head.is-process {
.is-text {
border-color: #FFD700;
}
.el-step__icon-inner {
color: #FFD700;
}
.el-step__title {
color: #FFD700;
}
}
.el-step__title.is-process {
color: #FFD700;
}
}
}
<el-form
ref="roleFormRef"
:model="formData"
:rules="formRules"
>
<el-form-item label="功能权限" prop="menuIds">
<el-tree
:data="menuOptions"
show-checkbox
ref="roleTreeRef"
node-key="menuId"
@check="checkChangeHandle"
empty-text="加载中,请稍候"
:props="{ label: 'menuName', children: 'children' }"
></el-tree>
</el-form-item>
</el-form>
const formData = reactive({
remark: '',
menuIds: ''
})
const menuOptions = ref([0, 2, 3, 4, 5])
function checkChangeHandle(a: any, b: any) {
formData.menuIds = b.checkedKeys
}
async function editRoleHandle(row: SubjectRole) {
let treeData:any = []
await getEditRoleTree(row.roleId)
.then((res: any) => {
treeData = res.data.checkedKeys // 后端返回选中的id
menuOptions.value = res.data.menus // 后端返回全部的id
})
.catch(err => console.log(err))
treeData.forEach((item: number) => {
nextTick(() => {
roleTreeRef.value.setChecked(item, true, false) // 回显
})
})
formData.menuIds = treeData
}
function submitForm(formEl: FormInstance | unpostSliceListdefined) {
formEl.validate((valid: any) => {
if (valid) {
let getCheckId = roleTreeRef.value.getCheckedKeys() // 被选中的菜单节点
let halfCheckedKeys = roleTreeRef.value.getHalfCheckedKeys() // 半选中的菜单节点
getCheckId.unshift.apply(getCheckId, halfCheckedKeys)
formData.menuIds = getCheckId
} else {
console.log('error submit!')
}
})
}
下方代码可解决搜索时不显示下级的问题
<el-tree
:data="filterProjectList"
:filter-node-method="filterNode"
>
function filterNode(value: string, data: any, node: any) {
/* if (!value) return true
return data.label.includes(value) */
// 上方的方式el-tree默认会不显示下级
let parentNode = node.parent; // 父级node
let labels = [node.label]; // 当前node的名字
let level = 1; // 层级
while (level < node.level) {
labels = [...labels, parentNode.label]; // 当前node名字,父级node的名字
parentNode = parentNode.parent;
level++;
}
return labels.some((d) => d.indexOf(value) !== -1);
}