【条件渲染】关于在<template>上使用v-if分类的理解

本文介绍了一个使用条件渲染来展示不同人员及其属性的例子。通过简单的模板语法实现针对不同名字的个性化展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<div v-for="people in arr">
      <template v-if="people.name == '张三'">
            {{people.name}}的有{{people.length}}
      </template>
      <template v-if="people.name == '李四'">
            {{people.name}}有{{people.length}}
      </template>
      <template v-if="people.name == '王五'">
            {{people.name}}足有{{people.length}}
      </template>
  </div>
根据条件分别渲染不同条件的数据
<template> <!-- drawer --> <template v-if="modalConfig?.component === 'drawer'"> <el-drawer v-model="modalVisible" :append-to-body="true" v-bind="modalConfig?.drawer" @close="handleCloseModal" > <!-- 表单 --> <el-form ref="formRef" label-width="auto" v-bind="modalConfig?.form" :model="formData" :rules="formRules" :disabled="modalConfig?.formDisabled" > <el-row :gutter="20"> <template v-for="item in formItems" :key="item.prop"> <el-col v-show="!item.hidden" v-bind="item.col"> <el-form-item :label="item.label" :prop="item.prop"> <!-- Label --> <template v-if="item.tips" #label> <span> {{ item.label }} <el-tooltip placement="bottom" effect="light" :content="item.tips + ''" :raw-content="true" > <el-icon style="vertical-align: -0.15em" size="16"> <QuestionFilled /> </el-icon> </el-tooltip> </span> </template> <!-- Input 输入框 --> <template v-if="item.type === 'input' || item.type === undefined"> <el-input v-model="formData[item.prop]" v-bind="item.attrs" /> </template> <!-- Select 选择器 --> <template v-else-if="item.type === 'select'"> <el-select v-model="formData[item.prop]" v-bind="item.attrs"> <template v-for="option in item.options" :key="option.value"> <el-option v-bind="option" /> </template> </el-select> </template> <!-- Radio 单选框 --> <template v-else-if="item.type === 'radio'"> <el-radio-group v-model="formData[item.prop]" v-bind="item.attrs"> <template v-for="option in item.options" :key="option.value"> <el-radio v-bind="option" /> </template> </el-radio-group> </template> <!-- switch 开关 --> <template v-else-if="item.type === 'switch'"> <el-switch v-model="formData[item.prop]" inline-prompt v-bind="item.attrs" /> </template> <!-- Checkbox 多选框 --> <template v-else-if="item.type === 'checkbox'"> <el-checkbox-group v-model="formData[item.prop]" v-bind="item.attrs"> <template v-for="option in item.options" :key="option.value"> <el-checkbox v-bind="option" /> </template> </el-checkbox-group> </template> <!-- Input Number 数字输入框 --> <template v-else-if="item.type === 'input-number'"> <el-input-number v-model="formData[item.prop]" v-bind="item.attrs" /> </template> <!-- TreeSelect 树形选择 --> <template v-else-if="item.type === 'tree-select'"> <FkSelectTree v-model="formData[item.prop]" v-bind="item.attrs" :multiple="item.attrs?.multiple" /> </template> <!-- DatePicker 日期选择器 --> <template v-else-if="item.type === 'date-picker'"> <el-date-picker v-model="formData[item.prop]" v-bind="item.attrs" /> </template> <!-- Text 文本 --> <template v-else-if="item.type === 'text'"> <el-text v-bind="item.attrs"> {{ formData[item.prop] }} </el-text> </template> <!-- 格式化代码集 --> <template v-else-if="item.type === 'sys-code'"> <FkSysCode v-model="formData[item.prop]" :sysCode="item.sysCodeSetCode" v-bind="item.attrs" /> </template> <!-- 自定义 --> <template v-else-if="item.type === 'custom'"> <slot :name="item.slotName ?? item.prop" :prop="item.prop" :form-data="formData" :attrs="item.attrs" /> </template> </el-form-item> </el-col> </template> </el-row> </el-form> <!-- 弹窗底部操作按钮 --> <template #footer> <div v-if="!formDisable"> <el-button type="primary" @click="handleSubmit">确 定1</el-button> <el-button @click="handleClose">取 消</el-button> </div> <div v-else> <el-button @click="handleClose">关闭</el-button> </div> </template> </el-drawer> </template> <!-- dialog --> <template v-else> <el-dialog v-model="modalVisible" :align-center="true" :append-to-body="true" width="70vw" v-bind="modalConfig?.dialog" style="padding-right: 0" @close="handleCloseModal" > <!-- 滚动 --> <el-scrollbar max-height="60vh"> <!-- 表单 --> <el-form ref="formRef" label-width="auto" v-bind="modalConfig.form" style="padding-right: var(--el-dialog-padding-primary)" :model="formData" :rules="formRules" > <el-row :gutter="20"> <template v-for="item in formItems" :key="item.prop"> <el-col v-show="!item.hidden" v-bind="item.col"> <el-form-item :label="item.label" :prop="item.prop"> <!-- Label --> <template v-if="item.tips" #label> <span> {{ item.label }} <el-tooltip placement="bottom" effect="light" :content="item.tips + ''" :raw-content="true" > <el-icon style="vertical-align: -0.15em" size="16"> <QuestionFilled /> </el-icon> </el-tooltip> </span> </template> <!-- Input 输入框 --> <template v-if="item.type === 'input' || item.type === undefined"> <el-input v-model="formData[item.prop]" v-bind="item.attrs" clearable /> </template> <!-- Select 选择器 --> <template v-else-if="item.type === 'select'"> <el-select v-model="formData[item.prop]" v-bind="item.attrs"> <template v-for="option in item.options" :key="option.value"> <el-option v-bind="option" /> </template> </el-select> </template> <!-- Radio 单选框 --> <template v-else-if="item.type === 'radio'"> <el-radio-group v-model="formData[item.prop]" v-bind="item.attrs"> <template v-for="option in item.options" :key="option.value"> <el-radio v-bind="option" /> </template> </el-radio-group> </template> <!-- switch 开关 --> <template v-else-if="item.type === 'switch'"> <el-switch v-model="formData[item.prop]" inline-prompt v-bind="item.attrs" /> </template> <!-- Checkbox 多选框 --> <template v-else-if="item.type === 'checkbox'"> <el-checkbox-group v-model="formData[item.prop]" v-bind="item.attrs"> <template v-for="option in item.options" :key="option.value"> <el-checkbox v-bind="option" /> </template> </el-checkbox-group> </template> <!-- Input Number 数字输入框 --> <template v-else-if="item.type === 'input-number'"> <el-input-number v-model="formData[item.prop]" v-bind="item.attrs" /> </template> <!-- TreeSelect 树形选择 --> <template v-else-if="item.type === 'tree-select'"> <FkSelectTree v-model="formData[item.prop]" v-bind="item.attrs" :multiple="item.attrs?.multiple" /> </template> <!-- DatePicker 日期选择器 --> <template v-else-if="item.type === 'date-picker'"> <el-date-picker v-model="formData[item.prop]" v-bind="item.attrs" /> </template> <!-- Text 文本 --> <template v-else-if="item.type === 'text'"> <el-text v-bind="item.attrs"> {{ formData[item.prop] }} </el-text> </template> <!-- 格式化代码集 --> <template v-else-if="item.type === 'sys-code'"> <FkSysCode v-model="formData[item.prop]" :sys-code="item.sysCodeSetCode" v-bind="item.attrs" /> </template> <!-- 自定义 --> <template v-else-if="item.type === 'custom'"> <slot :name="item.slotName ?? item.prop" :prop="item.prop" :form-data="formData" :attrs="item.attrs" /> </template> </el-form-item> </el-col> </template> </el-row> </el-form> </el-scrollbar> <!-- 弹窗底部操作按钮 --> <template #footer> <div style="padding-right: var(--el-dialog-padding-primary)"> <el-button type="primary" @click="handleSubmit">确 定</el-button> <el-button @click="handleClose">取 消</el-button> </div> </template> </el-dialog> </template> </template> <script setup lang="ts"> import { useThrottleFn } from "@vueuse/core"; import type { FormInstance, FormRules } from "element-plus"; import { nextTick, reactive, ref, watch, watchEffect } from "vue"; import type { IModalConfig, IObject, IContentConfig } from "./types"; // 定义接收的属性 const props = defineProps<{ modalConfig: IModalConfig; contentConfig?: IContentConfig; }>(); // 自定义事件 const emit = defineEmits<{ submitClick: []; }>(); const pk = props.modalConfig?.pk ?? "id"; const modalVisible = ref(false); const formRef = ref<FormInstance>(); let formItems = reactive(props.modalConfig.formItems); let formItemChanges = ref<Record<string, any>>({}); const formData = reactive<IObject>({}); const formRules = ref<FormRules>({}); const formDisable = ref(false); const prepareFuncs = []; for (const item of formItems) { item.initFn && item.initFn(item); formData[item.prop] = item.initialValue ?? ""; formRules.value[item.prop] = item.rules ?? []; if (item.watch !== undefined) { prepareFuncs.push(() => { watch( () => formData[item.prop], (newValue, oldValue) => { item.watch && item.watch(newValue, oldValue, formData, formItems); } ); }); } if (item.computed !== undefined) { prepareFuncs.push(() => { watchEffect(() => { item.computed && (formData[item.prop] = item.computed(formData)); }); }); } if (item.watchEffect !== undefined) { prepareFuncs.push(() => { watchEffect(() => { item.watchEffect && item.watchEffect(formData); }); }); } if (item.change) { formItemChanges.value[item.prop] = item.change; } } prepareFuncs.forEach((func) => func()); // 获取表单数据 function getFormData(key?: string) { return key === undefined ? formData : (formData[key] ?? undefined); } // 设置表单值 function setFormData(data: IObject) { for (const key in formData) { if (Object.prototype.hasOwnProperty.call(formData, key) && key in data) { formData[key] = data[key]; formRef.value?.clearValidate(); } } if (Object.prototype.hasOwnProperty.call(data, pk)) { formData[pk] = data[pk]; formRef.value?.clearValidate(); } } // 设置表单项值 function setFormItemData(key: string, value: any) { formData[key] = value; formRef.value?.clearValidate(); } // 显示modal function setModalVisible(data: IObject = {}) { modalVisible.value = true; // nextTick解决赋值后重置表单无效问题 nextTick(() => { Object.values(data).length > 0 && setFormData(data); }); formRef.value?.clearValidate(); } // 表单提交 const handleSubmit = useThrottleFn(() => { formRef.value?.validate((valid: boolean) => { if (valid) { if (typeof props.modalConfig.beforeSubmit === "function") { props.modalConfig.beforeSubmit(formData); } if ( props.contentConfig && props.contentConfig.lefftTree && props.contentConfig.lefftTree.treeKeyName ) { formData[props.contentConfig.lefftTree.treeKeyName] = props.contentConfig?.lefftTree.treeKeyValue; } if (!props.modalConfig.formAction) { ElMessage.error("表单提交未配置"); return; } props.modalConfig.formAction(formData).then(() => { let msg = "操作成功"; if (props.modalConfig.component === "drawer") { if (props.modalConfig.drawer?.title) { msg = `${props.modalConfig.drawer?.title}成功`; } } else { if (props.modalConfig.dialog?.title) { msg = `${props.modalConfig.dialog?.title}成功`; } } ElMessage.success(msg); handleClose(); emit("submitClick"); }); } }); }, 3000); // 取消弹窗 function handleClose() { console.log("取消弹窗"); handleCloseModal(); } // 关闭弹窗 function handleCloseModal() { modalVisible.value = false; handleDrawerClose(); formRef.value?.resetFields(); formRef.value?.clearValidate(); } // 禁用表单--用于详情时候用 function handleDisabled(disable: boolean) { formRef.value?.clearValidate; formDisable.value = disable; props.modalConfig.formDisabled = disable; } // 初始化监听 let formWatcher: () => void; const setupFormWatcher = () => { // 监听指定字段变化 formWatcher = watch( () => props.modalConfig.formItems .filter((formItem) => formItemChanges.value[formItem.prop]) .map((formItem) => ({ prop: formItem.prop, value: formData[formItem.prop], })), (fields) => { fields.forEach((field) => { if (!formItemChanges.value[field.prop]) return; console.log("字段变化:", field.prop, field.value); const changeConfig = formItemChanges.value[field.prop]; if (changeConfig.hidden) { const hiddenStates = changeConfig.hidden(formData); props.modalConfig.formItems.forEach((formItem) => { if (hiddenStates[formItem.prop] !== undefined) { formItem.hidden = hiddenStates[formItem.prop]; formRules.value[formItem.prop] = formItem.hidden ? [] : formItem.rules || []; } }); } }); formRef.value?.clearValidate(); }, { deep: true, immediate: true } ); }; watch( () => modalVisible.value, (newModalVisible) => { if (newModalVisible) { setupFormWatcher(); } else { handleDrawerClose(); } } ); // 弹窗关闭处理 const handleDrawerClose = () => { if (formWatcher) { formWatcher(); // 调用停止监听函数 } }; // 组件卸载时确保停止监听 onUnmounted(() => { handleDrawerClose(); }); // 暴露的属性和方法 defineExpose({ setModalVisible, getFormData, setFormData, setFormItemData, handleDisabled }); </script> <style lang="scss" scoped></style> 优化,弹窗关闭后取消监听,表单校验逻辑
最新发布
07-17
``` <template> <lay-layout class="home-class"> <lay-header> <lay-logo class="logo">工单管理系统</lay-logo> <lay-switch v-model="collapse"></lay-switch> <lay-switch v-model="active20"></lay-switch> <lay-dropdown> <lay-button type="text" icon="layui-icon-user"></lay-button> <template #content> <lay-dropdown-menu> <lay-dropdown-menu-item>个人中心</lay-dropdown-menu-item> <lay-dropdown-menu-item divided>退出登录</lay-dropdown-menu-item> </lay-dropdown-menu> </template> </lay-dropdown> </lay-header> <lay-layout class="flex-container"> <!-- 侧边菜单 --> <lay-side> <lay-menu :collapse="collapse" :tree="isTree" :theme="active20 ? 'dark' : 'light'" :selected-key="selectedKey" :open-keys="openKey" @changeSelectedKey="changeSelectedKey"> <lay-menu-item id="/"> <template #icon> <lay-icon type="layui-icon-home"></lay-icon> </template> <template #title> 首页 </template> </lay-menu-item> <lay-sub-menu id="/processUsage"> <template #icon> <lay-icon type="layui-icon-template"></lay-icon> </template> <template #title> 流程使用 </template> <lay-menu-item id="/apply">工单申请</lay-menu-item> <lay-menu-item id="/draft">草稿箱</lay-menu-item> <lay-menu-item id="/todo">待办事项</lay-menu-item> </lay-sub-menu> <lay-sub-menu title="流程查询" is="queryProcess"> <template #icon> <lay-icon type="layui-icon-search"></lay-icon> </template> <template #title> 流程查询 </template> <lay-menu-item id="/query">工单查询</lay-menu-item> <lay-menu-item id="/my-process">我的发起</lay-menu-item> <lay-menu-item id="/processed">已处理工单</lay-menu-item> </lay-sub-menu> <lay-sub-menu title="系统管理" v-if="isAdmin" id="/system"> <template #icon> <lay-icon type="layui-icon-set"></lay-icon> </template> <template #title> 系统管理 </template> <lay-menu-item id="/permission">权限管理</lay-menu-item> <lay-menu-item id="/workflow">流程配置</lay-menu-item> </lay-sub-menu> </lay-menu> </lay-side> <!-- 主体内容 --> <lay-body style="padding: 20px"> <!-- 面包屑 --> <GlobalBreadcrumb></GlobalBreadcrumb> <router-view /> </lay-body> </lay-layout> </lay-layout> </template> <script setup> import { ref } from 'vue'; import GlobalBreadcrumb from '../components/global/GlobalBreadcrumb.vue'; const isAdmin = ref(true); const collapse = ref(false); const active20 = ref(false); const selectedKey = ref("/") const openKey = ref(["/"]) const isTree = ref(true) </script>```lay-menu 加了事件changeSelectedKey,如何实现
03-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值